From b0628fe0bdebca6b327231253475fbb18b9027a1 Mon Sep 17 00:00:00 2001 From: 409 <409dev@protonmail.com> Date: Sun, 13 Jul 2025 13:33:14 +0200 Subject: [PATCH] better file previews --- backend/Cargo.lock | 1 + backend/Cargo.toml | 1 + backend/src/fs/mod.rs | 16 ++++++++-- frontend/components/DirectoryEntry.vue | 18 +++++------ frontend/components/DirectoryList.vue | 3 +- frontend/components/actions/UploadDialog.vue | 3 +- .../components/actions/UploadListEntry.vue | 30 +++++++++++++----- frontend/types/index.ts | 1 + frontend/utils/icons.ts | 31 +++++++++++++------ 9 files changed, 71 insertions(+), 33 deletions(-) diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 5ebcbb9..52cc20b 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -1960,6 +1960,7 @@ dependencies = [ "dotenv", "env_logger", "log", + "mime_guess", "serde", "serde_json", "sqlx", diff --git a/backend/Cargo.toml b/backend/Cargo.toml index d5eab92..8585b29 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -8,6 +8,7 @@ axum = { version = "0.8.4", features = ["multipart", "query"] } dotenv = "0.15.0" env_logger = "0.11.8" log = "0.4.27" +mime_guess = "2.0.5" serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.140" sqlx = { version = "0.8.6", features = ["postgres", "runtime-tokio", "uuid"] } diff --git a/backend/src/fs/mod.rs b/backend/src/fs/mod.rs index f5381d4..ca3b4ca 100644 --- a/backend/src/fs/mod.rs +++ b/backend/src/fs/mod.rs @@ -5,7 +5,7 @@ pub use file::*; use serde::{Deserialize, Serialize}; -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum FileType { File, @@ -17,10 +17,22 @@ pub enum FileType { pub struct DirectoryEntry { name: String, file_type: FileType, + mime_type: Option, } impl DirectoryEntry { pub fn new(name: String, file_type: FileType) -> Self { - Self { name, file_type } + let mime_type = match name.split("/").last() { + Some(last) if last.contains(".") => { + mime_guess::from_path(&name).first_raw().map(str::to_owned) + } + _ => None, + }; + + Self { + name, + file_type, + mime_type, + } } } diff --git a/frontend/components/DirectoryEntry.vue b/frontend/components/DirectoryEntry.vue index 7ccefdd..d99e0aa 100644 --- a/frontend/components/DirectoryEntry.vue +++ b/frontend/components/DirectoryEntry.vue @@ -6,26 +6,22 @@ import { ContextMenuItem, } from '@/components/ui/context-menu'; import { deleteWarrenEntry } from '~/lib/api/warrens'; -import type { FileType } from '~/types'; +import type { DirectoryEntry } from '~/types'; const route = useRoute(); const warrenRoute = useWarrenRoute(); -const { name, fileType, disabled } = defineProps<{ - name: string; - fileType: FileType; +const { entry, disabled } = defineProps<{ + entry: DirectoryEntry; disabled: boolean; }>(); -const iconName = computed(() => - fileType === 'file' ? 'lucide:file' : 'lucide:folder' -); const deleting = ref(false); async function submitDelete() { deleting.value = true; - await deleteWarrenEntry(warrenRoute.value, name, fileType); + await deleteWarrenEntry(warrenRoute.value, entry.name, entry.fileType); deleting.value = false; } @@ -35,7 +31,7 @@ async function submitDelete() { diff --git a/frontend/components/DirectoryList.vue b/frontend/components/DirectoryList.vue index d0af4fc..b1df74d 100644 --- a/frontend/components/DirectoryList.vue +++ b/frontend/components/DirectoryList.vue @@ -18,8 +18,7 @@ const sortedEntries = computed(() => diff --git a/frontend/components/actions/UploadDialog.vue b/frontend/components/actions/UploadDialog.vue index f917935..dfe2eb2 100644 --- a/frontend/components/actions/UploadDialog.vue +++ b/frontend/components/actions/UploadDialog.vue @@ -216,14 +216,13 @@ async function submit() { class="h-full w-full" >
diff --git a/frontend/components/actions/UploadListEntry.vue b/frontend/components/actions/UploadListEntry.vue index f1bcb29..098c329 100644 --- a/frontend/components/actions/UploadListEntry.vue +++ b/frontend/components/actions/UploadListEntry.vue @@ -8,18 +8,34 @@ const { file, uploading } = defineProps<{ file: UploadFile; uploading: boolean; }>(); + +function createObjectUrl(file: File): string { + return URL.createObjectURL(file); +}