mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-08-02 18:10:18 +05:30
feat(preload): add file.list, file.pickFolder, file.pickFile convenience methods
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { ChevronRight } from 'lucide-react';
|
||||
import { ChevronRight, FolderOpen } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '@/components/ui/collapsible';
|
||||
import { ScrollArea } from '@/components/ui/scroll-area';
|
||||
import { useFileStore } from '@/stores/file-store';
|
||||
@@ -6,7 +7,7 @@ import { FileTree } from './FileTree';
|
||||
import { Outline } from './Outline';
|
||||
|
||||
export function Sidebar() {
|
||||
const rootPath = useFileStore((s) => s.rootPath);
|
||||
const tree = useFileStore((s) => s.tree);
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col gap-3">
|
||||
@@ -20,9 +21,12 @@ export function Sidebar() {
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent>
|
||||
<ScrollArea className="h-[calc(100vh-240px)]">
|
||||
{!rootPath ? (
|
||||
<div className="flex flex-col items-center justify-center gap-2 py-8 text-xs text-muted-foreground">
|
||||
{!tree ? (
|
||||
<div className="flex flex-col items-center gap-2 p-4 text-xs text-muted-foreground">
|
||||
<span>No folder opened</span>
|
||||
<Button size="sm" variant="outline" onClick={() => useFileStore.getState().openFolderDialog()}>
|
||||
<FolderOpen className="mr-1" /> Open Folder
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<FileTree />
|
||||
|
||||
@@ -66,6 +66,10 @@ export const ipc = {
|
||||
safeCall('file', 'write', path, content),
|
||||
list: (dir: string): Promise<IpcResult<FileEntry[] | ChannelMissing>> =>
|
||||
safeCall('file', 'list', dir),
|
||||
pickFolder: (): Promise<IpcResult<string | null | ChannelMissing>> =>
|
||||
safeCall('file', 'pickFolder'),
|
||||
pickFile: (): Promise<IpcResult<string | null | ChannelMissing>> =>
|
||||
safeCall('file', 'pickFile'),
|
||||
onChange: (cb: (path: string) => void): (() => void) => {
|
||||
if (typeof window === 'undefined' || !window.electronAPI?.file?.onChange) {
|
||||
return () => {};
|
||||
|
||||
@@ -39,6 +39,9 @@ interface FileState {
|
||||
markTabClean: (id: string) => void;
|
||||
markTabDirty: (id: string) => void;
|
||||
reorderTabs: (fromIndex: number, toIndex: number) => void;
|
||||
openFolderDialog: () => Promise<void>;
|
||||
openFileDialog: () => Promise<void>;
|
||||
saveActiveBuffer: () => Promise<boolean>;
|
||||
}
|
||||
|
||||
function entryToNode(entry: FileEntry): FileNode {
|
||||
@@ -191,5 +194,32 @@ export const useFileStore = create<FileState>()(
|
||||
tabs.splice(toIndex, 0, moved);
|
||||
});
|
||||
},
|
||||
|
||||
openFolderDialog: async () => {
|
||||
const result = await ipc.file.pickFolder();
|
||||
if (!result.ok || result.data === null) return;
|
||||
await useFileStore.getState().openFolder(result.data);
|
||||
},
|
||||
|
||||
openFileDialog: async () => {
|
||||
const result = await ipc.file.pickFile();
|
||||
if (!result.ok || result.data === null) return;
|
||||
await useFileStore.getState().openFile(result.data);
|
||||
},
|
||||
|
||||
saveActiveBuffer: async () => {
|
||||
const { activeTabId } = useFileStore.getState();
|
||||
if (!activeTabId) return false;
|
||||
|
||||
const buffer = useEditorStore.getState().buffers.get(activeTabId);
|
||||
if (!buffer) return false;
|
||||
|
||||
const writeResult = await ipc.file.write(activeTabId, buffer.content);
|
||||
if (!writeResult.ok) return false;
|
||||
|
||||
useEditorStore.getState().markSaved(activeTabId);
|
||||
useFileStore.getState().markTabClean(activeTabId);
|
||||
return true;
|
||||
},
|
||||
}))
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user