MCPcopy Index your code
hub / github.com/ZenNotes/zennotes / ExternalFileApp

Function ExternalFileApp

packages/app-core/src/components/ExternalFileApp.tsx:45–314  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

43}
44
45export function ExternalFileApp(): JSX.Element {
46 const prefs = useMemo(() => loadFloatingPrefs(), [])
47 const [content, setContent] = useState<ExternalFileContent | null>(null)
48 const [dirty, setDirty] = useState(false)
49 const [mode, setMode] = useState<'edit' | 'preview'>('edit')
50 const [moving, setMoving] = useState(false)
51 const [moveError, setMoveError] = useState<string | null>(null)
52 const viewRef = useRef<EditorView | null>(null)
53 const saveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
54 // Source of truth for the body: seeded on load and updated on every
55 // edit. The editor is recreated on each edit/preview toggle, so it must
56 // re-seed from here — `content` is captured stale in setContainerRef.
57 const bodyRef = useRef<string | null>(null)
58
59 // Apply theme + font vars before paint.
60 useEffect(() => {
61 applyTheme(prefs)
62 const mql = window.matchMedia('(prefers-color-scheme: dark)')
63 if (prefs.themeMode === 'auto') {
64 const onChange = (): void => applyTheme(prefs)
65 mql.addEventListener('change', onChange)
66 return () => mql.removeEventListener('change', onChange)
67 }
68 return undefined
69 }, [prefs])
70
71 // Initial load.
72 useEffect(() => {
73 let alive = true
74 void window.zen
75 .readExternalFile()
76 .then((c) => {
77 if (!alive) return
78 bodyRef.current = c.body
79 setContent(c)
80 })
81 .catch((err) => {
82 console.error('readExternalFile failed', err)
83 })
84 return () => {
85 alive = false
86 }
87 }, [])
88
89 const persist = useCallback(async (body: string) => {
90 try {
91 await window.zen.writeExternalFile(body)
92 setDirty(false)
93 } catch (err) {
94 console.error('writeExternalFile failed', err)
95 }
96 }, [])
97
98 // Mount CodeMirror once content is loaded.
99 const setContainerRef = useCallback(
100 (el: HTMLDivElement | null) => {
101 if (!el) {
102 viewRef.current?.destroy()

Callers

nothing calls this directly

Calls 15

loadFloatingPrefsFunction · 0.90
applyThemeFunction · 0.90
headingFoldingFunction · 0.90
lineNumberExtensionFunction · 0.90
vimAwareDefaultKeymapFunction · 0.90
applyVimInsertEscapeFunction · 0.90
titleFromNameFunction · 0.85
readExternalFileMethod · 0.80
writeExternalFileMethod · 0.80
createMethod · 0.80

Tested by

no test coverage detected