@@ -1487,31 +1487,33 @@ const Reader = ({ bookPath, bookId, bookRecord, getCoverDataUrl, onBack, darkMod
14871487 return
14881488 }
14891489
1490- const highlights = ( doc . defaultView as any ) ?. CSS ?. highlights
1491- const HighlightCtor = ( doc . defaultView as any ) ?. Highlight
1492- if ( ! highlights || ! HighlightCtor ) {
1493- console . log ( '[TTS:follow] skip highlight: Custom Highlight API unavailable' , { absoluteOffset } )
1494- return
1495- }
1496-
14971490 ensureTTSHighlightStyle ( doc )
14981491 const range = createRangeFromTextOffset ( doc , absoluteOffset )
14991492 if ( ! range ) {
15001493 console . log ( '[TTS:follow] skip highlight: range not found' , { absoluteOffset } )
1494+ followTTSRange ( null , doc , absoluteOffset , allowAutoFollow )
15011495 return
15021496 }
1503- highlights . set ( TTS_HIGHLIGHT_ID , new HighlightCtor ( range ) )
1497+
1498+ const highlights = ( doc . defaultView as any ) ?. CSS ?. highlights
1499+ const HighlightCtor = ( doc . defaultView as any ) ?. Highlight
1500+ if ( highlights && HighlightCtor ) {
1501+ highlights . set ( TTS_HIGHLIGHT_ID , new HighlightCtor ( range ) )
1502+ } else {
1503+ console . log ( '[TTS:follow] Custom Highlight API unavailable, only auto-follow by progress' , { absoluteOffset } )
1504+ }
15041505 followTTSRange ( range , doc , absoluteOffset , allowAutoFollow )
15051506 }
15061507
1507- const followTTSRange = ( range : Range , doc : Document , absoluteOffset : number , allowAutoFollow : boolean ) => {
1508+ const followTTSRange = ( range : Range | null , doc : Document , absoluteOffset : number , allowAutoFollow : boolean ) => {
15081509 const loc = ( renditionRef . current as any ) ?. currentLocation ?.( )
15091510 const displayed = loc ?. start ?. displayed as { page : number ; total : number } | undefined
15101511 const currentPage = displayed ?. page ?? 1
15111512 const totalPages = Math . max ( displayed ?. total ?? ttsChapterPageTotalRef . current , 1 )
15121513 const textLength = Math . max ( ttsChapterTextLengthRef . current , 1 )
15131514 const continuousPage = absoluteOffset / textLength * totalPages + 1
15141515 const estimatedPage = Math . min ( totalPages , Math . max ( 1 , Math . floor ( continuousPage ) ) )
1516+ const progressShouldAdvance = continuousPage >= currentPage + 0.9
15151517
15161518 if ( ! allowAutoFollow ) {
15171519 console . log ( '[TTS:follow] skip next: 初始 highlight 不觸發翻頁' , { absoluteOffset, currentPage, estimatedPage, totalPages } )
@@ -1533,26 +1535,19 @@ const Reader = ({ bookPath, bookId, bookRecord, getCoverDataUrl, onBack, darkMod
15331535 return
15341536 }
15351537
1536- const rect = range . getBoundingClientRect ( )
1537- if ( rect . width === 0 && rect . height === 0 ) {
1538- console . log ( '[TTS:follow] skip next: empty rect' )
1539- return
1540- }
1541-
15421538 const viewportWidth = doc . documentElement . clientWidth || doc . defaultView ?. innerWidth || 0
15431539 const viewportHeight = doc . documentElement . clientHeight || doc . defaultView ?. innerHeight || 0
1544- if ( viewportWidth <= 0 || viewportHeight <= 0 ) {
1545- console . log ( '[TTS:follow] skip next: invalid viewport' , { viewportWidth, viewportHeight } )
1546- return
1547- }
1540+ const rect = range ?. getBoundingClientRect ( )
1541+ const hasUsableRect = ! ! rect && ! ( rect . width === 0 && rect . height === 0 ) && viewportWidth > 0 && viewportHeight > 0
15481542
1549- const rectOutside =
1543+ const rectOutside = hasUsableRect && ! ! rect && (
15501544 rect . left > viewportWidth * 0.82 ||
15511545 rect . right > viewportWidth * 1.02 ||
15521546 rect . top > viewportHeight * 0.92 ||
15531547 rect . bottom > viewportHeight * 1.08
1548+ )
15541549
1555- const shouldAdvance = rectOutside && continuousPage >= currentPage + 0.82
1550+ const shouldAdvance = progressShouldAdvance || ( rectOutside && continuousPage >= currentPage + 0.82 )
15561551
15571552 console . log ( '[TTS:follow] check' , {
15581553 displayed,
@@ -1561,9 +1556,11 @@ const Reader = ({ bookPath, bookId, bookRecord, getCoverDataUrl, onBack, darkMod
15611556 continuousPage : Number ( continuousPage . toFixed ( 2 ) ) ,
15621557 currentPage,
15631558 totalPages,
1564- rect : { left : Math . round ( rect . left ) , right : Math . round ( rect . right ) , top : Math . round ( rect . top ) , bottom : Math . round ( rect . bottom ) } ,
1559+ rect : rect ? { left : Math . round ( rect . left ) , right : Math . round ( rect . right ) , top : Math . round ( rect . top ) , bottom : Math . round ( rect . bottom ) } : null ,
15651560 viewport : { width : viewportWidth , height : viewportHeight } ,
1561+ hasUsableRect,
15661562 rectOutside,
1563+ progressShouldAdvance,
15671564 shouldAdvance,
15681565 } )
15691566
0 commit comments