support sepia and black global themes with chat outline refactor#472
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
全局主题模式仅支持 system / light / dark:sepia 和 black 仅作为 reader-local 主题存在于
data-reader-theme,data-theme-mode全局模式写入后缺少对应 CSS 规则,导致 sepia/black 主题下color-scheme和--reader-highlight等变量未生效。Chat Outline 自建面板与 Reader 共用 ReaderRailPanel 逻辑,但样式不一致:Chat 的 outline 使用自定义按钮样式(
ENTRY_LIST_BUTTON_BASE_CLASS硬编码 border、padding),Reader 的 outline 已迁移到buttonMenuItemClassName()token。Chat 面板还使用了中文固定文本 "目录" 和 "用户消息",与国际化行为不一致。Outline 活跃项高亮依赖
window.innerHeight:useArticleOutlineMinimap始终通过globalThis.window读取视口高度,当文章在自定义 scroll 容器中渲染时(如 ConversationDetailPane 的 reader viewport),活跃项跟踪会出现偏移。评论面板频繁调用 React 更新函数(syncReactUpdate)导致警告:焦点切换、评论列表更新等场景多次同步触发 React 更新,JSDOM 测试中产生
Warning: flushSync was called from inside a lifecycle method等告警。Changes
Global theme mode: add sepia and black
APP_THEME_MODES从['system', 'light', 'dark']扩展为 5 项,含sepia和black。tokens.css新增[data-theme-mode='sepia']/[data-theme-mode='black']规则,设置color-scheme: light/dark,并定义--reader-highlight。useAppThemeMode中colorScheme映射逻辑更新:sepia和light对应light,其余映射到dark。ThemePanel新增 sepia 和 black 选项。Chat Outline → shared ReaderRailPanel
ChatOutlinePanel新增import { ReaderRailPanel }和buttonMenuItemClassName。ENTRY_LIST_BUTTON_BASE_CLASS、ENTRY_MINIMAP_BUTTON_CLASS,统一使用 token 类名。TRIGGER_CLASS+TRIGGER_BARS_CLASS,样式与 Reader 侧栏对齐。buttonMenuItemClassName()+webclipper-btn--tone-muted,替代硬编码 border/background。document.body.textContent不再包含中文)。ReaderRailPanel新增menuPopoverPanelClassName(170)替换硬编码样式,padding 从tw-gap-3收窄为tw-gap-1以匹配 chat 条目密度。Outline scroll root support
useArticleOutlineMinimap新增可选参数scrollRoot?: Element。readViewportRect接受scrollRoot:当 scrollRoot 存在时使用scrollRoot.getBoundingClientRect(),否则 fallback 到window.innerHeight。syncActiveIndex依赖scrollRoot变化重新计算。ArticleReaderView透传outlineScrollRoot和readerOutlinePortalTarget。ConversationDetailPane新增readerOutlinePortalTarget状态,在 article header 中渲染 portal 目标,article outline rail 通过createPortal挂载到目标节点。readerOutlinePortalTarget存在时,reader 主体不再 inline 渲染 outline rail,避免重复。Comment panel React update batching
asyncReactUpdate函数,使用queueMicrotask将 React 更新推迟到微任务。MountOptions新增deferReactUpdates字段。mountThreadedCommentsPanel根据deferReactUpdates选择syncReactUpdate或asyncReactUpdate。ArticleCommentsSection中commentChatWith挂载时传入deferReactUpdates: true。localStorage access safety
readBrowserLocalStorageValue/writeBrowserLocalStorageValue在AppShell中抽取为专用函数,统一访问globalThis.window?.localStorage。locate.ts、ThreadedCommentsPanel.tsx、inpage-comments-panel-shadow.ts中isLocateDebugEnabled改为先取anyGlobal.window?.localStorage再.getItem。useSettingsSection中的readStoredSettingsSection/writeStoredSettingsSection同步改为globalThis.window?.localStorage。Reader toolbar sticky removal
ReaderToolbar移除tw-sticky tw-top-5类,toolbar 不再 sticky 定位。Test improvements
tests/unit/chat-outline-panel.test.ts(113 行):验证无 entries 时不渲染、rail 面板正确、hover 展开 panel、active 项样式、点击选中。inpage-comments-sidebar-toggle.test.ts:将api.open()等调用包裹在act()中,避免 React scheduler 警告。app-shell-comments-sidebar.test.ts:将selectionchange+pointerup事件包裹在act(async)中。reader-header-toolbar.test.ts:验证 black 主题写入。attachEvent/detachEventpolyfill 到 JSDOM setup。Tests
npm run compile && npm run test && npm run build确认全量通过。tests/unit/chat-outline-panel.test.ts:[data-reader-rail-wrap="chat-outline"]不存在2. 给我一个行动清单data-reader-rail-panel="chat-outline"存在tests/smoke/inpage-comments-sidebar-toggle.test.ts:api.open({ focusComposer: true }),期望api.isOpen() === trueapi.open(),期望 panel 保持打开(不关闭)selectionchange+pointerup,期望onComposerSelectionRequest被调用tests/smoke/reader-mode-regression.test.ts:tests/unit/reader-header-toolbar.test.ts:updateThemeMode收到'black'