web based infinite canvas
at main 135 lines 4.2 kB view raw
1import { invoke } from "@tauri-apps/api/core"; 2import { open, save } from "@tauri-apps/plugin-dialog"; 3import { readTextFile, writeTextFile } from "@tauri-apps/plugin-fs"; 4import { load } from "@tauri-apps/plugin-store"; 5import type { DesktopFileOps, DirectoryEntry, FileHandle } from "inkfinite-core"; 6 7export type { DesktopFileOps }; 8 9const STORE_NAME = "inkfinite-desktop.json"; 10const RECENT_FILES_KEY = "recentFiles"; 11const WORKSPACE_DIR_KEY = "workspaceDir"; 12const MAX_RECENT_FILES = 10; 13 14type FileEntry = { path: string; name: string; is_dir: boolean }; 15 16/** 17 * Create desktop file operations using Tauri APIs 18 */ 19export function createDesktopFileOps(): DesktopFileOps { 20 let storePromise: Promise<Awaited<ReturnType<typeof load>>> | null = null; 21 22 async function getStore() { 23 if (!storePromise) { 24 storePromise = load(STORE_NAME); 25 } 26 return storePromise; 27 } 28 29 async function showOpenDialog(): Promise<string | null> { 30 const result = await open({ 31 multiple: false, 32 directory: false, 33 filters: [{ name: "Inkfinite Files", extensions: ["inkfinite.json", "json"] }], 34 }); 35 36 return result; 37 } 38 39 async function showSaveDialog(defaultName?: string): Promise<string | null> { 40 const result = await save({ 41 defaultPath: defaultName || "Untitled.inkfinite.json", 42 filters: [{ name: "Inkfinite Files", extensions: ["inkfinite.json"] }], 43 }); 44 45 return result; 46 } 47 48 async function readFile(path: string): Promise<string> { 49 return readTextFile(path); 50 } 51 52 async function writeFile(path: string, content: string): Promise<void> { 53 await writeTextFile(path, content); 54 } 55 56 async function getRecentFiles(): Promise<FileHandle[]> { 57 const store = await getStore(); 58 const recent = (await store.get<FileHandle[]>(RECENT_FILES_KEY)) || []; 59 return recent; 60 } 61 62 async function addRecentFile(handle: FileHandle): Promise<void> { 63 const store = await getStore(); 64 const recent = (await store.get<FileHandle[]>(RECENT_FILES_KEY)) || []; 65 const filtered = recent.filter((f) => f.path !== handle.path); 66 const updated = [handle, ...filtered].slice(0, MAX_RECENT_FILES); 67 await store.set(RECENT_FILES_KEY, updated); 68 await store.save(); 69 } 70 71 async function removeRecentFile(path: string): Promise<void> { 72 const store = await getStore(); 73 const recent = (await store.get<FileHandle[]>(RECENT_FILES_KEY)) || []; 74 const filtered = recent.filter((f) => f.path !== path); 75 await store.set(RECENT_FILES_KEY, filtered); 76 await store.save(); 77 } 78 79 async function clearRecentFiles(): Promise<void> { 80 const store = await getStore(); 81 await store.set(RECENT_FILES_KEY, []); 82 await store.save(); 83 } 84 85 async function getWorkspaceDir(): Promise<string | null> { 86 const store = await getStore(); 87 const workspace = (await store.get<string | null>(WORKSPACE_DIR_KEY)) || null; 88 return workspace; 89 } 90 91 async function setWorkspaceDir(path: string | null): Promise<void> { 92 const store = await getStore(); 93 await store.set(WORKSPACE_DIR_KEY, path); 94 await store.save(); 95 } 96 97 async function pickWorkspaceDir(): Promise<string | null> { 98 const result = await invoke<string | null>("pick_workspace_directory"); 99 if (result) { 100 await setWorkspaceDir(result); 101 } 102 return result; 103 } 104 105 async function readDirectory(directory: string, pattern?: string): Promise<DirectoryEntry[]> { 106 const entries = await invoke<FileEntry[]>("read_directory", { directory, pattern: pattern || "*.inkfinite.json" }); 107 108 return entries.map((e) => ({ path: e.path, name: e.name, isDir: e.is_dir })); 109 } 110 111 async function renameFile(oldPath: string, newPath: string): Promise<void> { 112 await invoke("rename_file", { oldPath, newPath }); 113 } 114 115 async function deleteFile(path: string): Promise<void> { 116 await invoke("delete_file", { filePath: path }); 117 } 118 119 return { 120 showOpenDialog, 121 showSaveDialog, 122 readFile, 123 writeFile, 124 getRecentFiles, 125 addRecentFile, 126 removeRecentFile, 127 clearRecentFiles, 128 getWorkspaceDir, 129 setWorkspaceDir, 130 pickWorkspaceDir, 131 readDirectory, 132 renameFile, 133 deleteFile, 134 }; 135}