diff --git a/app/src/media/storage/Storage.ts b/app/src/media/storage/Storage.ts index 6615f8e..1d11b1d 100644 --- a/app/src/media/storage/Storage.ts +++ b/app/src/media/storage/Storage.ts @@ -71,22 +71,29 @@ export class Storage implements EmitsEvents { let info: FileUploadPayload = { name, - meta: { - size: 0, - type: "application/octet-stream", - }, + meta: isFile(file) + ? { + size: file.size, + type: file.type, + } + : { + size: 0, + type: "application/octet-stream", + }, etag: typeof result === "string" ? result : "", }; + // normally only etag is returned if (typeof result === "object") { info = result; - } else if (isFile(file)) { - info.meta.size = file.size; - info.meta.type = file.type; } // try to get better meta info - if (!isMimeType(info.meta.type, ["application/octet-stream", "application/json"])) { + if ( + !info.meta.type || + ["application/octet-stream", "application/json"].includes(info.meta.type) || + !info.meta.size + ) { const meta = await this.#adapter.getObjectMeta(name); if (!meta) { throw new Error("Failed to get object meta"); diff --git a/app/src/media/storage/mime-types-tiny.ts b/app/src/media/storage/mime-types-tiny.ts index 16598b6..fcadd55 100644 --- a/app/src/media/storage/mime-types-tiny.ts +++ b/app/src/media/storage/mime-types-tiny.ts @@ -2,8 +2,8 @@ export const Q = { video: ["mp4", "webm"], audio: ["ogg"], image: ["jpeg", "png", "gif", "webp", "bmp", "tiff", "avif", "heic", "heif"], - text: ["html", "css", "mdx", "yaml", "vcard", "csv", "vtt"], - application: ["zip", "xml", "toml", "json", "json5", "pdf"], + text: ["html", "css", "mdx", "yaml", "vcard", "csv", "vtt", "xml"], + application: ["zip", "toml", "json", "json5", "pdf", "sql"], font: ["woff", "woff2", "ttf", "otf"], } as const; diff --git a/app/src/ui/elements/media/DropzoneInner.tsx b/app/src/ui/elements/media/DropzoneInner.tsx index db3402e..742ca3b 100644 --- a/app/src/ui/elements/media/DropzoneInner.tsx +++ b/app/src/ui/elements/media/DropzoneInner.tsx @@ -1,7 +1,22 @@ import { type ComponentPropsWithoutRef, memo, type ReactNode, useCallback, useMemo } from "react"; import { twMerge } from "tailwind-merge"; import { useRenderCount } from "ui/hooks/use-render-count"; -import { TbDots, TbExternalLink, TbTrash, TbUpload } from "react-icons/tb"; +import { + TbDots, + TbExternalLink, + TbFileTypeCsv, + TbFileText, + TbJson, + TbFileTypePdf, + TbMarkdown, + TbMusic, + TbTrash, + TbUpload, + TbFileTypeTxt, + TbFileTypeXml, + TbZip, + TbFileTypeSql, +} from "react-icons/tb"; import { Dropdown, type DropdownItem } from "ui/components/overlay/Dropdown"; import { IconButton } from "ui/components/buttons/IconButton"; import { formatNumber } from "core/utils"; @@ -85,7 +100,7 @@ const UploadPlaceholder = ({ onClick, text = "Upload files" }) => { ); }; -type ReducedFile = Pick; +type ReducedFile = Omit; export type PreviewComponentProps = { file: ReducedFile; fallback?: (props: { file: ReducedFile }) => ReactNode; @@ -271,8 +286,59 @@ const VideoPreview = ({ return