@codingfactory/socialkit-vue 0.5.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/stores/content.d.ts +1418 -0
- package/dist/stores/content.d.ts.map +1 -0
- package/dist/stores/content.js +1195 -0
- package/dist/stores/content.js.map +1 -0
- package/dist/stores/discussion.d.ts +28 -12
- package/dist/stores/discussion.d.ts.map +1 -1
- package/dist/stores/discussion.js +2 -1
- package/dist/stores/discussion.js.map +1 -1
- package/dist/types/content-api.d.ts +23 -0
- package/dist/types/content-api.d.ts.map +1 -0
- package/dist/types/content-api.js +5 -0
- package/dist/types/content-api.js.map +1 -0
- package/dist/types/content.d.ts +309 -0
- package/dist/types/content.d.ts.map +1 -0
- package/dist/types/content.js +36 -0
- package/dist/types/content.js.map +1 -0
- package/dist/types/media.d.ts +63 -0
- package/dist/types/media.d.ts.map +1 -0
- package/dist/types/media.js +13 -0
- package/dist/types/media.js.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +78 -0
- package/src/stores/content.ts +1477 -0
- package/src/stores/discussion.ts +34 -8
- package/src/types/content-api.ts +24 -0
- package/src/types/content.ts +381 -0
- package/src/types/media.ts +81 -0
package/src/stores/discussion.ts
CHANGED
|
@@ -68,6 +68,25 @@ interface LocalReactionEchoMarker {
|
|
|
68
68
|
expiresAt: number
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
interface DiscussionCreateThreadResponse {
|
|
72
|
+
data?: Thread
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
interface DiscussionCreateReplyResponse {
|
|
76
|
+
data?: Reply
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
interface DiscussionDraftPayload {
|
|
80
|
+
title?: string | null
|
|
81
|
+
content?: string
|
|
82
|
+
metadata?: Record<string, unknown>
|
|
83
|
+
[key: string]: unknown
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
interface DiscussionSaveDraftResponse {
|
|
87
|
+
data?: DiscussionDraftPayload
|
|
88
|
+
}
|
|
89
|
+
|
|
71
90
|
type UnknownRecord = Record<string, unknown>
|
|
72
91
|
|
|
73
92
|
function isRecord(value: unknown): value is UnknownRecord {
|
|
@@ -979,13 +998,16 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
|
|
|
979
998
|
}
|
|
980
999
|
}
|
|
981
1000
|
|
|
982
|
-
async function createThread(
|
|
1001
|
+
async function createThread(
|
|
1002
|
+
spaceSlug: string,
|
|
1003
|
+
input: CreateThreadInput
|
|
1004
|
+
): Promise<DiscussionCreateThreadResponse> {
|
|
983
1005
|
cleanupRealtimeChannels()
|
|
984
1006
|
loading.value = true
|
|
985
1007
|
error.value = null
|
|
986
1008
|
|
|
987
1009
|
try {
|
|
988
|
-
const response = await client.post<
|
|
1010
|
+
const response = await client.post<DiscussionCreateThreadResponse>(`/v1/discussion/spaces/${spaceSlug}/threads`, {
|
|
989
1011
|
title: input.title,
|
|
990
1012
|
body: input.body,
|
|
991
1013
|
audience: input.audience || 'public',
|
|
@@ -1107,11 +1129,14 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
|
|
|
1107
1129
|
return err.message === 'Network Error' && !err.response
|
|
1108
1130
|
}
|
|
1109
1131
|
|
|
1110
|
-
async function createReply(
|
|
1132
|
+
async function createReply(
|
|
1133
|
+
threadId: string,
|
|
1134
|
+
input: CreateReplyInput
|
|
1135
|
+
): Promise<DiscussionCreateReplyResponse> {
|
|
1111
1136
|
pendingReplyCreations.set(threadId, (pendingReplyCreations.get(threadId) ?? 0) + 1)
|
|
1112
1137
|
|
|
1113
1138
|
try {
|
|
1114
|
-
const response = await client.post<
|
|
1139
|
+
const response = await client.post<DiscussionCreateReplyResponse>(`/v1/discussion/threads/${threadId}/replies`, {
|
|
1115
1140
|
body: input.body,
|
|
1116
1141
|
parent_reply_id: input.parent_id,
|
|
1117
1142
|
...(input.quoted_reply_id ? { quoted_reply_id: input.quoted_reply_id } : {}),
|
|
@@ -2093,9 +2118,9 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
|
|
|
2093
2118
|
id: string,
|
|
2094
2119
|
content: string,
|
|
2095
2120
|
options?: SaveDraftOptions
|
|
2096
|
-
): Promise<
|
|
2121
|
+
): Promise<DiscussionSaveDraftResponse> {
|
|
2097
2122
|
try {
|
|
2098
|
-
const response = await client.post<
|
|
2123
|
+
const response = await client.post<DiscussionSaveDraftResponse>('/v1/editor/drafts/save', {
|
|
2099
2124
|
type,
|
|
2100
2125
|
id,
|
|
2101
2126
|
title: options?.title,
|
|
@@ -2110,13 +2135,14 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
|
|
|
2110
2135
|
}
|
|
2111
2136
|
}
|
|
2112
2137
|
|
|
2113
|
-
async function getDraft(type: string, id: string): Promise<
|
|
2138
|
+
async function getDraft(type: string, id: string): Promise<DiscussionDraftPayload | null> {
|
|
2114
2139
|
try {
|
|
2115
2140
|
const response = await client.get<unknown>('/v1/editor/drafts/check', {
|
|
2116
2141
|
params: { type, id },
|
|
2117
2142
|
})
|
|
2118
2143
|
const responseData = toRecord(response.data)
|
|
2119
|
-
|
|
2144
|
+
const draftData = toRecord(responseData?.data)
|
|
2145
|
+
return draftData as DiscussionDraftPayload | null
|
|
2120
2146
|
} catch (draftError) {
|
|
2121
2147
|
if (isAxiosError(draftError) && draftError.response?.status === 404) {
|
|
2122
2148
|
return null
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content API type definitions.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { FeedEntry, Post } from './content.js'
|
|
6
|
+
|
|
7
|
+
export interface FeedResponse {
|
|
8
|
+
data: {
|
|
9
|
+
entries: FeedEntry[]
|
|
10
|
+
meta?: {
|
|
11
|
+
next_cursor?: string | null
|
|
12
|
+
has_more?: boolean
|
|
13
|
+
current_page?: number
|
|
14
|
+
total?: number
|
|
15
|
+
}
|
|
16
|
+
next_cursor?: string | null
|
|
17
|
+
}
|
|
18
|
+
page_entries?: FeedEntry[]
|
|
19
|
+
next_cursor?: string | null
|
|
20
|
+
entries?: FeedEntry[]
|
|
21
|
+
posts?: Post[]
|
|
22
|
+
hasMore?: boolean
|
|
23
|
+
nextCursor?: string | null
|
|
24
|
+
}
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content-domain types and store contracts shared across SocialKit frontends.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { ApiService } from '../services/api.js'
|
|
6
|
+
import type { LocalMediaItem } from './media.js'
|
|
7
|
+
|
|
8
|
+
export interface BaseEntity {
|
|
9
|
+
id: string
|
|
10
|
+
created_at: string
|
|
11
|
+
updated_at?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type VideoRenderStatus = 'pending' | 'processing' | 'ready' | 'failed'
|
|
15
|
+
|
|
16
|
+
export interface PostMedia {
|
|
17
|
+
id?: string
|
|
18
|
+
uuid?: string
|
|
19
|
+
mime_type?: string
|
|
20
|
+
url?: string
|
|
21
|
+
thumb_url?: string
|
|
22
|
+
preview_url?: string
|
|
23
|
+
playback_url?: string
|
|
24
|
+
thumbnail_url?: string
|
|
25
|
+
urls?: {
|
|
26
|
+
original?: string
|
|
27
|
+
thumb?: string
|
|
28
|
+
thumbnail?: string
|
|
29
|
+
preview?: string
|
|
30
|
+
}
|
|
31
|
+
type?: 'image' | 'video'
|
|
32
|
+
alt_text?: string
|
|
33
|
+
width?: number
|
|
34
|
+
height?: number
|
|
35
|
+
responsive?: {
|
|
36
|
+
preview?: {
|
|
37
|
+
srcset?: string
|
|
38
|
+
}
|
|
39
|
+
original?: {
|
|
40
|
+
srcset?: string
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
processing_status?: VideoRenderStatus
|
|
44
|
+
video_render_status?: VideoRenderStatus
|
|
45
|
+
video_render_progress?: number
|
|
46
|
+
video_render_error?: string | null
|
|
47
|
+
video_render_job_id?: string | null
|
|
48
|
+
source_media_id?: string
|
|
49
|
+
output_media_id?: string
|
|
50
|
+
provider?: string
|
|
51
|
+
provider_asset_id?: string
|
|
52
|
+
provider_library_id?: string
|
|
53
|
+
duration?: number
|
|
54
|
+
aspect_ratio?: string
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface PostAuthor {
|
|
58
|
+
id: string
|
|
59
|
+
name: string
|
|
60
|
+
avatar?: string | null
|
|
61
|
+
username?: string | null
|
|
62
|
+
handle?: string | null
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type PostFeelingType = 'mood' | 'activity'
|
|
66
|
+
export type PostFeelingValue =
|
|
67
|
+
| 'inspired'
|
|
68
|
+
| 'creative'
|
|
69
|
+
| 'focused'
|
|
70
|
+
| 'relaxed'
|
|
71
|
+
| 'excited'
|
|
72
|
+
| 'grateful'
|
|
73
|
+
| 'proud'
|
|
74
|
+
| 'experimental'
|
|
75
|
+
| 'in_the_studio'
|
|
76
|
+
| 'teaching_a_class'
|
|
77
|
+
| 'at_a_show'
|
|
78
|
+
| 'experimenting'
|
|
79
|
+
| 'collaborating'
|
|
80
|
+
| 'learning_a_technique'
|
|
81
|
+
|
|
82
|
+
export interface PostFeeling {
|
|
83
|
+
type: PostFeelingType
|
|
84
|
+
value: PostFeelingValue
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface PostMeta {
|
|
88
|
+
live_viewers?: number | null
|
|
89
|
+
feeling?: PostFeeling | null
|
|
90
|
+
[key: string]: unknown
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export type PostShareType = 'original' | 'repost' | 'quote'
|
|
94
|
+
|
|
95
|
+
export interface QuotedPostPreview {
|
|
96
|
+
id: string
|
|
97
|
+
body: string
|
|
98
|
+
author?: PostAuthor | null
|
|
99
|
+
author_id?: string
|
|
100
|
+
created_at?: string
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface Post extends BaseEntity {
|
|
104
|
+
body: string
|
|
105
|
+
share_type?: PostShareType
|
|
106
|
+
quoted_post_id?: string | null
|
|
107
|
+
quoted_post?: QuotedPostPreview | null
|
|
108
|
+
content_warning?: string | null
|
|
109
|
+
sensitive?: boolean
|
|
110
|
+
author: PostAuthor
|
|
111
|
+
author_id: string
|
|
112
|
+
reactions_count: number
|
|
113
|
+
comments_count: number
|
|
114
|
+
user_has_reacted: boolean
|
|
115
|
+
user_has_reposted?: boolean
|
|
116
|
+
user_repost_id?: string | null
|
|
117
|
+
visibility?: 'public' | 'private' | 'friends'
|
|
118
|
+
media?: PostMedia[]
|
|
119
|
+
meta?: PostMeta
|
|
120
|
+
live_viewers?: number | null
|
|
121
|
+
is_quarantined?: boolean
|
|
122
|
+
published_site_names?: string[] | null
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface PostWithPendingState extends Post {
|
|
126
|
+
_isPending?: boolean
|
|
127
|
+
_tempId?: string
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface Comment extends BaseEntity {
|
|
131
|
+
body: string
|
|
132
|
+
post_id: string
|
|
133
|
+
author: PostAuthor
|
|
134
|
+
media?: PostMedia[]
|
|
135
|
+
parent_id?: string
|
|
136
|
+
thread_id?: string
|
|
137
|
+
depth?: number
|
|
138
|
+
reactions_count?: number
|
|
139
|
+
replies_count?: number
|
|
140
|
+
user_has_reacted?: boolean
|
|
141
|
+
user_reaction_type?: string
|
|
142
|
+
reactions?: Record<string, number>
|
|
143
|
+
replies?: Comment[]
|
|
144
|
+
is_hidden?: boolean
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface Reaction {
|
|
148
|
+
id: string
|
|
149
|
+
user_id: string
|
|
150
|
+
target_id: string
|
|
151
|
+
target_type: 'post' | 'comment'
|
|
152
|
+
kind: string
|
|
153
|
+
created_at: string
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface ThreadSummary {
|
|
157
|
+
id: string
|
|
158
|
+
space_id: string
|
|
159
|
+
slug: string
|
|
160
|
+
title: string
|
|
161
|
+
body?: string | null
|
|
162
|
+
reply_count: number
|
|
163
|
+
author_id: string
|
|
164
|
+
author?: {
|
|
165
|
+
id: string
|
|
166
|
+
name: string
|
|
167
|
+
handle?: string
|
|
168
|
+
avatar_url?: string | null
|
|
169
|
+
avatar?: unknown
|
|
170
|
+
} | null
|
|
171
|
+
created_at: string
|
|
172
|
+
tags?: Array<{
|
|
173
|
+
id: string
|
|
174
|
+
slug: string
|
|
175
|
+
label: string
|
|
176
|
+
}>
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export interface AlbumSummary {
|
|
180
|
+
id: string
|
|
181
|
+
name: string
|
|
182
|
+
description?: string | null
|
|
183
|
+
media_count: number
|
|
184
|
+
owner: {
|
|
185
|
+
id: string
|
|
186
|
+
type: string
|
|
187
|
+
name?: string
|
|
188
|
+
avatar_url?: string | null
|
|
189
|
+
}
|
|
190
|
+
cover_media?: {
|
|
191
|
+
uuid: string
|
|
192
|
+
urls: {
|
|
193
|
+
thumb?: string
|
|
194
|
+
preview?: string
|
|
195
|
+
original?: string
|
|
196
|
+
}
|
|
197
|
+
} | null
|
|
198
|
+
created_at?: string | null
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export interface FeedEntry {
|
|
202
|
+
id?: string
|
|
203
|
+
entity_id: string
|
|
204
|
+
entity_type: string
|
|
205
|
+
created_at?: string
|
|
206
|
+
activity_type?: string
|
|
207
|
+
actor_id?: string
|
|
208
|
+
owner_user_id?: string
|
|
209
|
+
visibility?: string
|
|
210
|
+
is_hidden?: boolean
|
|
211
|
+
post?: PostWithPendingState | null
|
|
212
|
+
thread?: ThreadSummary | null
|
|
213
|
+
album?: AlbumSummary | null
|
|
214
|
+
[key: string]: unknown
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export interface ScheduledPostEntry {
|
|
218
|
+
id: string
|
|
219
|
+
status: string
|
|
220
|
+
publish_at: string
|
|
221
|
+
post_id: string | null
|
|
222
|
+
payload: Record<string, unknown> | string | null
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export interface ScheduledPostsPage {
|
|
226
|
+
data: ScheduledPostEntry[]
|
|
227
|
+
meta: {
|
|
228
|
+
next_cursor: string | null
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export type PendingPostStatus = 'pending' | 'uploading' | 'failed'
|
|
233
|
+
|
|
234
|
+
export interface PendingVideoRender {
|
|
235
|
+
sourceMediaUuid: string
|
|
236
|
+
renderJobId: string | null
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export interface PendingPost {
|
|
240
|
+
tempId: string
|
|
241
|
+
body: string
|
|
242
|
+
share_type?: PostShareType | undefined
|
|
243
|
+
quoted_post_id?: string | undefined
|
|
244
|
+
visibility: string
|
|
245
|
+
content_warning?: string | undefined
|
|
246
|
+
meta?: PostMeta | undefined
|
|
247
|
+
media_ids?: string[] | undefined
|
|
248
|
+
mediaItems?: LocalMediaItem[] | undefined
|
|
249
|
+
hadUnuploadedMedia?: boolean | undefined
|
|
250
|
+
container_type?: string | undefined
|
|
251
|
+
container_id?: string | undefined
|
|
252
|
+
pendingVideoRenders?: PendingVideoRender[] | undefined
|
|
253
|
+
status: PendingPostStatus
|
|
254
|
+
createdAt: string
|
|
255
|
+
retryCount: number
|
|
256
|
+
error?: string | undefined
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export interface RecoverablePendingDraft {
|
|
260
|
+
tempId: string
|
|
261
|
+
body: string
|
|
262
|
+
visibility: string
|
|
263
|
+
contentWarning?: string
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export type ProcessPendingPostResult =
|
|
267
|
+
| {
|
|
268
|
+
ok: true
|
|
269
|
+
postId: string
|
|
270
|
+
isQuarantined?: boolean
|
|
271
|
+
}
|
|
272
|
+
| {
|
|
273
|
+
ok: false
|
|
274
|
+
error: string
|
|
275
|
+
retryable: boolean
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export function isPost(obj: unknown): obj is Post {
|
|
279
|
+
return (
|
|
280
|
+
obj !== null
|
|
281
|
+
&& typeof obj === 'object'
|
|
282
|
+
&& 'id' in obj
|
|
283
|
+
&& 'body' in obj
|
|
284
|
+
&& 'author' in obj
|
|
285
|
+
&& 'reactions_count' in obj
|
|
286
|
+
&& 'comments_count' in obj
|
|
287
|
+
)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export function isComment(obj: unknown): obj is Comment {
|
|
291
|
+
return (
|
|
292
|
+
obj !== null
|
|
293
|
+
&& typeof obj === 'object'
|
|
294
|
+
&& 'id' in obj
|
|
295
|
+
&& 'body' in obj
|
|
296
|
+
&& 'post_id' in obj
|
|
297
|
+
&& 'author' in obj
|
|
298
|
+
)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export type PostUpdate = Partial<Omit<Post, 'id' | 'created_at' | 'author' | 'author_id'>>
|
|
302
|
+
export type CommentUpdate = Partial<Omit<Comment, 'id' | 'created_at' | 'author' | 'post_id'>>
|
|
303
|
+
|
|
304
|
+
export interface PostResponse {
|
|
305
|
+
data: Post
|
|
306
|
+
meta?: Record<string, unknown>
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export interface PostListResponse {
|
|
310
|
+
data: Post[]
|
|
311
|
+
meta?: {
|
|
312
|
+
total: number
|
|
313
|
+
per_page: number
|
|
314
|
+
current_page: number
|
|
315
|
+
next_cursor?: string
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export interface CommentListResponse {
|
|
320
|
+
data: Comment[]
|
|
321
|
+
meta?: {
|
|
322
|
+
total: number
|
|
323
|
+
next_cursor?: string
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
export enum PostVisibility {
|
|
328
|
+
PUBLIC = 'public',
|
|
329
|
+
PRIVATE = 'private',
|
|
330
|
+
FRIENDS = 'friends'
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export enum ReactionKind {
|
|
334
|
+
LIKE = 'like',
|
|
335
|
+
LOVE = 'love',
|
|
336
|
+
HAHA = 'haha',
|
|
337
|
+
WOW = 'wow',
|
|
338
|
+
SAD = 'sad',
|
|
339
|
+
ANGRY = 'angry'
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export interface ContentActiveRecipeMeta {
|
|
343
|
+
id: string
|
|
344
|
+
name: string
|
|
345
|
+
icon: string | null
|
|
346
|
+
is_preset: boolean
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export interface ContentCurrentUser {
|
|
350
|
+
id: string
|
|
351
|
+
name: string
|
|
352
|
+
handle?: string | null
|
|
353
|
+
avatar?: string | null
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export interface ContentStoreStorage {
|
|
357
|
+
getItem(key: string): string | null
|
|
358
|
+
setItem(key: string, value: string): void
|
|
359
|
+
removeItem(key: string): void
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
export interface ContentMediaUploadService {
|
|
363
|
+
uploadLocalMediaItems(items: LocalMediaItem[]): Promise<string[]>
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export interface ContentStoreLogger {
|
|
367
|
+
error: (...args: unknown[]) => void
|
|
368
|
+
warn: (...args: unknown[]) => void
|
|
369
|
+
info: (...args: unknown[]) => void
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export interface ContentStoreConfig {
|
|
373
|
+
client: ApiService
|
|
374
|
+
mediaUploadService: ContentMediaUploadService
|
|
375
|
+
getCurrentUser: () => ContentCurrentUser | null
|
|
376
|
+
syncActiveRecipe?: (meta: ContentActiveRecipeMeta | null) => void
|
|
377
|
+
storage?: ContentStoreStorage | null
|
|
378
|
+
pageSize?: number
|
|
379
|
+
logger?: ContentStoreLogger
|
|
380
|
+
storeId?: string
|
|
381
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core type definitions for media.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface MediaItem {
|
|
6
|
+
id: string
|
|
7
|
+
type: 'image' | 'video' | 'document'
|
|
8
|
+
url: string
|
|
9
|
+
thumbnail_url?: string
|
|
10
|
+
alt_text?: string
|
|
11
|
+
width?: number
|
|
12
|
+
height?: number
|
|
13
|
+
size?: number
|
|
14
|
+
mime_type?: string
|
|
15
|
+
created_at?: string
|
|
16
|
+
updated_at?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function isMediaItem(obj: unknown): obj is MediaItem {
|
|
20
|
+
return (
|
|
21
|
+
obj !== null
|
|
22
|
+
&& typeof obj === 'object'
|
|
23
|
+
&& 'id' in obj
|
|
24
|
+
&& 'type' in obj
|
|
25
|
+
&& 'url' in obj
|
|
26
|
+
&& typeof (obj as MediaItem).type === 'string'
|
|
27
|
+
&& ['image', 'video', 'document'].includes((obj as MediaItem).type)
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface UploadedMedia {
|
|
32
|
+
id: string
|
|
33
|
+
url: string
|
|
34
|
+
thumb_url?: string | null
|
|
35
|
+
preview_url?: string | null
|
|
36
|
+
mime_type: string
|
|
37
|
+
size: number
|
|
38
|
+
urls?: {
|
|
39
|
+
original?: string
|
|
40
|
+
thumbnail?: string
|
|
41
|
+
preview?: string
|
|
42
|
+
}
|
|
43
|
+
original_url?: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface LocalMediaItem {
|
|
47
|
+
id?: string
|
|
48
|
+
previewUrl: string
|
|
49
|
+
file?: File
|
|
50
|
+
mimeType: string
|
|
51
|
+
name: string
|
|
52
|
+
size: number
|
|
53
|
+
status: 'pending' | 'uploading' | 'uploaded' | 'failed'
|
|
54
|
+
error?: string
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface FilterConfig {
|
|
58
|
+
name: string
|
|
59
|
+
type: string
|
|
60
|
+
value: number | string
|
|
61
|
+
timestamp?: number
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export type ImageEditorContext = 'profile' | 'editor' | 'gallery'
|
|
65
|
+
export type ImageFormat = 'jpeg' | 'png' | 'webp'
|
|
66
|
+
|
|
67
|
+
export interface ImageEditorSaveData {
|
|
68
|
+
imageData: Blob
|
|
69
|
+
filters: FilterConfig[]
|
|
70
|
+
metadata: ImageEditorMetadata
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface ImageEditorMetadata {
|
|
74
|
+
originalUrl: string
|
|
75
|
+
context: string
|
|
76
|
+
appliedFilters: FilterConfig[]
|
|
77
|
+
processingTime: number
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export type MediaType = MediaItem['type']
|
|
81
|
+
export type MediaUpdate = Partial<Omit<MediaItem, 'id' | 'created_at'>>
|