pukaad-ui-lib 1.456.0 → 1.459.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/module.json +1 -1
- package/dist/runtime/components/chat/chat-conversation-item.d.vue.ts +2 -2
- package/dist/runtime/components/chat/chat-conversation-item.vue.d.ts +2 -2
- package/dist/runtime/components/comment.d.vue.ts +3 -0
- package/dist/runtime/components/comment.vue +8 -6
- package/dist/runtime/components/comment.vue.d.ts +3 -0
- package/dist/runtime/components/display/display-image.vue +6 -1
- package/dist/runtime/components/display/display-video.d.vue.ts +1 -1
- package/dist/runtime/components/display/display-video.vue.d.ts +1 -1
- package/dist/runtime/components/drawer/drawer-post-content.vue +18 -0
- package/dist/runtime/components/input/input-comment.d.vue.ts +1 -1
- package/dist/runtime/components/input/input-comment.vue.d.ts +1 -1
- package/dist/runtime/components/input/input-rating.d.vue.ts +1 -1
- package/dist/runtime/components/input/input-rating.vue.d.ts +1 -1
- package/dist/runtime/components/input/input-search.d.vue.ts +1 -1
- package/dist/runtime/components/input/input-search.vue.d.ts +1 -1
- package/dist/runtime/components/input/input-text-field.d.vue.ts +1 -1
- package/dist/runtime/components/input/input-text-field.vue.d.ts +1 -1
- package/dist/runtime/components/input/input-textarea.d.vue.ts +1 -1
- package/dist/runtime/components/input/input-textarea.vue.d.ts +1 -1
- package/dist/runtime/components/modal/modal-password-confirmed.d.vue.ts +1 -1
- package/dist/runtime/components/modal/modal-password-confirmed.vue.d.ts +1 -1
- package/dist/runtime/components/modal/modal-password-verify.d.vue.ts +1 -1
- package/dist/runtime/components/modal/modal-password-verify.vue.d.ts +1 -1
- package/dist/runtime/components/preview/preview-content.vue +16 -7
- package/dist/runtime/composables/store-chat.d.ts +2 -2
- package/dist/runtime/composables/store-notification.d.ts +1 -1
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -27,12 +27,12 @@ declare const __VLS_export: import("vue").DefineComponent<ChatConversationItemPr
|
|
|
27
27
|
avatar: string | null;
|
|
28
28
|
muted: boolean;
|
|
29
29
|
disabledMenu: boolean;
|
|
30
|
-
unreadCount: number;
|
|
31
|
-
pinned: boolean;
|
|
32
30
|
preview: string;
|
|
33
31
|
to: string;
|
|
34
32
|
active: boolean;
|
|
35
33
|
typing: boolean;
|
|
34
|
+
unreadCount: number;
|
|
35
|
+
pinned: boolean;
|
|
36
36
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
37
37
|
declare const _default: typeof __VLS_export;
|
|
38
38
|
export default _default;
|
|
@@ -27,12 +27,12 @@ declare const __VLS_export: import("vue").DefineComponent<ChatConversationItemPr
|
|
|
27
27
|
avatar: string | null;
|
|
28
28
|
muted: boolean;
|
|
29
29
|
disabledMenu: boolean;
|
|
30
|
-
unreadCount: number;
|
|
31
|
-
pinned: boolean;
|
|
32
30
|
preview: string;
|
|
33
31
|
to: string;
|
|
34
32
|
active: boolean;
|
|
35
33
|
typing: boolean;
|
|
34
|
+
unreadCount: number;
|
|
35
|
+
pinned: boolean;
|
|
36
36
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
37
37
|
declare const _default: typeof __VLS_export;
|
|
38
38
|
export default _default;
|
|
@@ -35,6 +35,8 @@ type __VLS_Props = {
|
|
|
35
35
|
currentUser: User;
|
|
36
36
|
fetchFn?: (page: number, pageSize: number) => Promise<CommentFetchResult>;
|
|
37
37
|
pageSize?: number;
|
|
38
|
+
/** ดูอย่างเดียว (เช่นหน้าพรีวิว) — ไม่มีช่องพิมพ์/เมนู กดถูกใจ/ตอบกลับ/ดูโปรไฟล์ไม่ได้ แต่ยังกดดูการตอบกลับ/ดูเพิ่มเติมได้ */
|
|
39
|
+
readonly?: boolean;
|
|
38
40
|
};
|
|
39
41
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
40
42
|
addComment: (comment: CommentItem) => void;
|
|
@@ -67,6 +69,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
|
67
69
|
comments: CommentItem[];
|
|
68
70
|
commentCount: number;
|
|
69
71
|
pageSize: number;
|
|
72
|
+
readonly: boolean;
|
|
70
73
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
71
74
|
declare const _default: typeof __VLS_export;
|
|
72
75
|
export default _default;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
</div>
|
|
9
9
|
|
|
10
10
|
<!-- กล่องคอมเมนต์หลัก — ปุ่มโผล่ตอนคลิกเข้าช่องพิมพ์ (actions-on-focus) -->
|
|
11
|
-
<InputComment ref="mainInputRef" v-model="mainCommentInput" :avatar="currentUser.avatar"
|
|
11
|
+
<InputComment v-if="!props.readonly" ref="mainInputRef" v-model="mainCommentInput" :avatar="currentUser.avatar"
|
|
12
12
|
placeholder="เพิ่มความคิดเห็น" actions-on-focus @submit="onSendComment" />
|
|
13
13
|
<div v-for="cmt in resolvedComments" :key="cmt.id" class="flex flex-col gap-[16px] w-full">
|
|
14
14
|
<div class="flex flex-col gap-[4px] w-full">
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
</template>
|
|
41
41
|
</div>
|
|
42
42
|
</div>
|
|
43
|
-
<div class="self-center transition-opacity" :class="
|
|
43
|
+
<div v-if="!props.readonly" class="self-center transition-opacity" :class="
|
|
44
44
|
isMenuVisible(cmt.id) ? 'opacity-100' : 'opacity-0 pointer-events-none'
|
|
45
45
|
">
|
|
46
46
|
<PickerOptionMenu horizontal variant="ghost" circle size="icon-sm" icon-size="20"
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
</div>
|
|
50
50
|
</template>
|
|
51
51
|
</div>
|
|
52
|
-
<div class="pl-[38px] flex gap-[16px] text-gray">
|
|
52
|
+
<div class="pl-[38px] flex gap-[16px] text-gray" :inert="props.readonly || void 0">
|
|
53
53
|
<div class="font-body-large">
|
|
54
54
|
{{ convertDateToRelativeText(cmt.created_at) }}
|
|
55
55
|
</div>
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
@click="toggleContentExpand(`reply-${reply.id}`)">ดูเพิ่มเติม</span></template>
|
|
120
120
|
</div>
|
|
121
121
|
</div>
|
|
122
|
-
<div class="self-center transition-opacity" :class="
|
|
122
|
+
<div v-if="!props.readonly" class="self-center transition-opacity" :class="
|
|
123
123
|
isMenuVisible(reply.id) ? 'opacity-100' : 'opacity-0 pointer-events-none'
|
|
124
124
|
">
|
|
125
125
|
<PickerOptionMenu horizontal variant="ghost" circle size="icon-xs" icon-size="20"
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
</div>
|
|
130
130
|
</template>
|
|
131
131
|
</div>
|
|
132
|
-
<div class="pl-[38px] flex gap-[16px] text-gray">
|
|
132
|
+
<div class="pl-[38px] flex gap-[16px] text-gray" :inert="props.readonly || void 0">
|
|
133
133
|
<div class="font-body-large">
|
|
134
134
|
{{ convertDateToRelativeText(reply.created_at) }}
|
|
135
135
|
</div>
|
|
@@ -177,7 +177,8 @@ const props = defineProps({
|
|
|
177
177
|
commentCount: { type: Number, required: false, default: 0 },
|
|
178
178
|
currentUser: { type: Object, required: true },
|
|
179
179
|
fetchFn: { type: Function, required: false },
|
|
180
|
-
pageSize: { type: Number, required: false, default: 20 }
|
|
180
|
+
pageSize: { type: Number, required: false, default: 20 },
|
|
181
|
+
readonly: { type: Boolean, required: false, default: false }
|
|
181
182
|
});
|
|
182
183
|
const emit = defineEmits(["submit", "reply", "like-comment", "like-reply", "edit-comment", "edit-reply", "delete-comment", "delete-reply", "report-comment", "report-reply"]);
|
|
183
184
|
const internalComments = ref([]);
|
|
@@ -343,6 +344,7 @@ const onToggleLikeReplyComment = (reply) => {
|
|
|
343
344
|
emit("like-reply", reply);
|
|
344
345
|
};
|
|
345
346
|
const onViewProfileComment = (id) => {
|
|
347
|
+
if (props.readonly) return;
|
|
346
348
|
if (id) router.push(`/@${id}`);
|
|
347
349
|
};
|
|
348
350
|
const onEditClick = (id, content, replyTo) => {
|
|
@@ -35,6 +35,8 @@ type __VLS_Props = {
|
|
|
35
35
|
currentUser: User;
|
|
36
36
|
fetchFn?: (page: number, pageSize: number) => Promise<CommentFetchResult>;
|
|
37
37
|
pageSize?: number;
|
|
38
|
+
/** ดูอย่างเดียว (เช่นหน้าพรีวิว) — ไม่มีช่องพิมพ์/เมนู กดถูกใจ/ตอบกลับ/ดูโปรไฟล์ไม่ได้ แต่ยังกดดูการตอบกลับ/ดูเพิ่มเติมได้ */
|
|
39
|
+
readonly?: boolean;
|
|
38
40
|
};
|
|
39
41
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
40
42
|
addComment: (comment: CommentItem) => void;
|
|
@@ -67,6 +69,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
|
67
69
|
comments: CommentItem[];
|
|
68
70
|
commentCount: number;
|
|
69
71
|
pageSize: number;
|
|
72
|
+
readonly: boolean;
|
|
70
73
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
71
74
|
declare const _default: typeof __VLS_export;
|
|
72
75
|
export default _default;
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
<Image
|
|
20
20
|
:src="getSrc((props.items ?? [])[0])"
|
|
21
21
|
class="rounded-[8px]"
|
|
22
|
-
width="
|
|
22
|
+
:width="widthMainImg"
|
|
23
23
|
height="auto"
|
|
24
24
|
/>
|
|
25
25
|
</div>
|
|
@@ -66,6 +66,11 @@ const heightBox = computed(() => {
|
|
|
66
66
|
if (length > 1 && length <= 4) return 422;
|
|
67
67
|
return 480;
|
|
68
68
|
});
|
|
69
|
+
const widthMainImg = computed(() => {
|
|
70
|
+
const length = props.items?.length ?? 0;
|
|
71
|
+
if (length === 3 || length === 4) return 633;
|
|
72
|
+
return 720;
|
|
73
|
+
});
|
|
69
74
|
const widthSubImg = computed(() => {
|
|
70
75
|
const length = props.items?.length ?? 0;
|
|
71
76
|
if (length === 0) return 0;
|
|
@@ -102,9 +102,9 @@ declare const __VLS_base: import("vue").DefineComponent<DisplayVideoProps, {
|
|
|
102
102
|
loop: boolean;
|
|
103
103
|
controls: boolean;
|
|
104
104
|
preload: "none" | "metadata" | "auto";
|
|
105
|
+
playsinline: boolean;
|
|
105
106
|
sources: DisplayVideoSource[];
|
|
106
107
|
tracks: DisplayVideoTrack[];
|
|
107
|
-
playsinline: boolean;
|
|
108
108
|
disablePictureInPicture: boolean;
|
|
109
109
|
disableRemotePlayback: boolean;
|
|
110
110
|
volume: number;
|
|
@@ -102,9 +102,9 @@ declare const __VLS_base: import("vue").DefineComponent<DisplayVideoProps, {
|
|
|
102
102
|
loop: boolean;
|
|
103
103
|
controls: boolean;
|
|
104
104
|
preload: "none" | "metadata" | "auto";
|
|
105
|
+
playsinline: boolean;
|
|
105
106
|
sources: DisplayVideoSource[];
|
|
106
107
|
tracks: DisplayVideoTrack[];
|
|
107
|
-
playsinline: boolean;
|
|
108
108
|
disablePictureInPicture: boolean;
|
|
109
109
|
disableRemotePlayback: boolean;
|
|
110
110
|
volume: number;
|
|
@@ -74,6 +74,9 @@
|
|
|
74
74
|
</template>
|
|
75
75
|
</InputFile>
|
|
76
76
|
</div>
|
|
77
|
+
<div v-if="needsManualPoster" class="font-body-small text-destructive">
|
|
78
|
+
ไม่สามารถสร้างหน้าปกจากวิดีโอได้ กรุณาอัปโหลดภาพหน้าปก
|
|
79
|
+
</div>
|
|
77
80
|
<div
|
|
78
81
|
v-show="hasCoverText && !hasCoverFile"
|
|
79
82
|
class="flex gap-[8px] py-[4px] px-[12px]"
|
|
@@ -190,6 +193,7 @@ const coverText = ref("");
|
|
|
190
193
|
const coverFiles = ref([]);
|
|
191
194
|
const posterFiles = ref([]);
|
|
192
195
|
const generatedPoster = ref(null);
|
|
196
|
+
const posterGenerationFailed = ref(false);
|
|
193
197
|
const description = ref("");
|
|
194
198
|
const fileColumns = ref(false);
|
|
195
199
|
const selectedPlaces = ref([]);
|
|
@@ -245,6 +249,7 @@ watch(
|
|
|
245
249
|
([videoFile, manualPoster]) => {
|
|
246
250
|
const generation = ++thumbnailGeneration;
|
|
247
251
|
clearGeneratedPoster();
|
|
252
|
+
posterGenerationFailed.value = false;
|
|
248
253
|
if (manualPoster || typeof File === "undefined" || !(videoFile instanceof File) || !videoFile.type.startsWith("video/")) {
|
|
249
254
|
thumbnailPromise = Promise.resolve();
|
|
250
255
|
return;
|
|
@@ -258,6 +263,9 @@ watch(
|
|
|
258
263
|
mediaType: "image"
|
|
259
264
|
};
|
|
260
265
|
}).catch(() => {
|
|
266
|
+
if (generation === thumbnailGeneration) {
|
|
267
|
+
posterGenerationFailed.value = true;
|
|
268
|
+
}
|
|
261
269
|
});
|
|
262
270
|
},
|
|
263
271
|
{ immediate: true }
|
|
@@ -269,6 +277,9 @@ onBeforeUnmount(() => {
|
|
|
269
277
|
const effectivePoster = computed(
|
|
270
278
|
() => posterFiles.value[0] ?? generatedPoster.value
|
|
271
279
|
);
|
|
280
|
+
const needsManualPoster = computed(
|
|
281
|
+
() => coverFileType.value === "video" && !posterFiles.value[0] && (posterGenerationFailed.value || typeof File === "undefined" || !(coverFiles.value[0]?.file instanceof File))
|
|
282
|
+
);
|
|
272
283
|
const previewItem = computed(() => {
|
|
273
284
|
if (hasCoverFile.value) {
|
|
274
285
|
const file = coverFiles.value[0];
|
|
@@ -449,6 +460,13 @@ const submitContent = async (status) => {
|
|
|
449
460
|
if (contentType === "video" && !posterFiles.value[0]) {
|
|
450
461
|
await thumbnailPromise;
|
|
451
462
|
}
|
|
463
|
+
if (contentType === "video" && status === "PUBLISHED" && !effectivePoster.value) {
|
|
464
|
+
posterGenerationFailed.value = true;
|
|
465
|
+
$toast?.error?.(
|
|
466
|
+
"\u0E01\u0E23\u0E38\u0E13\u0E32\u0E2D\u0E31\u0E1B\u0E42\u0E2B\u0E25\u0E14\u0E20\u0E32\u0E1E\u0E2B\u0E19\u0E49\u0E32\u0E1B\u0E01\u0E02\u0E2D\u0E07\u0E27\u0E34\u0E14\u0E35\u0E42\u0E2D"
|
|
467
|
+
);
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
452
470
|
const [uploadedMedia, uploadedPoster] = await Promise.all([
|
|
453
471
|
uploadFiles(coverFiles.value, "content-media"),
|
|
454
472
|
contentType === "video" && effectivePoster.value ? uploadFiles([effectivePoster.value], "content-media") : Promise.resolve([])
|
|
@@ -47,10 +47,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
47
47
|
loading: boolean;
|
|
48
48
|
disabled: boolean;
|
|
49
49
|
placeholder: string;
|
|
50
|
+
cancelText: string;
|
|
50
51
|
autofocus: boolean;
|
|
51
52
|
disabledAvatar: boolean;
|
|
52
53
|
submitText: string;
|
|
53
|
-
cancelText: string;
|
|
54
54
|
actionsOnFocus: boolean;
|
|
55
55
|
disabledActions: boolean;
|
|
56
56
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -47,10 +47,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
47
47
|
loading: boolean;
|
|
48
48
|
disabled: boolean;
|
|
49
49
|
placeholder: string;
|
|
50
|
+
cancelText: string;
|
|
50
51
|
autofocus: boolean;
|
|
51
52
|
disabledAvatar: boolean;
|
|
52
53
|
submitText: string;
|
|
53
|
-
cancelText: string;
|
|
54
54
|
actionsOnFocus: boolean;
|
|
55
55
|
disabledActions: boolean;
|
|
56
56
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -10,10 +10,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
10
10
|
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
11
11
|
}>, {
|
|
12
12
|
size: number;
|
|
13
|
+
readonly: boolean;
|
|
13
14
|
borderColor: string;
|
|
14
15
|
modelValue: number;
|
|
15
16
|
backgroundColor: string;
|
|
16
|
-
readonly: boolean;
|
|
17
17
|
ratingStep: number;
|
|
18
18
|
borderSize: number;
|
|
19
19
|
activeColor: string;
|
|
@@ -10,10 +10,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
10
10
|
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
11
11
|
}>, {
|
|
12
12
|
size: number;
|
|
13
|
+
readonly: boolean;
|
|
13
14
|
borderColor: string;
|
|
14
15
|
modelValue: number;
|
|
15
16
|
backgroundColor: string;
|
|
16
|
-
readonly: boolean;
|
|
17
17
|
ratingStep: number;
|
|
18
18
|
borderSize: number;
|
|
19
19
|
activeColor: string;
|
|
@@ -33,11 +33,11 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
33
33
|
type: import("./input-text-field.vue.js").InputTextFieldType;
|
|
34
34
|
icon: string;
|
|
35
35
|
disabled: boolean;
|
|
36
|
+
readonly: boolean;
|
|
36
37
|
id: string;
|
|
37
38
|
name: string;
|
|
38
39
|
required: boolean;
|
|
39
40
|
placeholder: string;
|
|
40
|
-
readonly: boolean;
|
|
41
41
|
disabledErrorMessage: boolean;
|
|
42
42
|
iconPosition: import("#pukaad-ui/types/components/input/input-search").InputSearchIconPosition;
|
|
43
43
|
disabledIcon: boolean;
|
|
@@ -33,11 +33,11 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
33
33
|
type: import("./input-text-field.vue.js").InputTextFieldType;
|
|
34
34
|
icon: string;
|
|
35
35
|
disabled: boolean;
|
|
36
|
+
readonly: boolean;
|
|
36
37
|
id: string;
|
|
37
38
|
name: string;
|
|
38
39
|
required: boolean;
|
|
39
40
|
placeholder: string;
|
|
40
|
-
readonly: boolean;
|
|
41
41
|
disabledErrorMessage: boolean;
|
|
42
42
|
iconPosition: import("#pukaad-ui/types/components/input/input-search").InputSearchIconPosition;
|
|
43
43
|
disabledIcon: boolean;
|
|
@@ -56,11 +56,11 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
56
56
|
}>, {
|
|
57
57
|
type: InputTextFieldType;
|
|
58
58
|
disabled: boolean;
|
|
59
|
+
readonly: boolean;
|
|
59
60
|
id: string;
|
|
60
61
|
name: string;
|
|
61
62
|
required: boolean;
|
|
62
63
|
limit: number;
|
|
63
|
-
readonly: boolean;
|
|
64
64
|
disabledErrorMessage: boolean;
|
|
65
65
|
disabledBorder: boolean;
|
|
66
66
|
showCounter: boolean;
|
|
@@ -56,11 +56,11 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
56
56
|
}>, {
|
|
57
57
|
type: InputTextFieldType;
|
|
58
58
|
disabled: boolean;
|
|
59
|
+
readonly: boolean;
|
|
59
60
|
id: string;
|
|
60
61
|
name: string;
|
|
61
62
|
required: boolean;
|
|
62
63
|
limit: number;
|
|
63
|
-
readonly: boolean;
|
|
64
64
|
disabledErrorMessage: boolean;
|
|
65
65
|
disabledBorder: boolean;
|
|
66
66
|
showCounter: boolean;
|
|
@@ -40,6 +40,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
40
40
|
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
41
41
|
}>, {
|
|
42
42
|
disabled: boolean;
|
|
43
|
+
readonly: boolean;
|
|
43
44
|
id: string;
|
|
44
45
|
name: string;
|
|
45
46
|
required: boolean;
|
|
@@ -48,7 +49,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
48
49
|
fullHeight: boolean;
|
|
49
50
|
rows: number;
|
|
50
51
|
limit: number;
|
|
51
|
-
readonly: boolean;
|
|
52
52
|
disabledErrorMessage: boolean;
|
|
53
53
|
disabledBorder: boolean;
|
|
54
54
|
showCounter: boolean;
|
|
@@ -40,6 +40,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
40
40
|
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
41
41
|
}>, {
|
|
42
42
|
disabled: boolean;
|
|
43
|
+
readonly: boolean;
|
|
43
44
|
id: string;
|
|
44
45
|
name: string;
|
|
45
46
|
required: boolean;
|
|
@@ -48,7 +49,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
48
49
|
fullHeight: boolean;
|
|
49
50
|
rows: number;
|
|
50
51
|
limit: number;
|
|
51
|
-
readonly: boolean;
|
|
52
52
|
disabledErrorMessage: boolean;
|
|
53
53
|
disabledBorder: boolean;
|
|
54
54
|
showCounter: boolean;
|
|
@@ -24,8 +24,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
24
24
|
}) => any) | undefined;
|
|
25
25
|
}>, {
|
|
26
26
|
title: string;
|
|
27
|
-
disabledForgotPassword: boolean;
|
|
28
27
|
confirmText: string;
|
|
28
|
+
disabledForgotPassword: boolean;
|
|
29
29
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
30
30
|
declare const _default: typeof __VLS_export;
|
|
31
31
|
export default _default;
|
|
@@ -24,8 +24,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
24
24
|
}) => any) | undefined;
|
|
25
25
|
}>, {
|
|
26
26
|
title: string;
|
|
27
|
-
disabledForgotPassword: boolean;
|
|
28
27
|
confirmText: string;
|
|
28
|
+
disabledForgotPassword: boolean;
|
|
29
29
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
30
30
|
declare const _default: typeof __VLS_export;
|
|
31
31
|
export default _default;
|
|
@@ -32,8 +32,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
32
32
|
}>, {
|
|
33
33
|
title: string;
|
|
34
34
|
mode: "login" | "secure";
|
|
35
|
-
disabledForgotPassword: boolean;
|
|
36
35
|
confirmText: string;
|
|
36
|
+
disabledForgotPassword: boolean;
|
|
37
37
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
38
38
|
declare const _default: typeof __VLS_export;
|
|
39
39
|
export default _default;
|
|
@@ -32,8 +32,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
32
32
|
}>, {
|
|
33
33
|
title: string;
|
|
34
34
|
mode: "login" | "secure";
|
|
35
|
-
disabledForgotPassword: boolean;
|
|
36
35
|
confirmText: string;
|
|
36
|
+
disabledForgotPassword: boolean;
|
|
37
37
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
38
38
|
declare const _default: typeof __VLS_export;
|
|
39
39
|
export default _default;
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
v-else-if="contentData.content_type === 'image'"
|
|
37
37
|
:items="contentData.media"
|
|
38
38
|
item-src="url"
|
|
39
|
+
@select="openImage"
|
|
39
40
|
/>
|
|
40
41
|
<!-- Video -->
|
|
41
42
|
<DisplayVideo
|
|
@@ -119,13 +120,12 @@
|
|
|
119
120
|
</div>
|
|
120
121
|
|
|
121
122
|
<!-- ส่งรายการเข้าไปเอง (ไม่ใช้ fetchFn) เพราะ fetchFn โหลดหน้าถัดไปจาก window scroll -->
|
|
122
|
-
<
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
</div>
|
|
123
|
+
<Comment
|
|
124
|
+
:comments="comments"
|
|
125
|
+
:comment-count="commentTotal"
|
|
126
|
+
:current-user="previewUser"
|
|
127
|
+
readonly
|
|
128
|
+
/>
|
|
129
129
|
|
|
130
130
|
<div ref="sentinel" class="h-[1px]" />
|
|
131
131
|
<div v-if="isLoadingComments" class="flex justify-center py-[16px]">
|
|
@@ -138,6 +138,8 @@
|
|
|
138
138
|
</div>
|
|
139
139
|
</div>
|
|
140
140
|
</div>
|
|
141
|
+
|
|
142
|
+
<ModalDisplayImage v-model="isImageOpen" :src="selectedImage" />
|
|
141
143
|
</div>
|
|
142
144
|
</template>
|
|
143
145
|
|
|
@@ -172,6 +174,8 @@ const isLoadingComments = ref(false);
|
|
|
172
174
|
const hasMoreComments = computed(
|
|
173
175
|
() => commentPage.value < commentTotalPages.value
|
|
174
176
|
);
|
|
177
|
+
const isImageOpen = ref(false);
|
|
178
|
+
const selectedImage = ref("");
|
|
175
179
|
const previewUser = { id: "", name: "", avatar: "" };
|
|
176
180
|
const labelItems = computed(
|
|
177
181
|
() => (contentData.value.labels ?? []).map((label) => ({
|
|
@@ -289,6 +293,11 @@ const fetchComments = async (page = 1) => {
|
|
|
289
293
|
if (requestId === commentRequestId) isLoadingComments.value = false;
|
|
290
294
|
}
|
|
291
295
|
};
|
|
296
|
+
const openImage = (item) => {
|
|
297
|
+
if (!item?.url) return;
|
|
298
|
+
selectedImage.value = item.url;
|
|
299
|
+
isImageOpen.value = true;
|
|
300
|
+
};
|
|
292
301
|
const loadAll = () => {
|
|
293
302
|
fetchContentData();
|
|
294
303
|
fetchRecommendations();
|
|
@@ -121,7 +121,7 @@ export declare const useChatStore: import("pinia").StoreDefinition<"pukaad-chat"
|
|
|
121
121
|
startRealtime: () => void;
|
|
122
122
|
stopRealtime: () => void;
|
|
123
123
|
resync: (activeConversationId?: string) => Promise<void>;
|
|
124
|
-
}, "headers" | "
|
|
124
|
+
}, "headers" | "conversations" | "unreadFirst" | "hasMoreConversations" | "hasLoadedConversations" | "isLoadingConversations" | "peerLastRead" | "messages" | "hasOlder" | "isLoadingOlder" | "isConnected" | "unreadChatCount">, Pick<{
|
|
125
125
|
conversations: import("vue").Ref<{
|
|
126
126
|
id: string;
|
|
127
127
|
profile: {
|
|
@@ -365,4 +365,4 @@ export declare const useChatStore: import("pinia").StoreDefinition<"pukaad-chat"
|
|
|
365
365
|
startRealtime: () => void;
|
|
366
366
|
stopRealtime: () => void;
|
|
367
367
|
resync: (activeConversationId?: string) => Promise<void>;
|
|
368
|
-
}, "reset" | "
|
|
368
|
+
}, "reset" | "setUnreadFirst" | "setMyProfileId" | "fetchConversations" | "fetchConversation" | "fetchLatestMessages" | "fetchOlderMessages" | "sendMessage" | "sendMedia" | "retryMessage" | "markRead" | "isReadByPeer" | "unreadCountOf" | "startUnreadBadge" | "stopUnreadBadge" | "previewOf" | "sendTyping" | "isPeerTyping" | "deleteMessage" | "startRealtime" | "stopRealtime" | "resync">>;
|
|
@@ -215,4 +215,4 @@ export declare const useNotificationStore: import("pinia").StoreDefinition<"noti
|
|
|
215
215
|
openDrawer: () => void;
|
|
216
216
|
closeDrawer: () => void;
|
|
217
217
|
toggleDrawer: () => void;
|
|
218
|
-
}, "
|
|
218
|
+
}, "markRead" | "fetchList" | "loadMore" | "prefetch" | "markAllRead" | "fetchUnreadCount" | "initRealtime" | "closeRealtime" | "setUnreadCount" | "openDrawer" | "closeDrawer" | "toggleDrawer">>;
|