8
8
controls :alt =" attachment.description ?? undefined" :src =" attachment.url" >
9
9
Your browser does not support the video tag.
10
10
</video >
11
+ <a v-else class =" bg-dark-800 w-full h-full rounded flex items-center justify-center" :href =" attachment.url"
12
+ target =" _blank" download >
13
+ <div class =" flex flex-col items-center gap-2 max-w-56 overflow-hidden text-ellipsis" >
14
+ <iconify-icon icon =" tabler:file" width =" none" class =" size-10 text-gray-300" />
15
+ <p class =" text-gray-300 text-sm font-mono" >{{ getFilename(attachment.url) }}</p >
16
+ <p class =" text-gray-300 text-xs" v-if =" attachment.meta?.length" >{{
17
+ formatBytes(Number(attachment.meta?.length)) }}</p >
18
+ </div >
19
+ </a >
11
20
<!-- Alt text viewer -->
12
21
<Popover .Root :positioning =" {
13
22
strategy: 'fixed',
@@ -36,4 +45,24 @@ const props = defineProps<{
36
45
const openLightbox = () => {
37
46
useEvent (" attachment:view" , props .attachment );
38
47
};
48
+
49
+ const formatBytes = (bytes : number ) => {
50
+ if (bytes === 0 ) return " 0 Bytes" ;
51
+ const k = 1000 ;
52
+ const dm = 2 ;
53
+ const sizes = [" Bytes" , " KB" , " MB" , " GB" , " TB" , " PB" , " EB" , " ZB" , " YB" ];
54
+ const i = Math .floor (Math .log (bytes ) / Math .log (k ));
55
+ return ` ${Number .parseFloat ((bytes / k ** i ).toFixed (dm ))} ${sizes [i ]} ` ;
56
+ };
57
+
58
+ const getFilename = (url : string ) => {
59
+ // Handle proxy case
60
+ if (url .includes (" /media/proxy" )) {
61
+ // Decode last part of URL as base64url, which is the real URL
62
+ const realUrl = atob (url .split (" /" ).pop () ?? " " );
63
+ return realUrl .substring (realUrl .lastIndexOf (" /" ) + 1 );
64
+ }
65
+ const path = new URL (url ).pathname ;
66
+ return path .substring (path .lastIndexOf (" /" ) + 1 );
67
+ };
39
68
</script >
0 commit comments