diff --git a/src/main/ipcHandlers.ts b/src/main/ipcHandlers.ts index 382bb90..c84d206 100644 --- a/src/main/ipcHandlers.ts +++ b/src/main/ipcHandlers.ts @@ -7,7 +7,7 @@ import { eventManager } from './eventManager'; import { Store } from './store'; import { MODEL_PROVIDERS } from './models/modelProvider'; -const scanFolder = async (store: Store, folderPath: string, modelManager: ModelManager) => { +const scanFolder = async (store: Store, folderPath: string, includeSubdirectories: boolean, modelManager: ModelManager) => { const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif']; const images: Image[] = store.getImages() || []; @@ -16,7 +16,7 @@ const scanFolder = async (store: Store, folderPath: string, modelManager: ModelM for (const entry of entries) { const imagePath = path.join(dir, entry.name); - if (entry.isDirectory()) { + if (entry.isDirectory() && includeSubdirectories) { await scanRecursively(imagePath); } else if (entry.isFile() && imageExtensions.includes(path.extname(entry.name).toLowerCase())) { let image = images.find((image) => image.id === imagePath); @@ -51,7 +51,7 @@ export const setupIpcHandlers = (webContents: Electron.WebContents, store: Store return store.getSettings(); }); - ipcMain.handle('add-folder', async () => { + ipcMain.handle('select-folder', async () => { const settings = store.getSettings(); if (!MODEL_PROVIDERS[settings.modelProviderConfig.name].isInitialized(settings)) { @@ -61,12 +61,22 @@ export const setupIpcHandlers = (webContents: Electron.WebContents, store: Store const result = await dialog.showOpenDialog({ properties: ['openDirectory'] }); if (!result.canceled) { const folderPath = result.filePaths[0]; - await scanFolder(store, folderPath, modelManager); - return { success: true, message: 'Folder added successfully' }; + return { success: true, path: folderPath }; } return { success: false }; }); + ipcMain.handle('add-folder', async (_event, folderPath: string, includeSubdirectories: boolean) => { + const settings = store.getSettings(); + + if (!MODEL_PROVIDERS[settings.modelProviderConfig.name].isInitialized(settings)) { + return { success: false, message: 'Model provider not initialized. Go to Settings and enter your the information for the model provider.' }; + } + + await scanFolder(store, folderPath, includeSubdirectories, modelManager); + return { success: true, message: 'Folder added successfully' }; + }); + ipcMain.handle('get-images', () => { return store.getImages(); }); diff --git a/src/preload/index.ts b/src/preload/index.ts index e1b31c8..149781d 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -9,7 +9,9 @@ const imageUpdatedListeners: Record => ipcRenderer.invoke('save-settings', settings), getSettings: (): Promise => ipcRenderer.invoke('get-settings'), - addFolder: (): Promise<{ success: boolean; message: string }> => ipcRenderer.invoke('add-folder'), + selectFolder: (): Promise<{ success: boolean; path?: string }> => ipcRenderer.invoke('select-folder'), + addFolder: (folderPath: string, includeSubdirs: boolean): Promise<{ success: boolean; message?: string }> => + ipcRenderer.invoke('add-folder', folderPath, includeSubdirs), getImages: (): Promise => ipcRenderer.invoke('get-images'), generateImageCaption: (image: Image): Promise => ipcRenderer.invoke('generate-image-caption', image), addImageUpdatedListener: (callback: (event: Electron.IpcRendererEvent, image: Image) => void): string => { diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index e77bc12..13e61a2 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -11,7 +11,7 @@ const App = () => { useEffect(() => { Modal.setAppElement('#app'); - navigate('/'); + navigate('/home'); }, []); return ( diff --git a/src/renderer/src/components/AddFolderModal.tsx b/src/renderer/src/components/AddFolderModal.tsx new file mode 100644 index 0000000..fc315eb --- /dev/null +++ b/src/renderer/src/components/AddFolderModal.tsx @@ -0,0 +1,92 @@ +import React, { useState } from 'react'; +import Modal from 'react-modal'; +import { HiFolderAdd } from 'react-icons/hi'; + +type Props = { + isOpen: boolean; + onRequestClose: () => void; + onSubmit: (folderPath: string, includeSubdirs: boolean) => void; +}; + +const AddFolderModal = ({ isOpen, onRequestClose, onSubmit }: Props) => { + const [folderPath, setFolderPath] = useState(''); + const [includeSubdirectories, setIncludeSubdirectories] = useState(false); + + const handleSelectFolder = async () => { + const result = await window.api.selectFolder(); + if (result.success && result.path) { + setFolderPath(result.path); + } + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + onSubmit(folderPath, includeSubdirectories); + setFolderPath(''); + setIncludeSubdirectories(false); + }; + + return ( + +

Add Folder

+
+
+ +
+ + +
+
+
+ setIncludeSubdirectories(e.target.checked)} + className="h-4 w-4 text-teal-600 focus:ring-teal-500 border-gray-300 rounded" + /> + +
+ +
+ + +
+
+
+ ); +}; + +export default AddFolderModal; diff --git a/src/renderer/src/components/Home.tsx b/src/renderer/src/components/Home.tsx index e1a001d..d79f656 100644 --- a/src/renderer/src/components/Home.tsx +++ b/src/renderer/src/components/Home.tsx @@ -5,6 +5,7 @@ import { Image } from '@shared/types'; import ImageDetails from './ImageDetails'; import { useSnackbar } from 'notistack'; import Pager from './Pager'; +import AddFolderModal from './AddFolderModal'; const Home = () => { const { enqueueSnackbar } = useSnackbar(); @@ -45,10 +46,12 @@ const Home = () => { // The filtering is now done in the filteredImages variable }; - const handleAddFolder = async (): Promise => { - const result = await window.api.addFolder(); + const [isAddFolderModalOpen, setIsAddFolderModalOpen] = useState(false); + + const handleAddFolder = async (folderPath: string, includeSubdirectories: boolean): Promise => { + const result = await window.api.addFolder(folderPath, includeSubdirectories); if (result.success) { - // Refresh the images after adding a new folder + setIsAddFolderModalOpen(false); const updatedImages = await window.api.getImages(); setImages(updatedImages); } else if (result.message) { @@ -91,7 +94,7 @@ const Home = () => {