@@ -6,8 +6,13 @@ import NotebookViewer from './components/NotebookViewer.jsx'
66import NotesPanel from './components/NotesPanel.jsx'
77import Welcome from './components/Welcome.jsx'
88import GuidedTour from './components/GuidedTour.jsx'
9- import { getCatalog , getNotebook } from './data/notebooks.js'
9+ import SettingsPanel from './components/SettingsPanel.jsx'
10+ import ChangelogModal from './components/ChangelogModal.jsx'
11+ import { SettingsProvider } from './context/SettingsContext.jsx'
12+ import useSettings from './hooks/useSettings.js'
13+ import useTheme from './hooks/useTheme.js'
1014import useNotesAndBookmarks from './hooks/useNotesAndBookmarks.js'
15+ import { getCatalog , getNotebook } from './data/notebooks.js'
1116
1217const NOTES_SENTINEL = '__notes__'
1318
@@ -37,6 +42,9 @@ const LEGACY_NOTEBOOK_IDS = {
3742 '21-opd' : '23-opd' ,
3843}
3944
45+ // 从构建时注入的 git log 数据中读取
46+ const CHANGELOG_COMMITS = typeof __CHANGELOG_COMMITS__ !== 'undefined' ? __CHANGELOG_COMMITS__ : [ ]
47+
4048function normalizeNotebookId ( id ) {
4149 return LEGACY_NOTEBOOK_IDS [ id ] || id
4250}
@@ -79,17 +87,27 @@ function getInitialNotebookId() {
7987 return hash ? normalizeNotebookId ( hash ) : null
8088}
8189
82- function App ( ) {
90+ function AppContent ( ) {
8391 const [ lang , setLang ] = useState ( ( ) => getInitialLang ( ) )
8492 const [ catalog , setCatalog ] = useState ( ( ) => getCatalog ( lang ) )
8593 const [ currentId , setCurrentId ] = useState ( ( ) => getInitialNotebookId ( ) )
8694 const [ loading ] = useState ( false )
8795 const [ sidebarOpen , setSidebarOpen ] = useState ( false )
8896 const [ tourActive , setTourActive ] = useState ( false )
8997 const [ tourStepIndex , setTourStepIndex ] = useState ( 0 )
98+ const [ settingsOpen , setSettingsOpen ] = useState ( false )
99+ const [ changelogOpen , setChangelogOpen ] = useState ( false )
90100
101+ const { settings, updateSettings } = useSettings ( )
102+ const { resolvedTheme, toggleTheme } = useTheme ( settings . theme )
91103 const nbm = useNotesAndBookmarks ( )
92104
105+ // 同步字号到 CSS 变量
106+ useEffect ( ( ) => {
107+ const sizeMap = { small : '14.5px' , default : '16.5px' , large : '18.5px' }
108+ document . documentElement . style . setProperty ( '--font-size-notebook' , sizeMap [ settings . fontSize ] || '16.5px' )
109+ } , [ settings . fontSize ] )
110+
93111 useEffect ( ( ) => {
94112 setCatalog ( getCatalog ( lang ) )
95113 document . documentElement . lang = lang === 'en' ? 'en' : 'zh-CN'
@@ -288,11 +306,11 @@ function App() {
288306 } , [ ] )
289307
290308 return (
291- < div className = "min-h-screen flex bg-slate-50/70 text-slate-800 font-sans antialiased" >
309+ < div className = "min-h-screen flex bg-[var(--bg-app)] text-[var(--text-body)] font-sans antialiased" >
292310 { /* Mobile menu button */ }
293311 < button
294312 onClick = { ( ) => setSidebarOpen ( true ) }
295- className = "md:hidden fixed top-4 left-4 z-40 p-2 rounded-lg bg-white /80 border border-slate-200/50 text-slate-600 hover:text-slate-800 shadow-sm backdrop-blur-md transition-colors select-none"
313+ className = "md:hidden fixed top-4 left-4 z-40 p-2 rounded-lg bg-[var(--bg-sidebar)] /80 border border-[var(--border-light)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] shadow-sm backdrop-blur-md transition-colors select-none"
296314 aria-label = "Toggle sidebar"
297315 >
298316 < Menu className = "w-5 h-5" />
@@ -315,6 +333,8 @@ function App() {
315333 onHome = { handleHome }
316334 onStartTour = { startTour }
317335 onOpenNotes = { handleOpenNotes }
336+ onOpenSettings = { ( ) => setSettingsOpen ( true ) }
337+ onOpenChangelog = { ( ) => setChangelogOpen ( true ) }
318338 bookmarks = { nbm . bookmarks }
319339 notes = { nbm . notes }
320340 isOpen = { sidebarOpen }
@@ -365,8 +385,30 @@ function App() {
365385 onPrev = { handleTourPrev }
366386 onClose = { stopTour }
367387 />
388+
389+ < SettingsPanel
390+ isOpen = { settingsOpen }
391+ onClose = { ( ) => setSettingsOpen ( false ) }
392+ lang = { lang }
393+ />
394+
395+ < ChangelogModal
396+ isOpen = { changelogOpen }
397+ onClose = { ( ) => setChangelogOpen ( false ) }
398+ lang = { lang }
399+ commits = { CHANGELOG_COMMITS }
400+ />
368401 </ div >
369402 )
370403}
371404
372- export default App
405+ export default function App ( ) {
406+ const { settings, updateSettings } = useSettings ( )
407+ const { resolvedTheme, toggleTheme } = useTheme ( settings . theme )
408+
409+ return (
410+ < SettingsProvider settings = { settings } updateSettings = { updateSettings } resolvedTheme = { resolvedTheme } toggleTheme = { toggleTheme } >
411+ < AppContent />
412+ </ SettingsProvider >
413+ )
414+ }
0 commit comments