diff --git a/src/App.tsx b/src/App.tsx index 745e1810..bd20ab8d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -18,7 +18,6 @@ if (typeof window !== "undefined") { import { ErrorNotifications } from "./components/ErrorNotifications"; import { GitStatusIndicator } from "./components/GitStatusIndicator"; import { SnowEffect } from "./components/SnowEffect"; -import { SyncProgress } from "./components/SyncProgress"; import { TitleBar } from "./components/TitleBar"; import { CopilotButton } from "./components/copilot/CopilotButton"; import { BottomLeftControls } from "./components/layout/BottomLeftControls"; @@ -378,15 +377,7 @@ function AppContent({ workspacePath }: AppContentProps) { ) : currentPageId ? ( - - - Loading editor... - - - } - > + - ); diff --git a/src/components/Breadcrumb.tsx b/src/components/Breadcrumb.tsx index 6aa3c4ab..1f093dd5 100644 --- a/src/components/Breadcrumb.tsx +++ b/src/components/Breadcrumb.tsx @@ -1,6 +1,6 @@ import { Text } from "@mantine/core"; import { IconChevronRight } from "@tabler/icons-react"; -import { useCallback, useState } from "react"; +import { useCallback } from "react"; import { useTranslation } from "react-i18next"; import { useBlockStore } from "../stores/blockStore"; import { usePageStore } from "../stores/pageStore"; @@ -92,8 +92,6 @@ export function Breadcrumb({ workspaceName, onNavigateHome }: BreadcrumbProps) { const selectPage = usePageStore((state) => state.selectPage); const pagesById = usePageStore((state) => state.pagesById); - const [isLoading, setIsLoading] = useState(false); - const handleZoomToLevel = useCallback((index: number) => { const { zoomOutToIndex } = useViewStore.getState(); zoomOutToIndex(index); @@ -106,40 +104,37 @@ export function Breadcrumb({ workspaceName, onNavigateHome }: BreadcrumbProps) { const handleNavigateToPage = useCallback( async (pageIdIndex: number) => { - try { - setIsLoading(true); - const pageId = pagePathIds[pageIdIndex]; - const page = pagesById[pageId]; - - if (!pageId || !page) { - console.error( - "[Breadcrumb] Invalid page navigation: pageId or page not found", - ); - return; - } - - await selectPage(pageId); - await loadPage(pageId); + const pageId = pagePathIds[pageIdIndex]; + const page = pagesById[pageId]; + + if (!pageId || !page) { + console.error( + "[Breadcrumb] Invalid page navigation: pageId or page not found", + ); + return; + } - const parentNames: string[] = []; - const parentIds: string[] = []; + const parentNames: string[] = []; + const parentIds: string[] = []; - for (let i = 0; i < pageIdIndex; i++) { - const parentId = pagePathIds[i]; - const parentPage = pagesById[parentId]; - if (parentPage) { - parentNames.push(parentPage.title); - parentIds.push(parentId); - } + for (let i = 0; i < pageIdIndex; i++) { + const parentId = pagePathIds[i]; + const parentPage = pagesById[parentId]; + if (parentPage) { + parentNames.push(parentPage.title); + parentIds.push(parentId); } - parentIds.push(pageId); + } + parentIds.push(pageId); - openNote(pageId, page.title, parentNames, parentIds); - handleZoomOutToPage(); + selectPage(pageId); + openNote(pageId, page.title, parentNames, parentIds); + handleZoomOutToPage(); + + try { + await loadPage(pageId); } catch (error) { - console.error("[Breadcrumb] Failed to navigate to page:", error); - } finally { - setIsLoading(false); + console.error("[Breadcrumb] Failed to load page:", error); } }, [ @@ -184,12 +179,10 @@ export function Breadcrumb({ workspaceName, onNavigateHome }: BreadcrumbProps) { onClick={ isWorkspace ? onNavigateHome - : isLoading - ? undefined - : () => { - const pageIdIndex = index - 1; - handleNavigateToPage(pageIdIndex); - } + : () => { + const pageIdIndex = index - 1; + handleNavigateToPage(pageIdIndex); + } } /> @@ -223,9 +216,7 @@ export function Breadcrumb({ workspaceName, onNavigateHome }: BreadcrumbProps) { ariaLabel={displayText} ariaCurrentPage={isZoomLast} onClick={ - isZoomLast || isLoading - ? undefined - : () => handleZoomToLevel(index) + isZoomLast ? undefined : () => handleZoomToLevel(index) } /> diff --git a/src/components/LinkedReferences.tsx b/src/components/LinkedReferences.tsx index 9a629c2a..ce8b5b6e 100644 --- a/src/components/LinkedReferences.tsx +++ b/src/components/LinkedReferences.tsx @@ -1,4 +1,4 @@ -import { Accordion, Box, Loader, Stack, Text } from "@mantine/core"; +import { Accordion, Box, Stack, Text } from "@mantine/core"; import { invoke } from "@tauri-apps/api/core"; import { useEffect, useState } from "react"; import { usePageStore } from "../stores/pageStore"; @@ -23,7 +23,6 @@ interface LinkedReferencesProps { export function LinkedReferences({ pageId }: LinkedReferencesProps) { const [backlinks, setBacklinks] = useState([]); - const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const workspacePath = useWorkspaceStore((state) => state.workspacePath); const pagesById = usePageStore((state) => state.pagesById); @@ -34,7 +33,6 @@ export function LinkedReferences({ pageId }: LinkedReferencesProps) { if (!pageId || !workspacePath) return; const fetchBacklinks = async () => { - setIsLoading(true); setError(null); try { @@ -48,8 +46,6 @@ export function LinkedReferences({ pageId }: LinkedReferencesProps) { setError( err instanceof Error ? err.message : "Failed to load backlinks", ); - } finally { - setIsLoading(false); } }; @@ -91,25 +87,6 @@ export function LinkedReferences({ pageId }: LinkedReferencesProps) { ); const pageCount = backlinks.length; - if (isLoading) { - return ( - - - - - Loading linked references... - - - - ); - } - if (error) { return ( { diff --git a/src/components/SyncProgress.tsx b/src/components/SyncProgress.tsx deleted file mode 100644 index b4cbef53..00000000 --- a/src/components/SyncProgress.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { Box, Group, Progress, Text } from "@mantine/core"; -import { IconRefresh } from "@tabler/icons-react"; -import { useSyncStore } from "../stores/syncStore"; - -export function SyncProgress() { - const { isReindexing, progress, message } = useSyncStore(); - - if (!isReindexing) { - return null; - } - - return ( - - - - - {message || "Re-indexing..."} - - - {Math.round(progress)}% - - - - - - ); -} diff --git a/src/components/fileTree/PageTreeItem.tsx b/src/components/fileTree/PageTreeItem.tsx index d75f7c94..6ab65cee 100644 --- a/src/components/fileTree/PageTreeItem.tsx +++ b/src/components/fileTree/PageTreeItem.tsx @@ -131,7 +131,7 @@ export function PageTreeItem({ ], }, ], - [page.id, page.title, page.parentId, onAddChild, onEdit, onDelete, t] + [page.id, page.title, page.parentId, onAddChild, onEdit, onDelete, t], ); const handlePageClick = async (e: React.MouseEvent) => { @@ -159,23 +159,28 @@ export function PageTreeItem({ pagePathIds.push(page.id); - // Batch state updates: load data first, then switch view - const dataLoadStartTime = performance.now(); - await Promise.all([selectPage(page.id), loadPage(page.id)]); - const dataLoadTime = performance.now() - dataLoadStartTime; - - // Use startTransition for view switch to allow React to prioritize user input - const openStartTime = performance.now(); + const uiStartTime = performance.now(); + selectPage(page.id); startTransition(() => { openNote(page.id, page.title, parentNames, pagePathIds); }); - const openTime = performance.now() - openStartTime; + const uiTime = performance.now() - uiStartTime; + + const dataLoadStartTime = performance.now(); + try { + await loadPage(page.id); + } catch (error) { + console.error("[PageTreeItem] Failed to load page:", error); + } + const dataLoadTime = performance.now() - dataLoadStartTime; const totalTime = performance.now() - clickStartTime; console.log( - `[PageTreeItem:timing] === CLICK HANDLER COMPLETE: dataLoad=${dataLoadTime.toFixed( - 2 - )}ms, open=${openTime.toFixed(2)}ms, total=${totalTime.toFixed(2)}ms ===` + `[PageTreeItem:timing] === CLICK HANDLER COMPLETE: ui=${uiTime.toFixed( + 2, + )}ms, dataLoad=${dataLoadTime.toFixed(2)}ms, total=${totalTime.toFixed( + 2, + )}ms ===`, ); }; @@ -221,7 +226,7 @@ export function PageTreeItem({ const moveFocus = (direction: number) => { const buttons = Array.from( - document.querySelectorAll(".page-tree-item-button") + document.querySelectorAll(".page-tree-item-button"), ) as HTMLElement[]; const currentIndex = buttons.indexOf(document.activeElement as HTMLElement); if (currentIndex !== -1) { @@ -316,8 +321,8 @@ export function PageTreeItem({ ? isCollapsed ? "var(--opacity-disabled)" : isHovered - ? "var(--opacity-dimmed)" - : 0 + ? "var(--opacity-dimmed)" + : 0 : 0, visibility: hasChildren ? "visible" : "hidden", }} @@ -460,7 +465,7 @@ export function PageTreeItem({ id: page.id, title: page.title, parentId: page.parentId, - } + }, ); onDelete(page.id); }}