|
5 | 5 | import { _ } from "svelte-i18n";
|
6 | 6 | import UploadProgress from "./UploadProgress.svelte";
|
7 | 7 |
|
8 |
| - export let filetype: string | null = null; |
| 8 | + export let filetype: string | string[] | null = null; |
9 | 9 | export let dragging = false;
|
10 | 10 | export let boundedheight = true;
|
11 | 11 | export let center = true;
|
|
20 | 20 |
|
21 | 21 | let upload_id: string;
|
22 | 22 | let file_data: FileData[];
|
| 23 | + let accept_file_types: string | null; |
23 | 24 |
|
24 | 25 | // Needed for wasm support
|
25 | 26 | const upload_fn = getContext<typeof upload_files>("upload_files");
|
|
28 | 29 |
|
29 | 30 | const dispatch = createEventDispatcher();
|
30 | 31 |
|
| 32 | + $: if (filetype == null || typeof filetype === "string") { |
| 33 | + accept_file_types = filetype; |
| 34 | + } else { |
| 35 | + filetype = filetype.map((x) => { |
| 36 | + if (x.startsWith(".")) { |
| 37 | + return x; |
| 38 | + } |
| 39 | + return x + "/*"; |
| 40 | + }); |
| 41 | + accept_file_types = filetype.join(", "); |
| 42 | + } |
31 | 43 | function updateDragging(): void {
|
32 | 44 | dragging = !dragging;
|
33 | 45 | }
|
|
76 | 88 | }
|
77 | 89 |
|
78 | 90 | function is_valid_mimetype(
|
79 |
| - file_accept: string | null, |
| 91 | + file_accept: string | string[] | null, |
80 | 92 | mime_type: string
|
81 | 93 | ): boolean {
|
82 |
| - if (!file_accept) { |
| 94 | + if (!file_accept || file_accept === "*" || file_accept === "file/*") { |
83 | 95 | return true;
|
84 | 96 | }
|
85 |
| - if (file_accept === "*") { |
86 |
| - return true; |
| 97 | + if (typeof file_accept === "string" && file_accept.endsWith("/*")) { |
| 98 | + file_accept = file_accept.split(","); |
87 | 99 | }
|
88 |
| - if (file_accept.endsWith("/*")) { |
89 |
| - return mime_type.startsWith(file_accept.slice(0, -1)); |
| 100 | + if (Array.isArray(file_accept)) { |
| 101 | + return ( |
| 102 | + file_accept.includes(mime_type) || |
| 103 | + file_accept.some((type) => { |
| 104 | + const [category] = type.split("/"); |
| 105 | + return type.endsWith("/*") && mime_type.startsWith(category + "/"); |
| 106 | + }) |
| 107 | + ); |
90 | 108 | }
|
91 | 109 | return file_accept === mime_type;
|
92 | 110 | }
|
|
96 | 114 | if (!e.dataTransfer?.files) return;
|
97 | 115 |
|
98 | 116 | const files_to_load = Array.from(e.dataTransfer.files).filter((f) => {
|
99 |
| - if (filetype?.split(",").some((m) => is_valid_mimetype(m, f.type))) { |
| 117 | + const file_extension = |
| 118 | + f.type !== "" ? f.type : "." + f.name.split(".").pop(); |
| 119 | + if (file_extension && is_valid_mimetype(filetype, file_extension)) { |
100 | 120 | return true;
|
101 | 121 | }
|
102 | 122 | dispatch("error", `Invalid file type only ${filetype} allowed.`);
|
103 | 123 | return false;
|
104 | 124 | });
|
105 |
| -
|
106 | 125 | await load_files(files_to_load);
|
107 | 126 | }
|
108 | 127 | </script>
|
|
137 | 156 | type="file"
|
138 | 157 | bind:this={hidden_upload}
|
139 | 158 | on:change={load_files_from_upload}
|
140 |
| - accept={filetype} |
| 159 | + accept={accept_file_types} |
141 | 160 | multiple={file_count === "multiple" || undefined}
|
142 | 161 | webkitdirectory={file_count === "directory" || undefined}
|
143 | 162 | mozdirectory={file_count === "directory" || undefined}
|
|
0 commit comments