-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodels.ts
198 lines (174 loc) · 4.29 KB
/
models.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import {UUID as UID, uuidv7obj} from "uuidv7";
import type {Ref} from "vue";
// @ts-ignore
export class UUID extends UID {
constructor(data?: string | UUID) {
super()
if (typeof data === 'string') {
// @ts-ignore
this.bytes = UUID.parse(data).bytes
} else if (typeof data === 'object') {
Object.assign(this, data)
} else {
// @ts-ignore
this.bytes = uuidv7obj().bytes
}
}
getTime() {
const dataView = new DataView(this.bytes.buffer)
return new Date(
dataView.getUint32(0, false) * 2 ** 16
+ dataView.getUint16(4, false)
)
}
}
class Model {
static exclude: string[] = []
// noinspection JSUnusedLocalSymbols
constructor(obj: any) {
}
static fromArray<T>(arr?: any[]): T[] {
if (!arr) return <T[]>[]
return arr.map(obj => <T>new this(obj))
}
toJSON() {
const obj = {...this}
// @ts-ignore
this.constructor.exclude?.forEach(key => delete obj[key])
return obj
}
}
export const toJSONArray = (arr: Model[]) => arr.map(obj => obj.toJSON())
export class Board extends Model {
public id: string
public name: string
public description?: string
constructor(obj: any) {
super(obj)
this.id = obj.id
this.name = obj.name
this.description = obj.description
}
}
export class Content extends Model {
static override exclude = ['is_me', 'rank', 'liked', 'user']
public id: UUID
public parent_id: UUID
public type: string
public title?: string
public text: string
public is_me?: boolean
public views: number
public likes: number
public liked?: boolean
public rank?: number
public user?: User
constructor(obj: any) {
super(obj)
this.id = new UUID(obj.id)
this.parent_id = new UUID(obj.parent_id)
this.type = obj.type
this.title = obj.title
this.text = obj.text || ''
this.views = obj.views
this.likes = obj.likes
this.is_me = obj.is_me
this.liked = obj.liked
this.rank = obj.rank
this.user = obj.user
}
async changeLike(loading?: Ref<boolean>) {
needAuth()
if (loading) loading.value = true
const supabase = useSupabaseClient()
let result
if (!this.liked) {
result = await supabase.from('like').upsert({
content_id: this.id,
type: this.type,
} as never, {ignoreDuplicates: true})
} else {
result = await supabase.from('like').delete().eq('content_id', this.id)
}
const {error} = result
if (error) {
console.error(error)
useToast().Error(error.message)
return
}
this.liked = !this.liked
this.likes += this.liked ? 1 : -1
if (loading) loading.value = false
}
}
export class Comment extends Content {
public reply_to?: UUID
public deleted?: boolean
constructor(obj: any) {
super(obj)
this.reply_to = obj.reply_to ? new UUID(obj.reply_to) : undefined
this.deleted = obj.deleted
this.type = 'comment'
}
}
export class PollOption extends Content {
static override exclude = ['anonymous', ...Content.exclude]
constructor(obj: any) {
super(obj)
this.type = 'poll_option'
}
}
export class Blog extends Content {
static override exclude = [
'updated_at', 'reply', 'tags', 'comments',
...Content.exclude,
]
published: boolean
excerpt?: string
updated_at?: Date
reply?: number
locked?: boolean
images?: string[]
tags?: Tag[]
comments?: Comment[]
constructor(obj: any) {
super(obj)
this.published = obj.published
this.updated_at = new Date(obj.updated_at)
this.excerpt = obj.excerpt
this.reply = obj.reply
this.locked = obj.locked
this.tags = Tag.fromArray(obj.tags)
this.comments = Comment.fromArray(obj.comments)
this.images = obj.images || []
this.type = 'blog'
}
}
export class Tag extends Model {
id: UUID;
name: string;
popularity: number;
constructor(obj: any) {
super(obj)
if (typeof obj === 'string') {
this.id = new UUID()
this.name = obj
this.popularity = 0
} else {
this.id = new UUID(obj.id)
this.name = obj.name
this.popularity = obj.popularity
}
}
}
export class User extends Model {
id: UUID
name?: string
email?: string
constructor(obj: any) {
super(obj)
Object.assign(this, obj)
this.id = new UUID(obj.id)
}
}
export type OrderField = 'updated_at' | 'id'