|
9 | 9 | import AudioPlayer from "../players/AudioPlayer.svelte"; |
10 | 10 | import EosIconsLoading from "~icons/eos-icons/loading"; |
11 | 11 | import { base } from "$app/paths"; |
| 12 | + import { TEXT_MIME_ALLOWLIST } from "$lib/constants/mime"; |
12 | 13 |
|
13 | 14 | interface Props { |
14 | 15 | file: MessageFile; |
|
43 | 44 | const isVideo = (mime: string) => |
44 | 45 | mime.startsWith("video/") || mime === "mp4" || mime === "x-mpeg"; |
45 | 46 |
|
| 47 | + function matchesAllowed(contentType: string, allowed: readonly string[]): boolean { |
| 48 | + const ct = contentType.split(";")[0]?.trim().toLowerCase(); |
| 49 | + if (!ct) return false; |
| 50 | + const [ctType, ctSubtype] = ct.split("/"); |
| 51 | + for (const a of allowed) { |
| 52 | + const [aType, aSubtype] = a.toLowerCase().split("/"); |
| 53 | + const typeOk = aType === "*" || aType === ctType; |
| 54 | + const subOk = aSubtype === "*" || aSubtype === ctSubtype; |
| 55 | + if (typeOk && subOk) return true; |
| 56 | + } |
| 57 | + return false; |
| 58 | + } |
| 59 | +
|
46 | 60 | const isPlainText = (mime: string) => |
47 | | - mime === "text/plain" || |
48 | | - mime === "text/csv" || |
49 | | - mime === "text/markdown" || |
50 | | - mime === "application/json" || |
51 | | - mime === "application/xml" || |
52 | | - mime === "application/vnd.chatui.clipboard"; |
| 61 | + mime === "application/vnd.chatui.clipboard" || matchesAllowed(mime, TEXT_MIME_ALLOWLIST); |
53 | 62 |
|
54 | 63 | let isClickable = $derived(isImage(file.mime) || isPlainText(file.mime)); |
55 | 64 | </script> |
56 | 65 |
|
57 | 66 | {#if showModal && isClickable} |
58 | 67 | <!-- show the image file full screen, click outside to exit --> |
59 | | - <Modal width="sm:max-w-[800px]" onclose={() => (showModal = false)}> |
| 68 | + <Modal width="xl:max-w-[75dvw]" onclose={() => (showModal = false)}> |
60 | 69 | {#if isImage(file.mime)} |
61 | 70 | {#if file.type === "hash"} |
62 | 71 | <img |
|
182 | 191 | {/if} |
183 | 192 | </dl> |
184 | 193 | </div> |
185 | | -{:else if file.mime === "application/octet-stream"} |
| 194 | + {:else if file.mime === "application/octet-stream"} |
186 | 195 | <div |
187 | 196 | class="flex h-14 w-72 items-center gap-2 overflow-hidden rounded-xl border border-gray-200 bg-white p-2 dark:border-gray-800 dark:bg-gray-900" |
188 | 197 | class:file-hoverable={isClickable} |
|
0 commit comments