fix: resolve white screen and black screen on daily notes
- Lazy-load WhiteboardView to prevent module-scope side effect (registerBuiltinCommands) from crashing the entire JS module tree - Fix Rules of Hooks violation in Editor: hooks after early return caused React to crash when currentNote transitioned from null - Fix async race condition in Editor content initialization where noteContent arrived after renderToDOM had already run with empty content - Add error handling to DailyView's getOrCreateDaily call - Add inline fallback styles to index.html for pre-JS loading state Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0d26e63c9a
commit
9dcfece5bf
3 changed files with 26 additions and 16 deletions
|
|
@ -6,8 +6,8 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Graph Notes</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<body style="background:#09090b;color:#fafafa;font-family:sans-serif;">
|
||||
<div id="root"><p style="padding:2rem;">Loading Graph Notes...</p></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useState, useEffect, useCallback, createContext, useContext } from "react";
|
||||
import { useState, useEffect, useCallback, createContext, useContext, lazy, Suspense } from "react";
|
||||
import { Routes, Route, useNavigate, useParams } from "react-router-dom";
|
||||
import { Sidebar } from "./components/Sidebar";
|
||||
import { Editor } from "./components/Editor";
|
||||
|
|
@ -14,7 +14,7 @@ import { SearchReplace } from "./components/SearchReplace";
|
|||
import { FlashcardView } from "./components/FlashcardView";
|
||||
import { CSSEditor, useCustomCssInit } from "./components/CSSEditor";
|
||||
import { TabBar } from "./components/TabBar";
|
||||
import { WhiteboardView } from "./components/WhiteboardView";
|
||||
const WhiteboardView = lazy(() => import("./components/WhiteboardView").then(m => ({ default: m.WhiteboardView })));
|
||||
import { DatabaseView } from "./components/DatabaseView";
|
||||
import { GitPanel } from "./components/GitPanel";
|
||||
import { TimelineView } from "./components/TimelineView";
|
||||
|
|
@ -385,7 +385,7 @@ export default function App() {
|
|||
<Route path="/calendar" element={<CalendarView />} />
|
||||
<Route path="/kanban" element={<KanbanView />} />
|
||||
<Route path="/flashcards" element={<FlashcardView />} />
|
||||
<Route path="/whiteboard/:name" element={<WhiteboardView />} />
|
||||
<Route path="/whiteboard/:name" element={<Suspense fallback={<div className="flex-1 flex items-center justify-center"><p className="text-[var(--text-muted)]">Loading whiteboard...</p></div>}><WhiteboardView /></Suspense>} />
|
||||
<Route path="/database" element={<DatabaseView />} />
|
||||
<Route path="/timeline" element={<TimelineView />} />
|
||||
<Route path="/analytics" element={<GraphAnalytics />} />
|
||||
|
|
@ -411,6 +411,9 @@ function DailyView() {
|
|||
getOrCreateDaily(vaultPath).then((dailyPath) => {
|
||||
refreshNotes();
|
||||
navigate(`/note/${encodeURIComponent(dailyPath)}`, { replace: true });
|
||||
}).catch((e) => {
|
||||
console.error("[GraphNotes] Failed to create daily note:", e);
|
||||
navigate("/", { replace: true });
|
||||
});
|
||||
}, [vaultPath, navigate, refreshNotes]);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ export function Editor() {
|
|||
const [writingGoal, setWritingGoal] = useState(0);
|
||||
const [goalEditing, setGoalEditing] = useState(false);
|
||||
const lastSnapshotRef = useRef(0);
|
||||
const mermaidRef = useRef<HTMLDivElement>(null);
|
||||
const [noteEncrypted, setNoteEncrypted] = useState(false);
|
||||
const [lockScreenOpen, setLockScreenOpen] = useState(false);
|
||||
const [lockError, setLockError] = useState<string | null>(null);
|
||||
|
|
@ -105,9 +106,16 @@ export function Editor() {
|
|||
}, []);
|
||||
|
||||
// ── Initialize / switch note ──
|
||||
const contentRenderedRef = useRef(false);
|
||||
useEffect(() => {
|
||||
if (currentNote !== lastNoteRef.current) {
|
||||
lastNoteRef.current = currentNote;
|
||||
contentRenderedRef.current = false;
|
||||
renderToDOM(noteContent);
|
||||
if (noteContent) contentRenderedRef.current = true;
|
||||
} else if (!contentRenderedRef.current && noteContent) {
|
||||
// Content arrived async after note switch — render it now
|
||||
contentRenderedRef.current = true;
|
||||
renderToDOM(noteContent);
|
||||
}
|
||||
}, [currentNote, noteContent, renderToDOM]);
|
||||
|
|
@ -417,15 +425,7 @@ export function Editor() {
|
|||
return () => document.removeEventListener("mousedown", handler);
|
||||
}, []);
|
||||
|
||||
if (!currentNote) {
|
||||
return (
|
||||
<div className="flex-1 flex items-center justify-center">
|
||||
<p className="text-[var(--text-muted)]">Select a note to begin editing</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const renderedMarkdown = (() => {
|
||||
const renderedMarkdown = currentNote ? (() => {
|
||||
let html = marked(noteContent, { async: false }) as string;
|
||||
html = html.replace(
|
||||
/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g,
|
||||
|
|
@ -436,10 +436,9 @@ export function Editor() {
|
|||
}
|
||||
);
|
||||
return DOMPurify.sanitize(html, { ADD_ATTR: ['data-target'] });
|
||||
})();
|
||||
})() : "";
|
||||
|
||||
// Mermaid post-processing (render in a separate effect)
|
||||
const mermaidRef = useRef<HTMLDivElement>(null);
|
||||
useEffect(() => {
|
||||
if (!isPreview || !mermaidRef.current) return;
|
||||
const mermaidBlocks = mermaidRef.current.querySelectorAll<HTMLElement>("code.language-mermaid");
|
||||
|
|
@ -641,6 +640,14 @@ export function Editor() {
|
|||
? currentNote.replace(/\.md$/, "").split("/")
|
||||
: [];
|
||||
|
||||
if (!currentNote) {
|
||||
return (
|
||||
<div className="flex-1 flex items-center justify-center">
|
||||
<p className="text-[var(--text-muted)]">Select a note to begin editing</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`flex flex-col h-full ${focusMode ? "editor-focus" : ""}`} ref={editorRef}>
|
||||
{/* ── Breadcrumbs ── */}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue