Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 10x 10x 10x 1x 10x 1x 1x 1x 1x 1x 10x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 10x | import { useRef, useCallback, useState } from "react";
export type FileEntry = { name: string; content: string };
export interface UseFileManagerOptions {
tabs?: Array<{ name: string; content: string }>;
onFilesLoaded?: (files: FileEntry[], replaceAll: boolean) => void;
toast?: (params: { title: string; description?: string; variant?: string }) => void;
}
export function useFileManager({ tabs = [], onFilesLoaded, toast }: UseFileManagerOptions = {}) {
const fileInputRef = useRef<HTMLInputElement | null>(null);
const [lastLoadedFiles, setLastLoadedFiles] = useState<FileEntry[] | null>(null);
const onLoadFiles = useCallback(() => {
fileInputRef.current?.click();
}, []);
const downloadAllFiles = useCallback(async (providedTabs?: Array<{ name: string; content: string }>) => {
const which = providedTabs ?? tabs ?? [];
Eif (!which || which.length === 0) {
try {
toast?.({ title: "Nothing to download", description: "There are no open files to download" });
} catch {}
return;
}
which.forEach((tab, index) => {
setTimeout(() => {
const element = document.createElement("a");
element.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(tab.content));
element.setAttribute("download", tab.name);
(element as any).style.display = "none";
document.body.appendChild(element);
(element as any).click();
document.body.removeChild(element);
}, index * 200);
});
setTimeout(() => {
try {
toast?.({ title: "Download started", description: `${which.length} file(s) will be downloaded` });
} catch {}
}, which.length * 200 + 100);
}, [tabs, toast]);
const handleHiddenFileInput = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {
const fl = e.target.files;
Iif (!fl || fl.length === 0) return;
const files: FileEntry[] = [];
for (const f of Array.from(fl)) {
Iif (!f.name.endsWith(".ino") && !f.name.endsWith(".h")) continue;
try {
const txt = await f.text();
files.push({ name: f.name, content: txt });
} catch {}
}
Eif (files.length > 0) {
setLastLoadedFiles(files);
onFilesLoaded?.(files, false);
}
// clear input value to allow re-upload of same file
Iif (fileInputRef.current) fileInputRef.current.value = "";
}, [onFilesLoaded]);
return {
fileInputRef,
onLoadFiles,
downloadAllFiles,
handleHiddenFileInput,
lastLoadedFiles,
} as const;
}
|