pukaad-ui-lib 1.424.0 → 1.426.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.
Files changed (49) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/card/card-profile/card-profile-header.d.vue.ts +1 -1
  3. package/dist/runtime/components/card/card-profile/card-profile-header.vue.d.ts +1 -1
  4. package/dist/runtime/components/card/card-reaction.d.vue.ts +1 -1
  5. package/dist/runtime/components/card/card-reaction.vue.d.ts +1 -1
  6. package/dist/runtime/components/card/card-review.d.vue.ts +5 -5
  7. package/dist/runtime/components/card/card-review.vue.d.ts +5 -5
  8. package/dist/runtime/components/drawer/drawer-post-content.vue +46 -4
  9. package/dist/runtime/components/drawer/drawer-profile-network.d.vue.ts +1 -1
  10. package/dist/runtime/components/drawer/drawer-profile-network.vue.d.ts +1 -1
  11. package/dist/runtime/components/image/image-cropper.d.vue.ts +3 -3
  12. package/dist/runtime/components/image/image-cropper.vue.d.ts +3 -3
  13. package/dist/runtime/components/input/input-autocomplete.d.vue.ts +3 -3
  14. package/dist/runtime/components/input/input-autocomplete.vue.d.ts +3 -3
  15. package/dist/runtime/components/input/input-birth-date.d.vue.ts +1 -1
  16. package/dist/runtime/components/input/input-birth-date.vue.d.ts +1 -1
  17. package/dist/runtime/components/input/input-date-picker.d.vue.ts +1 -1
  18. package/dist/runtime/components/input/input-date-picker.vue.d.ts +1 -1
  19. package/dist/runtime/components/input/input-file.d.vue.ts +1 -1
  20. package/dist/runtime/components/input/input-file.vue +1 -0
  21. package/dist/runtime/components/input/input-file.vue.d.ts +1 -1
  22. package/dist/runtime/components/input/input-link.d.vue.ts +1 -1
  23. package/dist/runtime/components/input/input-link.vue.d.ts +1 -1
  24. package/dist/runtime/components/input/input-localized-name.d.vue.ts +2 -2
  25. package/dist/runtime/components/input/input-localized-name.vue.d.ts +2 -2
  26. package/dist/runtime/components/input/input-mention.vue +5 -3
  27. package/dist/runtime/components/input/input-search.d.vue.ts +1 -1
  28. package/dist/runtime/components/input/input-search.vue.d.ts +1 -1
  29. package/dist/runtime/components/input/input-suggest.d.vue.ts +2 -2
  30. package/dist/runtime/components/input/input-suggest.vue.d.ts +2 -2
  31. package/dist/runtime/components/input/input-tag-modal.d.vue.ts +2 -2
  32. package/dist/runtime/components/input/input-tag-modal.vue.d.ts +2 -2
  33. package/dist/runtime/components/input/input-tag.d.vue.ts +1 -1
  34. package/dist/runtime/components/input/input-tag.vue.d.ts +1 -1
  35. package/dist/runtime/components/input/input-text-field.d.vue.ts +1 -1
  36. package/dist/runtime/components/input/input-text-field.vue.d.ts +1 -1
  37. package/dist/runtime/components/input/input-textarea.d.vue.ts +2 -2
  38. package/dist/runtime/components/input/input-textarea.vue.d.ts +2 -2
  39. package/dist/runtime/components/input/input-typed-field.d.vue.ts +1 -1
  40. package/dist/runtime/components/input/input-typed-field.vue.d.ts +1 -1
  41. package/dist/runtime/components/ui/chart/ChartTooltipContent.d.vue.ts +1 -1
  42. package/dist/runtime/components/ui/chart/ChartTooltipContent.vue.d.ts +1 -1
  43. package/dist/runtime/components/ui/native-select/NativeSelectOptGroup.d.vue.ts +2 -2
  44. package/dist/runtime/components/ui/native-select/NativeSelectOptGroup.vue.d.ts +2 -2
  45. package/dist/runtime/components/ui/native-select/NativeSelectOption.d.vue.ts +2 -2
  46. package/dist/runtime/components/ui/native-select/NativeSelectOption.vue.d.ts +2 -2
  47. package/dist/runtime/utils/createVideoThumbnail.d.ts +1 -0
  48. package/dist/runtime/utils/createVideoThumbnail.js +47 -0
  49. package/package.json +1 -1
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pukaad-ui-lib",
3
3
  "configKey": "pukaadUI",
4
- "version": "1.424.0",
4
+ "version": "1.426.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -7,8 +7,8 @@ declare const __VLS_export: import("vue").DefineComponent<CardProfileAboutProps,
7
7
  onChat?: (() => any) | undefined;
8
8
  }>, {
9
9
  type: "article" | "media" | "sale-info";
10
- disabledPadding: boolean;
11
10
  preview: boolean;
11
+ disabledPadding: boolean;
12
12
  optionMenuButtonType: "solid" | "text";
13
13
  actionsHidden: boolean;
14
14
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -7,8 +7,8 @@ declare const __VLS_export: import("vue").DefineComponent<CardProfileAboutProps,
7
7
  onChat?: (() => any) | undefined;
8
8
  }>, {
9
9
  type: "article" | "media" | "sale-info";
10
- disabledPadding: boolean;
11
10
  preview: boolean;
11
+ disabledPadding: boolean;
12
12
  optionMenuButtonType: "solid" | "text";
13
13
  actionsHidden: boolean;
14
14
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -25,6 +25,7 @@ type __VLS_Props = {
25
25
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
26
26
  disabled: boolean;
27
27
  id: string;
28
+ state: string;
28
29
  itemCount: Count;
29
30
  itemActive: Reacted;
30
31
  padding: string | number;
@@ -32,7 +33,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
32
33
  disabledDividerTop: boolean;
33
34
  disabledDividerBottom: boolean;
34
35
  iconSize: number | string;
35
- state: string;
36
36
  loginPath: string;
37
37
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
38
38
  declare const _default: typeof __VLS_export;
@@ -25,6 +25,7 @@ type __VLS_Props = {
25
25
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
26
26
  disabled: boolean;
27
27
  id: string;
28
+ state: string;
28
29
  itemCount: Count;
29
30
  itemActive: Reacted;
30
31
  padding: string | number;
@@ -32,7 +33,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
32
33
  disabledDividerTop: boolean;
33
34
  disabledDividerBottom: boolean;
34
35
  iconSize: number | string;
35
- state: string;
36
36
  loginPath: string;
37
37
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
38
38
  declare const _default: typeof __VLS_export;
@@ -36,17 +36,17 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
36
36
  "onReply-delete"?: ((item: CardReviewProps) => any) | undefined;
37
37
  }>, {
38
38
  item: CardReviewProps;
39
- disabledMenu: boolean;
40
- isProfile: boolean;
41
- disabledLike: boolean;
42
- allowReply: boolean;
43
- replyAvatar: string;
44
39
  place: {
45
40
  id: string | number;
46
41
  name?: string;
47
42
  address?: string;
48
43
  cover?: string;
49
44
  };
45
+ disabledMenu: boolean;
46
+ isProfile: boolean;
47
+ disabledLike: boolean;
48
+ allowReply: boolean;
49
+ replyAvatar: string;
50
50
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
51
51
  declare const _default: typeof __VLS_export;
52
52
  export default _default;
@@ -36,17 +36,17 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
36
36
  "onReply-delete"?: ((item: CardReviewProps) => any) | undefined;
37
37
  }>, {
38
38
  item: CardReviewProps;
39
- disabledMenu: boolean;
40
- isProfile: boolean;
41
- disabledLike: boolean;
42
- allowReply: boolean;
43
- replyAvatar: string;
44
39
  place: {
45
40
  id: string | number;
46
41
  name?: string;
47
42
  address?: string;
48
43
  cover?: string;
49
44
  };
45
+ disabledMenu: boolean;
46
+ isProfile: boolean;
47
+ disabledLike: boolean;
48
+ allowReply: boolean;
49
+ replyAvatar: string;
50
50
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
51
51
  declare const _default: typeof __VLS_export;
52
52
  export default _default;
@@ -40,7 +40,7 @@
40
40
  @click="fileColumns = false"
41
41
  />
42
42
  </div>
43
- <div v-show="!hasCoverText" class="flex gap-[8px]">
43
+ <div v-show="!hasCoverText" class="flex gap-[8px] items-center">
44
44
  <!-- วิดีโอมีได้ตัวเดียว — เปิดช่องอัปโหลดภาพหน้าปก (poster) ไว้ข้างหน้าวิดีโอ -->
45
45
  <InputFile
46
46
  v-if="coverFileType === 'video'"
@@ -159,11 +159,12 @@
159
159
  </template>
160
160
 
161
161
  <script setup>
162
- import { ref, computed, watch } from "vue";
162
+ import { ref, computed, onBeforeUnmount, watch } from "vue";
163
163
  import { useNuxtApp } from "nuxt/app";
164
164
  import { useApi } from "../../composables/useApi";
165
165
  import { usePresignedUpload } from "../../composables/usePresignedUpload";
166
166
  import { CONTENT_COVER_COLORS } from "../../composables/useContentCard";
167
+ import { createVideoThumbnail } from "../../utils/createVideoThumbnail";
167
168
  const emit = defineEmits(["success", "saveDraft"]);
168
169
  const { $toast, $alert } = useNuxtApp();
169
170
  const api = useApi();
@@ -188,6 +189,7 @@ const selectedColor = ref(colors[0].hex);
188
189
  const coverText = ref("");
189
190
  const coverFiles = ref([]);
190
191
  const posterFiles = ref([]);
192
+ const generatedPoster = ref(null);
191
193
  const description = ref("");
192
194
  const fileColumns = ref(false);
193
195
  const selectedPlaces = ref([]);
@@ -227,6 +229,43 @@ watch(coverFileType, (type) => {
227
229
  posterFiles.value = [];
228
230
  }
229
231
  });
232
+ let generatedPosterUrl = "";
233
+ let thumbnailGeneration = 0;
234
+ let thumbnailPromise = Promise.resolve();
235
+ const clearGeneratedPoster = () => {
236
+ if (generatedPosterUrl) URL.revokeObjectURL(generatedPosterUrl);
237
+ generatedPosterUrl = "";
238
+ generatedPoster.value = null;
239
+ };
240
+ watch(
241
+ [() => coverFiles.value[0]?.file, () => posterFiles.value[0]],
242
+ ([videoFile, manualPoster]) => {
243
+ const generation = ++thumbnailGeneration;
244
+ clearGeneratedPoster();
245
+ if (manualPoster || typeof File === "undefined" || !(videoFile instanceof File) || !videoFile.type.startsWith("video/")) {
246
+ thumbnailPromise = Promise.resolve();
247
+ return;
248
+ }
249
+ thumbnailPromise = createVideoThumbnail(videoFile).then((thumbnail) => {
250
+ if (generation !== thumbnailGeneration) return;
251
+ generatedPosterUrl = URL.createObjectURL(thumbnail);
252
+ generatedPoster.value = {
253
+ file: thumbnail,
254
+ url: generatedPosterUrl,
255
+ mediaType: "image"
256
+ };
257
+ }).catch(() => {
258
+ });
259
+ },
260
+ { immediate: true }
261
+ );
262
+ onBeforeUnmount(() => {
263
+ thumbnailGeneration++;
264
+ clearGeneratedPoster();
265
+ });
266
+ const effectivePoster = computed(
267
+ () => posterFiles.value[0] ?? generatedPoster.value
268
+ );
230
269
  const previewItem = computed(() => {
231
270
  if (hasCoverFile.value) {
232
271
  const file = coverFiles.value[0];
@@ -234,7 +273,7 @@ const previewItem = computed(() => {
234
273
  return {
235
274
  id: "preview",
236
275
  type: "video",
237
- video: { src: file.url, poster: posterFiles.value[0]?.url },
276
+ video: { src: file.url, poster: effectivePoster.value?.url },
238
277
  title: description.value,
239
278
  location: previewLocation.value
240
279
  };
@@ -404,9 +443,12 @@ const submitContent = async (status) => {
404
443
  isSubmitting.value = true;
405
444
  try {
406
445
  const contentType = hasCoverFile.value ? coverFileType.value === "video" ? "video" : "image" : "post_it";
446
+ if (contentType === "video" && !posterFiles.value[0]) {
447
+ await thumbnailPromise;
448
+ }
407
449
  const [uploadedMedia, uploadedPoster] = await Promise.all([
408
450
  uploadFiles(coverFiles.value, "content-media"),
409
- contentType === "video" ? uploadFiles(posterFiles.value, "content-media") : Promise.resolve([])
451
+ contentType === "video" && effectivePoster.value ? uploadFiles([effectivePoster.value], "content-media") : Promise.resolve([])
410
452
  ]);
411
453
  const media = uploadedMedia.map((item, index) => ({
412
454
  media_type: contentType === "video" ? "video" : "photo",
@@ -30,9 +30,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
30
30
  "onExplore-places"?: (() => any) | undefined;
31
31
  "onRequire-auth"?: (() => any) | undefined;
32
32
  }>, {
33
- isMyProfile: boolean;
34
33
  profileId: string;
35
34
  defaultTab: "followers" | "following" | "favorites";
35
+ isMyProfile: boolean;
36
36
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
37
37
  declare const _default: typeof __VLS_export;
38
38
  export default _default;
@@ -30,9 +30,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
30
30
  "onExplore-places"?: (() => any) | undefined;
31
31
  "onRequire-auth"?: (() => any) | undefined;
32
32
  }>, {
33
- isMyProfile: boolean;
34
33
  profileId: string;
35
34
  defaultTab: "followers" | "following" | "favorites";
35
+ isMyProfile: boolean;
36
36
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
37
37
  declare const _default: typeof __VLS_export;
38
38
  export default _default;
@@ -64,15 +64,15 @@ declare const __VLS_export: import("vue").DefineComponent<ImageCropperProps, {
64
64
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ImageCropperProps> & Readonly<{}>, {
65
65
  src: string;
66
66
  center: boolean;
67
+ crossorigin: "" | "anonymous" | "use-credentials";
68
+ background: boolean;
69
+ modal: boolean;
67
70
  responsive: boolean;
68
71
  restore: boolean;
69
72
  checkCrossOrigin: boolean;
70
73
  checkOrientation: boolean;
71
- crossorigin: "" | "anonymous" | "use-credentials";
72
- modal: boolean;
73
74
  guides: boolean;
74
75
  highlight: boolean;
75
- background: boolean;
76
76
  autoCrop: boolean;
77
77
  movable: boolean;
78
78
  rotatable: boolean;
@@ -64,15 +64,15 @@ declare const __VLS_export: import("vue").DefineComponent<ImageCropperProps, {
64
64
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ImageCropperProps> & Readonly<{}>, {
65
65
  src: string;
66
66
  center: boolean;
67
+ crossorigin: "" | "anonymous" | "use-credentials";
68
+ background: boolean;
69
+ modal: boolean;
67
70
  responsive: boolean;
68
71
  restore: boolean;
69
72
  checkCrossOrigin: boolean;
70
73
  checkOrientation: boolean;
71
- crossorigin: "" | "anonymous" | "use-credentials";
72
- modal: boolean;
73
74
  guides: boolean;
74
75
  highlight: boolean;
75
- background: boolean;
76
76
  autoCrop: boolean;
77
77
  movable: boolean;
78
78
  rotatable: boolean;
@@ -69,13 +69,13 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
69
69
  name: string;
70
70
  required: boolean;
71
71
  description: string;
72
- options: AutocompleteOption[] | string[] | number[];
73
- placeholder: string;
74
72
  labelKey: string;
73
+ placeholder: string;
74
+ options: AutocompleteOption[] | string[] | number[];
75
+ limit: number;
75
76
  disabledErrorMessage: boolean;
76
77
  disabledBorder: boolean;
77
78
  showCounter: boolean;
78
- limit: number;
79
79
  returnObject: boolean;
80
80
  freeText: boolean;
81
81
  valueKey: string;
@@ -69,13 +69,13 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
69
69
  name: string;
70
70
  required: boolean;
71
71
  description: string;
72
- options: AutocompleteOption[] | string[] | number[];
73
- placeholder: string;
74
72
  labelKey: string;
73
+ placeholder: string;
74
+ options: AutocompleteOption[] | string[] | number[];
75
+ limit: number;
75
76
  disabledErrorMessage: boolean;
76
77
  disabledBorder: boolean;
77
78
  showCounter: boolean;
78
- limit: number;
79
79
  returnObject: boolean;
80
80
  freeText: boolean;
81
81
  valueKey: string;
@@ -30,8 +30,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
30
30
  id: string;
31
31
  name: string;
32
32
  required: boolean;
33
- placeholder: string;
34
33
  locale: string;
34
+ placeholder: string;
35
35
  disabledErrorMessage: boolean;
36
36
  layout: "month-and-year" | "month-only" | "year-only";
37
37
  dateFormat: string;
@@ -30,8 +30,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
30
30
  id: string;
31
31
  name: string;
32
32
  required: boolean;
33
- placeholder: string;
34
33
  locale: string;
34
+ placeholder: string;
35
35
  disabledErrorMessage: boolean;
36
36
  layout: "month-and-year" | "month-only" | "year-only";
37
37
  dateFormat: string;
@@ -44,8 +44,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
44
44
  id: string;
45
45
  name: string;
46
46
  required: boolean;
47
- placeholder: string;
48
47
  locale: string;
48
+ placeholder: string;
49
49
  disabledErrorMessage: boolean;
50
50
  layout: "month-and-year" | "month-only" | "year-only";
51
51
  dateFormat: string;
@@ -44,8 +44,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
44
44
  id: string;
45
45
  name: string;
46
46
  required: boolean;
47
- placeholder: string;
48
47
  locale: string;
48
+ placeholder: string;
49
49
  disabledErrorMessage: boolean;
50
50
  layout: "month-and-year" | "month-only" | "year-only";
51
51
  dateFormat: string;
@@ -34,8 +34,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
34
34
  name: string;
35
35
  fullHeight: boolean;
36
36
  fullWidth: boolean;
37
- disabledErrorMessage: boolean;
38
37
  limit: number;
38
+ disabledErrorMessage: boolean;
39
39
  accept: string;
40
40
  labelIcon: string;
41
41
  disabledDrop: boolean;
@@ -7,6 +7,7 @@
7
7
  ]"
8
8
  >
9
9
  <Draggable
10
+ v-if="arrFiles.length"
10
11
  v-model="arrFiles"
11
12
  :class="[
12
13
  'flex gap-[8px]',
@@ -34,8 +34,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
34
34
  name: string;
35
35
  fullHeight: boolean;
36
36
  fullWidth: boolean;
37
- disabledErrorMessage: boolean;
38
37
  limit: number;
38
+ disabledErrorMessage: boolean;
39
39
  accept: string;
40
40
  labelIcon: string;
41
41
  disabledDrop: boolean;
@@ -17,8 +17,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
17
17
  label: string;
18
18
  name: string;
19
19
  modelValue: InputLinkItem[] | ContactChannel[];
20
- showCounter: boolean;
21
20
  limit: number;
21
+ showCounter: boolean;
22
22
  format: "legacy" | "contact_channel";
23
23
  hideType: boolean;
24
24
  hideAddButton: boolean;
@@ -17,8 +17,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
17
17
  label: string;
18
18
  name: string;
19
19
  modelValue: InputLinkItem[] | ContactChannel[];
20
- showCounter: boolean;
21
20
  limit: number;
21
+ showCounter: boolean;
22
22
  format: "legacy" | "contact_channel";
23
23
  hideType: boolean;
24
24
  hideAddButton: boolean;
@@ -11,10 +11,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
11
11
  label: string;
12
12
  name: string;
13
13
  modelValue: LocalizedNameItem[];
14
- options: InputSelectItem[];
15
14
  placeholder: string;
16
- showCounter: boolean;
15
+ options: InputSelectItem[];
17
16
  limit: number;
17
+ showCounter: boolean;
18
18
  addLabel: string;
19
19
  removable: boolean;
20
20
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -11,10 +11,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
11
11
  label: string;
12
12
  name: string;
13
13
  modelValue: LocalizedNameItem[];
14
- options: InputSelectItem[];
15
14
  placeholder: string;
16
- showCounter: boolean;
15
+ options: InputSelectItem[];
17
16
  limit: number;
17
+ showCounter: boolean;
18
18
  addLabel: string;
19
19
  removable: boolean;
20
20
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -44,8 +44,9 @@
44
44
  />
45
45
  </div>
46
46
  <div v-if="post.type === 'video'" class="shrink-0">
47
- <div class="relative w-[40px] h-[40px] shrink-0">
47
+ <div class="relative w-[40px] h-[40px] shrink-0 bg-black/20 rounded-[4px]">
48
48
  <Image
49
+ v-if="post.thumnail"
49
50
  :src="post.thumnail"
50
51
  :width="40"
51
52
  :height="40"
@@ -185,8 +186,9 @@
185
186
  <Icon name="fa6-solid:message" size="24" class="text-primary" />
186
187
  </div>
187
188
  <div v-else-if="item.type === 'video'" class="shrink-0">
188
- <div class="relative w-[40px] h-[40px] shrink-0">
189
+ <div class="relative w-[40px] h-[40px] shrink-0 bg-black/20 rounded-[4px]">
189
190
  <Image
191
+ v-if="item.thumnail"
190
192
  :src="item.thumnail"
191
193
  :width="40"
192
194
  :height="40"
@@ -334,7 +336,7 @@ const mapContentToPostOption = (raw) => {
334
336
  type,
335
337
  title,
336
338
  image: type === "image" ? firstMedia?.url ?? null : null,
337
- thumnail: type === "video" ? raw.video_poster_url || firstMedia?.url : void 0
339
+ thumnail: type === "video" ? raw.video_poster_url : void 0
338
340
  };
339
341
  };
340
342
  const mapBlogToOption = (raw) => ({
@@ -36,8 +36,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
36
36
  id: string;
37
37
  name: string;
38
38
  required: boolean;
39
- readonly: boolean;
40
39
  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;
@@ -36,8 +36,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
36
36
  id: string;
37
37
  name: string;
38
38
  required: boolean;
39
- readonly: boolean;
40
39
  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;
@@ -20,12 +20,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
20
20
  name: string;
21
21
  required: boolean;
22
22
  description: string;
23
- placeholder: string;
24
23
  labelKey: string;
24
+ placeholder: string;
25
+ limit: number;
25
26
  disabledErrorMessage: boolean;
26
27
  disabledBorder: boolean;
27
28
  showCounter: boolean;
28
- limit: number;
29
29
  descriptionKey: string;
30
30
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
31
  declare const _default: typeof __VLS_export;
@@ -20,12 +20,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
20
20
  name: string;
21
21
  required: boolean;
22
22
  description: string;
23
- placeholder: string;
24
23
  labelKey: string;
24
+ placeholder: string;
25
+ limit: number;
25
26
  disabledErrorMessage: boolean;
26
27
  disabledBorder: boolean;
27
28
  showCounter: boolean;
28
- limit: number;
29
29
  descriptionKey: string;
30
30
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
31
  declare const _default: typeof __VLS_export;
@@ -40,9 +40,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
40
40
  id: string;
41
41
  name: string;
42
42
  required: boolean;
43
- options: InputTagModalOption[];
44
- placeholder: string;
45
43
  labelKey: string;
44
+ placeholder: string;
45
+ options: InputTagModalOption[];
46
46
  disabledErrorMessage: boolean;
47
47
  valueKey: string;
48
48
  searchPlaceholder: string;
@@ -40,9 +40,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
40
40
  id: string;
41
41
  name: string;
42
42
  required: boolean;
43
- options: InputTagModalOption[];
44
- placeholder: string;
45
43
  labelKey: string;
44
+ placeholder: string;
45
+ options: InputTagModalOption[];
46
46
  disabledErrorMessage: boolean;
47
47
  valueKey: string;
48
48
  searchPlaceholder: string;
@@ -26,8 +26,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
26
26
  "onUpdate:modelValue"?: ((value: SelectedTag[]) => any) | undefined;
27
27
  }>, {
28
28
  name: string;
29
- state: "user" | "admin";
30
29
  placeholder: string;
30
+ state: "user" | "admin";
31
31
  profileScope: "personal" | "business";
32
32
  limit: number;
33
33
  ignore: string[];
@@ -26,8 +26,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
26
26
  "onUpdate:modelValue"?: ((value: SelectedTag[]) => any) | undefined;
27
27
  }>, {
28
28
  name: string;
29
- state: "user" | "admin";
30
29
  placeholder: string;
30
+ state: "user" | "admin";
31
31
  profileScope: "personal" | "business";
32
32
  limit: number;
33
33
  ignore: string[];
@@ -60,10 +60,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
60
60
  name: string;
61
61
  required: boolean;
62
62
  readonly: boolean;
63
+ limit: number;
63
64
  disabledErrorMessage: boolean;
64
65
  disabledBorder: boolean;
65
66
  showCounter: boolean;
66
- limit: number;
67
67
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
68
68
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
69
69
  declare const _default: typeof __VLS_export;
@@ -60,10 +60,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
60
60
  name: string;
61
61
  required: boolean;
62
62
  readonly: boolean;
63
+ limit: number;
63
64
  disabledErrorMessage: boolean;
64
65
  disabledBorder: boolean;
65
66
  showCounter: boolean;
66
- limit: number;
67
67
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
68
68
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
69
69
  declare const _default: typeof __VLS_export;
@@ -46,12 +46,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
46
46
  resize: "none" | "both" | "horizontal" | "vertical";
47
47
  fullHeight: boolean;
48
48
  fullWidth: boolean;
49
- readonly: boolean;
50
49
  rows: number;
50
+ readonly: boolean;
51
+ limit: number;
51
52
  disabledErrorMessage: boolean;
52
53
  disabledBorder: boolean;
53
54
  showCounter: boolean;
54
- limit: number;
55
55
  heightScroll: boolean;
56
56
  spaceToComma: boolean;
57
57
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -46,12 +46,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
46
46
  resize: "none" | "both" | "horizontal" | "vertical";
47
47
  fullHeight: boolean;
48
48
  fullWidth: boolean;
49
- readonly: boolean;
50
49
  rows: number;
50
+ readonly: boolean;
51
+ limit: number;
51
52
  disabledErrorMessage: boolean;
52
53
  disabledBorder: boolean;
53
54
  showCounter: boolean;
54
- limit: number;
55
55
  heightScroll: boolean;
56
56
  spaceToComma: boolean;
57
57
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -22,8 +22,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
22
22
  name: string;
23
23
  required: boolean;
24
24
  options: import("../../../types/components/input/input-select.js").InputSelectItem[];
25
- showCounter: boolean;
26
25
  limit: number;
26
+ showCounter: boolean;
27
27
  removable: boolean;
28
28
  selectClass: import("vue").HTMLAttributes["class"];
29
29
  resetOnTypeChange: boolean;
@@ -22,8 +22,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
22
22
  name: string;
23
23
  required: boolean;
24
24
  options: import("../../../types/components/input/input-select.js").InputSelectItem[];
25
- showCounter: boolean;
26
25
  limit: number;
26
+ showCounter: boolean;
27
27
  removable: boolean;
28
28
  selectClass: import("vue").HTMLAttributes["class"];
29
29
  resetOnTypeChange: boolean;
@@ -18,8 +18,8 @@ type __VLS_Slots = {} & {
18
18
  default?: (props: typeof __VLS_1) => any;
19
19
  };
20
20
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
21
- payload: Record<string, any>;
22
21
  config: ChartConfig;
22
+ payload: Record<string, any>;
23
23
  indicator: "line" | "dot" | "dashed";
24
24
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
25
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -18,8 +18,8 @@ type __VLS_Slots = {} & {
18
18
  default?: (props: typeof __VLS_1) => any;
19
19
  };
20
20
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
21
- payload: Record<string, any>;
22
21
  config: ChartConfig;
22
+ payload: Record<string, any>;
23
23
  indicator: "line" | "dot" | "dashed";
24
24
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
25
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -14,7 +14,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
14
14
  dir?: string | undefined | undefined;
15
15
  draggable?: (boolean | "true" | "false") | undefined;
16
16
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
17
- enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
17
+ enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
18
18
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
19
19
  id?: string | undefined | undefined;
20
20
  inert?: (boolean | "true" | "false") | undefined;
@@ -208,7 +208,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
208
208
  dir?: string | undefined | undefined;
209
209
  draggable?: (boolean | "true" | "false") | undefined;
210
210
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
211
- enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
211
+ enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
212
212
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
213
213
  id?: string | undefined | undefined;
214
214
  inert?: (boolean | "true" | "false") | undefined;
@@ -14,7 +14,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
14
14
  dir?: string | undefined | undefined;
15
15
  draggable?: (boolean | "true" | "false") | undefined;
16
16
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
17
- enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
17
+ enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
18
18
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
19
19
  id?: string | undefined | undefined;
20
20
  inert?: (boolean | "true" | "false") | undefined;
@@ -208,7 +208,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
208
208
  dir?: string | undefined | undefined;
209
209
  draggable?: (boolean | "true" | "false") | undefined;
210
210
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
211
- enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
211
+ enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
212
212
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
213
213
  id?: string | undefined | undefined;
214
214
  inert?: (boolean | "true" | "false") | undefined;
@@ -16,7 +16,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
16
16
  dir?: string | undefined | undefined;
17
17
  draggable?: (boolean | "true" | "false") | undefined;
18
18
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
19
- enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
19
+ enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
20
20
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
21
21
  id?: string | undefined | undefined;
22
22
  inert?: (boolean | "true" | "false") | undefined;
@@ -212,7 +212,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
212
212
  dir?: string | undefined | undefined;
213
213
  draggable?: (boolean | "true" | "false") | undefined;
214
214
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
215
- enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
215
+ enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
216
216
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
217
217
  id?: string | undefined | undefined;
218
218
  inert?: (boolean | "true" | "false") | undefined;
@@ -16,7 +16,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
16
16
  dir?: string | undefined | undefined;
17
17
  draggable?: (boolean | "true" | "false") | undefined;
18
18
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
19
- enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
19
+ enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
20
20
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
21
21
  id?: string | undefined | undefined;
22
22
  inert?: (boolean | "true" | "false") | undefined;
@@ -212,7 +212,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
212
212
  dir?: string | undefined | undefined;
213
213
  draggable?: (boolean | "true" | "false") | undefined;
214
214
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
215
- enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
215
+ enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
216
216
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
217
217
  id?: string | undefined | undefined;
218
218
  inert?: (boolean | "true" | "false") | undefined;
@@ -0,0 +1 @@
1
+ export declare const createVideoThumbnail: (file: File, atSecond?: number) => Promise<File>;
@@ -0,0 +1,47 @@
1
+ export const createVideoThumbnail = (file, atSecond = 0.1) => new Promise((resolve, reject) => {
2
+ const video = document.createElement("video");
3
+ const objectUrl = URL.createObjectURL(file);
4
+ const timeout = window.setTimeout(fail, 1e4);
5
+ function cleanup() {
6
+ window.clearTimeout(timeout);
7
+ URL.revokeObjectURL(objectUrl);
8
+ }
9
+ function fail() {
10
+ cleanup();
11
+ reject(new Error("Failed to create video thumbnail"));
12
+ }
13
+ video.preload = "auto";
14
+ video.muted = true;
15
+ video.playsInline = true;
16
+ video.src = objectUrl;
17
+ video.addEventListener("error", fail, { once: true });
18
+ video.addEventListener(
19
+ "loadeddata",
20
+ () => {
21
+ const duration = Number.isFinite(video.duration) ? video.duration : 0;
22
+ const target = duration > 0 ? Math.min(atSecond, duration / 2) : 0;
23
+ if (target === 0) captureFrame();
24
+ else video.currentTime = target;
25
+ },
26
+ { once: true }
27
+ );
28
+ video.addEventListener("seeked", captureFrame, { once: true });
29
+ function captureFrame() {
30
+ const canvas = document.createElement("canvas");
31
+ canvas.width = video.videoWidth;
32
+ canvas.height = video.videoHeight;
33
+ canvas.getContext("2d")?.drawImage(video, 0, 0);
34
+ canvas.toBlob(
35
+ (blob) => {
36
+ cleanup();
37
+ if (!blob)
38
+ return reject(new Error("Failed to create video thumbnail"));
39
+ resolve(
40
+ new File([blob], "video-thumbnail.jpg", { type: "image/jpeg" })
41
+ );
42
+ },
43
+ "image/jpeg",
44
+ 0.85
45
+ );
46
+ }
47
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pukaad-ui-lib",
3
- "version": "1.424.0",
3
+ "version": "1.426.0",
4
4
  "description": "pukaad-ui for MeMSG",
5
5
  "repository": {
6
6
  "type": "git",