1919 * `ShellFallback` 首访加载态(此前懒 chunk 失败会一路抛到最外层 AppErrorBoundary ⇒
2020 * 整个导航壳被卸载、已访问页状态一起丢)。边界在 `shell/ShellFallback.tsx`。
2121 */
22- import { lazy , Suspense , useEffect , useState } from "react" ;
22+ import { lazy , Suspense , useEffect , useRef , useState } from "react" ;
2323import { listen } from "@tauri-apps/api/event" ;
2424import { invoke } from "@tauri-apps/api/core" ;
2525import { confirm } from "@tauri-apps/plugin-dialog" ;
@@ -46,6 +46,8 @@ import { ShellFallback, SlotErrorBoundary } from "./shell/ShellFallback";
4646// 两件**签名与语义逐字不变**(只搬不改,C9.19 第 1 条):文档段随代码搬走,本文件只剩装配与调用点。
4747import { PageSlot } from "./shell/PageSlot" ;
4848import { AiToast } from "./shell/aiToast" ;
49+ // 批 7 T1:`[[ts:ms]]` 深链的目标规格(**纯数据 + 纯函数**)—— 状态与 setter 仍住本文件(源码文本判据)。
50+ import { seekKeyOf , type FocusSeek } from "./shell/focusRouting" ;
4951// REQ-274(v0.19.4):全局 AI 对话面板(丙案——按需唤起 + 内容保活)
5052// 批 2 包体治理:从静态 import 改为按需 import,并在它之前加一道「首开挂载」闸门。
5153// @ai -context: 原语义(见文件末尾 dock 渲染处的注释)是「常驻挂载——开合仅切 display,
@@ -159,6 +161,10 @@ function MainShell() {
159161 const [ focusNoteId , setFocusNoteId ] = useState < number | null > ( null ) ;
160162 // v0.19.1(REQ-260):引用跳笔记 + 命中词高亮(key 递增——同笔记重复引用可重触发)
161163 const [ focusNoteSearch , setFocusNoteSearch ] = useState < { noteId : number ; search : string ; key : number } | null > ( null ) ;
164+ // 批 7 T1(R4/R9.1 的最小形态 · C9.2):`[[ts:ms]]` 深链的 **ms 载体**(`goSessions` 的第二个实参写它;`undefined` ⇒ 不 seek)。
165+ // @ai -context 为什么是 `{ms,key}` 而不是裸 number:裸值 setState 同值不触发 ⇒ 会话页已打开时再点同一时间码不会重新定位(其余 5 个粘滞字段的形态改造越权,登记批 8)。
166+ const [ focusSeekMs , setFocusSeekMs ] = useState < FocusSeek | null > ( null ) ;
167+ const focusSeekKeyRef = useRef ( 0 ) ;
162168
163169 // v0.19.1 审查 H1 修复:普通打开统一清带词态——focusNoteSearch 只写不清时,
164170 // NotesPage 合并 effect 会优先取残留的旧引用笔记,后续普通跨页跳转被重定向
@@ -175,7 +181,10 @@ function MainShell() {
175181 // 状态机、字段类型、各页消费逻辑一个字节未动(删字段 / 改路由参数是批 5 的视图层重构)。
176182 // 入口映射:⌘K 侧能独立发起的是页面命令(9 个)· 建体系向导 · 检索结果(带 ID 的笔记深链);
177183 // 其余带 ID 的深链(会话/体系/复习组/工作台/对话)仍由**页内入口**发起 —— ID 只有页内有。
178- const goSessions = ( sessionId : number ) => {
184+ const goSessions = ( sessionId : number , ms ?: number ) => {
185+ const key = seekKeyOf ( Date . now ( ) , focusSeekKeyRef . current ) ;
186+ focusSeekKeyRef . current = key ;
187+ setFocusSeekMs ( ms === undefined ? null : { ms, key } ) ;
179188 setFocusSessionId ( sessionId ) ;
180189 setPage ( "sessions" ) ;
181190 } ;
@@ -399,6 +408,9 @@ function MainShell() {
399408 onRefineTaskStarted = { ( _sessionId , taskId ) => goChatTask ( taskId ) }
400409 active = { page === "sessions" }
401410 onOpenNote = { ( id ) => openNotePlain ( id ) }
411+ // 批 7 T1(C9.2:接口在 7a 备好、行为在 7b 落地):ms 载体下传 + 消费后复位
412+ focusSeekMs = { focusSeekMs }
413+ onFocusSeekConsumed = { ( ) => setFocusSeekMs ( null ) }
402414 />
403415 </ PageSlot >
404416 < PageSlot show = { page === "notes" } mounted = { mountedPages . has ( "notes" ) } >
0 commit comments