@@ -25,27 +25,27 @@ const isValidFileType = (item: TreeItem) => {
2525 return false
2626}
2727
28- const imageFiles = computed (() => {
29- const images : TreeItem [] = []
28+ const mediaFiles = computed (() => {
29+ const medias : TreeItem [] = []
3030
31- const collectImages = (items : TreeItem []) => {
31+ const collectMedias = (items : TreeItem []) => {
3232 for (const item of items ) {
3333 if (item .type === ' file' && isValidFileType (item )) {
34- images .push (item )
34+ medias .push (item )
3535 }
3636 if (item .children ) {
37- collectImages (item .children )
37+ collectMedias (item .children )
3838 }
3939 }
4040 }
4141
42- collectImages (mediaTree .root .value )
42+ collectMedias (mediaTree .root .value )
4343
44- return images
44+ return medias
4545})
4646
47- const handleImageSelect = (image : TreeItem ) => {
48- emit (' select' , image )
47+ const handleMediaSelect = (media : TreeItem ) => {
48+ emit (' select' , media )
4949}
5050
5151const handleUpload = () => {
@@ -57,21 +57,21 @@ const handleUpload = () => {
5757<template >
5858 <UModal
5959 :open =" open"
60- :title =" $t(' studio.mediaPicker.title' )"
61- :description =" $t(' studio.mediaPicker.description' )"
60+ :title =" $t(` studio.mediaPicker.${type}. title` )"
61+ :description =" $t(` studio.mediaPicker.${type}. description` )"
6262 @update:open =" (value: boolean) => !value && emit('cancel')"
6363 >
6464 <template #body >
6565 <div
66- v-if =" imageFiles .length === 0"
66+ v-if =" mediaFiles .length === 0"
6767 class =" text-center py-4 text-muted"
6868 >
6969 <UIcon
70- name =" i-lucide-image-off"
70+ : name =" type === 'image' ? ' i-lucide-image-off' : 'i-lucide-video-off' "
7171 class =" size-8 mx-auto mb-2"
7272 />
7373 <p class =" text-sm" >
74- {{ $t(' studio.mediaPicker.noImagesAvailable' ) }}
74+ {{ $t(` studio.mediaPicker.${type}.notAvailable` ) }}
7575 </p >
7676 </div >
7777
@@ -80,23 +80,59 @@ const handleUpload = () => {
8080 class =" grid grid-cols-3 gap-4"
8181 >
8282 <button
83- v-for =" image in imageFiles "
84- :key =" image .fsPath"
85- class =" aspect-square rounded-lg overflow-hidden border border-default hover:border-accented hover:ring-1 hover:ring-accented transition-all cursor-pointer group relative"
86- @click =" handleImageSelect(image )"
83+ v-for =" media in mediaFiles "
84+ :key =" media .fsPath"
85+ class =" aspect-square rounded-lg cursor-pointer group relative"
86+ @click =" handleMediaSelect(media )"
8787 >
88+ <!-- Image Preview -->
8889 <div
89- class =" w-full h-full"
90+ v-if =" type === 'image'"
91+ class =" w-full h-full overflow-hidden rounded-lg border border-default hover:border-muted hover:ring-1 hover:ring-muted transition-all"
9092 style =" background : repeating-linear-gradient (45deg , #d4d4d8 0 12px , #a1a1aa 0 24px ), repeating-linear-gradient (-45deg , #a1a1aa 0 12px , #d4d4d8 0 24px ); background-blend-mode : overlay ; background-size : 24px 24px ;"
9193 >
9294 <Image
93- :src =" image .routePath || image .fsPath"
95+ :src =" media .routePath || media .fsPath"
9496 width =" 200"
9597 height =" 200"
96- :alt =" image .name"
97- class =" w-full h-full object-cover"
98+ :alt =" media .name"
99+ class =" w-full h-full object-cover rounded-lg group-hover:scale-105 transition-transform duration-300 ease-out "
98100 />
99101 </div >
102+
103+ <!-- Video Preview -->
104+ <div
105+ v-else
106+ class =" w-full h-full bg-linear-to-br from-neutral-900 via-neutral-800 to-neutral-900 flex flex-col items-center justify-center relative overflow-hidden rounded-lg"
107+ >
108+ <!-- Decorative film strip pattern -->
109+ <div class =" absolute inset-y-0 left-0 w-3 bg-neutral-950 flex flex-col justify-around py-1" >
110+ <div
111+ v-for =" i in 6"
112+ :key =" i"
113+ class =" w-1.5 h-2 bg-neutral-700 mx-auto rounded-sm"
114+ />
115+ </div >
116+ <div class =" absolute inset-y-0 right-0 w-3 bg-neutral-950 flex flex-col justify-around py-1" >
117+ <div
118+ v-for =" i in 6"
119+ :key =" i"
120+ class =" w-1.5 h-2 bg-neutral-700 mx-auto rounded-sm"
121+ />
122+ </div >
123+
124+ <div class =" size-14 rounded-full bg-white/10 backdrop-blur-sm flex items-center justify-center group-hover:bg-white/20 group-hover:scale-110 transition-all duration-300 shadow-lg" >
125+ <UIcon
126+ name =" i-lucide-video"
127+ class =" size-7 text-white ml-0.5"
128+ />
129+ </div >
130+
131+ <!-- Filename -->
132+ <p class =" absolute bottom-0 inset-x-0 text-[10px] text-neutral-300 truncate px-4 py-2 bg-linear-to-t from-black/60 to-transparent text-center font-medium" >
133+ {{ media.name }}
134+ </p >
135+ </div >
100136 </button >
101137 </div >
102138 </template >
@@ -107,7 +143,7 @@ const handleUpload = () => {
107143 icon =" i-lucide-upload"
108144 @click =" handleUpload"
109145 >
110- {{ $t(' studio.mediaPicker.upload' ) }}
146+ {{ $t(` studio.mediaPicker.${type}. upload` ) }}
111147 </UButton >
112148 </template >
113149 </UModal >
0 commit comments