From 11c8ce8ec927333bd7c6c38aba74d1c99023f465 Mon Sep 17 00:00:00 2001 From: Phil Denhoff Date: Thu, 28 Nov 2024 19:19:05 -0800 Subject: [PATCH] feat: Drag & drop to import new books --- src/components/organisms/Sidebar.tsx | 34 +++++++++++++++++++ src/lib/services/library/_internal/addBook.ts | 21 ++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/components/organisms/Sidebar.tsx b/src/components/organisms/Sidebar.tsx index 1cec315..915a99f 100644 --- a/src/components/organisms/Sidebar.tsx +++ b/src/components/organisms/Sidebar.tsx @@ -25,6 +25,8 @@ import { title as addBookFormTitle, } from "../molecules/AddBookForm"; import { SwitchLibraryForm } from "../molecules/SwitchLibraryForm"; +import { appWindow } from "@tauri-apps/api/window"; +import { addBookByDragDrop } from "@/lib/services/library/_internal/addBook"; export const Sidebar = () => { const { library, state, eventEmitter } = useLibrary(); @@ -45,6 +47,38 @@ export const Sidebar = () => { { close: closeSwitchLibraryModal, open: openSwitchLibraryModal }, ] = useDisclosure(false); + useEffect(() => { + let unlisten: (() => void) | undefined; + + const setupFileDropListener = async () => { + unlisten = await appWindow.onFileDropEvent((event) => { + if (!library) return; + + void (async () => { + if (event.payload.type === "drop") { + const metadataList = await addBookByDragDrop( + library, + event.payload.paths, + ); + const firstItem = metadataList[0]; + if (firstItem) { + setMetadata(firstItem); + openAddBookModal(); + } + } + })(); + }); + }; + + void setupFileDropListener(); + + return () => { + if (unlisten) { + unlisten(); + } + }; + }, [library, openAddBookModal]); + useEffect(() => { void (async () => { setAuthorList( diff --git a/src/lib/services/library/_internal/addBook.ts b/src/lib/services/library/_internal/addBook.ts index 1a21fb4..2654b39 100644 --- a/src/lib/services/library/_internal/addBook.ts +++ b/src/lib/services/library/_internal/addBook.ts @@ -5,6 +5,27 @@ import { EventEmitter } from "@/lib/event"; import { dialog } from "@tauri-apps/api"; import type { Library } from "./_types"; +export const addBookByDragDrop = async ( + library: Library, + paths: string[], +): Promise => { + const importableMetadata = []; + for (const path of paths) { + const importableFile = await library.checkFileImportable(path); + if (!importableFile) { + continue; + } + const metadata = await library.getImportableFileMetadata(importableFile); + if (!metadata) { + continue; + } + + importableMetadata.push(metadata); + } + + return importableMetadata; +}; + export const promptToAddBook = async ( library: Library, ): Promise => {