feat: enhance keyboard shortcut management and improve app responsiveness

- Updated the development script to include a build step before launching the app.
- Refactored the registration of quick ask and autocomplete functionalities to be asynchronous, ensuring proper initialization.
- Introduced IPC channels for getting and setting keyboard shortcuts, allowing users to customize their experience.
- Enhanced the platform module to support better interaction with the Electron API for clipboard operations.
- Improved the user interface for managing keyboard shortcuts in the settings dialog, providing a more intuitive experience.
This commit is contained in:
DESKTOP-RTLN3BA\$punk 2026-04-07 00:43:40 -07:00
parent e920923fa4
commit 49441233e7
30 changed files with 923 additions and 191 deletions

View file

@ -26,6 +26,7 @@ import { Progress } from "@/components/ui/progress";
import { Spinner } from "@/components/ui/spinner";
import { Switch } from "@/components/ui/switch";
import { documentsApiService } from "@/lib/apis/documents-api.service";
import { useElectronAPI } from "@/hooks/use-platform";
import {
trackDocumentUploadFailure,
trackDocumentUploadStarted,
@ -151,10 +152,11 @@ export function DocumentUploadTab({
};
}, []);
const electronAPI = useElectronAPI();
const [selectedFolder, setSelectedFolder] = useState<SelectedFolder | null>(null);
const [watchFolder, setWatchFolder] = useState(true);
const [folderSubmitting, setFolderSubmitting] = useState(false);
const isElectron = typeof window !== "undefined" && !!window.electronAPI?.browseFiles;
const isElectron = !!electronAPI?.browseFiles;
const acceptedFileTypes = useMemo(() => {
const etlService = process.env.NEXT_PUBLIC_ETL_SERVICE;
@ -216,33 +218,31 @@ export function DocumentUploadTab({
}, []);
const handleBrowseFiles = useCallback(async () => {
const api = window.electronAPI;
if (!api?.browseFiles) return;
if (!electronAPI?.browseFiles) return;
const paths = await api.browseFiles();
const paths = await electronAPI.browseFiles();
if (!paths || paths.length === 0) return;
setSelectedFolder(null);
const fileDataList = await api.readLocalFiles(paths);
const fileDataList = await electronAPI.readLocalFiles(paths);
const newFiles: FileWithId[] = fileDataList.map((fd) => ({
id: crypto.randomUUID?.() ?? `file-${Date.now()}-${Math.random().toString(36)}`,
file: new File([fd.data], fd.name, { type: fd.mimeType }),
}));
setFiles((prev) => [...prev, ...newFiles]);
}, []);
}, [electronAPI]);
const handleBrowseFolder = useCallback(async () => {
const api = window.electronAPI;
if (!api?.selectFolder) return;
if (!electronAPI?.selectFolder) return;
const folderPath = await api.selectFolder();
const folderPath = await electronAPI.selectFolder();
if (!folderPath) return;
const folderName = folderPath.split("/").pop() || folderPath.split("\\").pop() || folderPath;
setFiles([]);
setSelectedFolder({ path: folderPath, name: folderName });
setWatchFolder(true);
}, []);
}, [electronAPI]);
const handleFolderChange = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
@ -287,9 +287,7 @@ export function DocumentUploadTab({
);
const handleFolderSubmit = useCallback(async () => {
if (!selectedFolder) return;
const api = window.electronAPI;
if (!api) return;
if (!selectedFolder || !electronAPI) return;
setFolderSubmitting(true);
try {
@ -304,7 +302,7 @@ export function DocumentUploadTab({
const rootFolderId = (result as { root_folder_id?: number })?.root_folder_id ?? null;
if (watchFolder) {
await api.addWatchedFolder({
await electronAPI.addWatchedFolder({
path: selectedFolder.path,
name: selectedFolder.name,
excludePatterns: [
@ -332,7 +330,7 @@ export function DocumentUploadTab({
} finally {
setFolderSubmitting(false);
}
}, [selectedFolder, watchFolder, searchSpaceId, shouldSummarize, onSuccess]);
}, [selectedFolder, watchFolder, searchSpaceId, shouldSummarize, onSuccess, electronAPI]);
const handleUpload = async () => {
setUploadProgress(0);