@@ -98,6 +98,7 @@ type UrlState = {
9898 workId : string | null | undefined ;
9999 readerPath : string | null | undefined ;
100100 chunkId : string | null | undefined ;
101+ passageId : string | null | undefined ;
101102 profileUserId : string | null | undefined ;
102103 runId : string | null | undefined ;
103104 adminSection : "runs" | "users" | "analytics" | "incidents" | "logs" ;
@@ -394,6 +395,7 @@ function readUrlState(): UrlState {
394395 workId : undefined ,
395396 readerPath : undefined ,
396397 chunkId : undefined ,
398+ passageId : undefined ,
397399 profileUserId : undefined ,
398400 runId : undefined ,
399401 adminSection : "runs" ,
@@ -421,6 +423,7 @@ function readUrlState(): UrlState {
421423 workId : pathnameMatch ? decodeURIComponent ( pathnameMatch [ 1 ] ) : params . has ( "work" ) ? params . get ( "work" ) || null : undefined ,
422424 readerPath : params . has ( "reader" ) ? params . get ( "reader" ) || null : undefined ,
423425 chunkId : params . has ( "chunk" ) ? params . get ( "chunk" ) || null : undefined ,
426+ passageId : window . location . hash ? decodeURIComponent ( window . location . hash . replace ( / ^ # / , "" ) . trim ( ) ) || null : undefined ,
424427 profileUserId : profilePathMatch ? decodeURIComponent ( profilePathMatch [ 1 ] ) : params . has ( "profile" ) ? params . get ( "profile" ) || null : undefined ,
425428 runId : params . has ( "run" ) ? params . get ( "run" ) || null : undefined ,
426429 adminSection :
@@ -487,19 +490,24 @@ function writeUrlState(next: UrlState, mode: UrlWriteMode = "replace") {
487490 } else {
488491 url . searchParams . delete ( "session" ) ;
489492 }
490- if ( next . view === "book" && next . readerPath ) {
493+ if ( next . workId && next . readerPath ) {
491494 url . searchParams . set ( "reader" , next . readerPath ) ;
492495 } else {
493496 url . searchParams . delete ( "reader" ) ;
494497 }
495- if ( next . view === "book" && next . chunkId ) {
498+ if ( next . workId && next . chunkId ) {
496499 url . searchParams . set ( "chunk" , next . chunkId ) ;
497500 } else {
498501 url . searchParams . delete ( "chunk" ) ;
499502 }
500503 if ( next . view !== "book" && next . workId ) {
501504 url . searchParams . set ( "work" , next . workId ) ;
502505 }
506+ if ( next . workId && next . passageId ) {
507+ url . hash = next . passageId ;
508+ } else {
509+ url . hash = "" ;
510+ }
503511 if ( next . debugEnabled ) {
504512 url . searchParams . set ( "debug" , "true" ) ;
505513 } else {
@@ -3505,7 +3513,7 @@ export default function App() {
35053513 const [ activeReaderPath , setActiveReaderPath ] = useState < string | null | undefined > ( initialUrlState . readerPath ) ;
35063514 const [ activeChunkId , setActiveChunkId ] = useState < string | null | undefined > ( initialUrlState . chunkId ) ;
35073515 const [ pendingCitation , setPendingCitation ] = useState < Citation | null > ( null ) ;
3508- const [ activePassageId , setActivePassageId ] = useState < string | null > ( null ) ;
3516+ const [ activePassageId , setActivePassageId ] = useState < string | null > ( initialUrlState . passageId ?? null ) ;
35093517 const [ highlightedPassageExcerpt , setHighlightedPassageExcerpt ] = useState < string | null > ( null ) ;
35103518 const bookReaderFrameRef = useRef < HTMLIFrameElement | null > ( null ) ;
35113519 const lastReaderFrameHrefRef = useRef < string | null > ( null ) ;
@@ -3860,6 +3868,8 @@ export default function App() {
38603868 setActiveWorkId ( next . workId ) ;
38613869 setActiveReaderPath ( next . readerPath ) ;
38623870 setActiveChunkId ( next . chunkId ) ;
3871+ setActivePassageId ( next . passageId ?? null ) ;
3872+ setHighlightedPassageExcerpt ( null ) ;
38633873 setActiveProfileUserId ( next . profileUserId ) ;
38643874 setSelectedAdminRunId ( next . runId ) ;
38653875 setAdminSection ( next . adminSection ) ;
@@ -3887,6 +3897,7 @@ export default function App() {
38873897 workId : activeWorkId ,
38883898 readerPath : activeReaderPath ,
38893899 chunkId : activeChunkId ,
3900+ passageId : activePassageId ,
38903901 profileUserId : activeProfileUserId ,
38913902 runId : selectedAdminRunId ,
38923903 adminSection,
@@ -3895,7 +3906,7 @@ export default function App() {
38953906 exploreRandomSeed,
38963907 } , pendingUrlWriteModeRef . current ) ;
38973908 pendingUrlWriteModeRef . current = "replace" ;
3898- } , [ activeView , selectedSessionId , activeWorkId , activeReaderPath , activeChunkId , activeProfileUserId , selectedAdminRunId , adminSection , debugEnabled , exploreAppliedFilters , exploreRandomSeed ] ) ;
3909+ } , [ activeView , selectedSessionId , activeWorkId , activeReaderPath , activeChunkId , activePassageId , activeProfileUserId , selectedAdminRunId , adminSection , debugEnabled , exploreAppliedFilters , exploreRandomSeed ] ) ;
38993910
39003911 useEffect ( ( ) => {
39013912 if ( typeof window === "undefined" ) {
@@ -4319,14 +4330,12 @@ export default function App() {
43194330
43204331 const match = findPassageForCitation ( readerPassages , pendingCitation ) ;
43214332 if ( match ) {
4333+ pendingUrlWriteModeRef . current = "replace" ;
43224334 setActivePassageId ( match . passageId ) ;
43234335 setHighlightedPassageExcerpt ( match . highlight ) ;
43244336 if ( activeChunkId ) {
43254337 setActiveChunkId ( null ) ;
43264338 }
4327- const url = new URL ( window . location . href ) ;
4328- url . hash = match . passageId ;
4329- window . history . replaceState ( { } , "" , `${ url . pathname } ${ url . search } ${ url . hash } ` ) ;
43304339 }
43314340 setPendingCitation ( null ) ;
43324341 } , [ activeWork , pendingCitation , readerPassages , activeChunkId ] ) ;
@@ -4360,6 +4369,7 @@ export default function App() {
43604369 workId : context . workId ,
43614370 readerPath : normalized ,
43624371 chunkId : context . chunkId ,
4372+ passageId : activePassageId ,
43634373 profileUserId : context . profileUserId ,
43644374 runId : context . runId ,
43654375 adminSection : context . adminSection ,
@@ -4370,7 +4380,7 @@ export default function App() {
43704380
43714381 window . addEventListener ( "message" , handleReaderLocation ) ;
43724382 return ( ) => window . removeEventListener ( "message" , handleReaderLocation ) ;
4373- } , [ ] ) ;
4383+ } , [ activePassageId ] ) ;
43744384
43754385 useEffect ( ( ) => {
43764386 if ( ! activeWorkId ) {
@@ -5642,6 +5652,12 @@ export default function App() {
56425652 setRunArtifacts ( [ ] ) ;
56435653 setRecoveredActiveRunId ( null ) ;
56445654 setLoadError ( null ) ;
5655+ setActiveWorkId ( null ) ;
5656+ setActiveReaderPath ( null ) ;
5657+ setActiveChunkId ( null ) ;
5658+ setActivePassageId ( null ) ;
5659+ setHighlightedPassageExcerpt ( null ) ;
5660+ setPendingCitation ( null ) ;
56455661 setActiveView ( "assistant" ) ;
56465662 }
56475663
@@ -5656,6 +5672,8 @@ export default function App() {
56565672 setRunArtifacts ( [ ] ) ;
56575673 setRecoveredActiveRunId ( null ) ;
56585674 setLoadError ( null ) ;
5675+ setActiveReaderPath ( null ) ;
5676+ setActiveChunkId ( null ) ;
56595677 setHighlightedPassageExcerpt ( null ) ;
56605678 setActiveView ( "book" ) ;
56615679 }
@@ -5707,6 +5725,10 @@ export default function App() {
57075725 setMobileNavOpen ( false ) ;
57085726 if ( view !== "book" ) {
57095727 setActiveWorkId ( null ) ;
5728+ setActiveReaderPath ( null ) ;
5729+ setActiveChunkId ( null ) ;
5730+ setActivePassageId ( null ) ;
5731+ setHighlightedPassageExcerpt ( null ) ;
57105732 setPendingCitation ( null ) ;
57115733 }
57125734 if ( view !== "profile" ) {
@@ -5765,6 +5787,9 @@ export default function App() {
57655787 setMobileNavOpen ( false ) ;
57665788 setPendingCitation ( null ) ;
57675789 setActiveReaderPath ( null ) ;
5790+ setActiveChunkId ( null ) ;
5791+ setActivePassageId ( null ) ;
5792+ setHighlightedPassageExcerpt ( null ) ;
57685793 setActiveProfileUserId ( null ) ;
57695794 setActiveWorkId ( workId ) ;
57705795 if ( activeView === "explore" ) {
@@ -5780,6 +5805,9 @@ export default function App() {
57805805 pendingUrlWriteModeRef . current = "push" ;
57815806 setPendingCitation ( null ) ;
57825807 setActiveReaderPath ( null ) ;
5808+ setActiveChunkId ( null ) ;
5809+ setActivePassageId ( null ) ;
5810+ setHighlightedPassageExcerpt ( null ) ;
57835811 setActiveWorkId ( null ) ;
57845812 }
57855813
@@ -5797,6 +5825,8 @@ export default function App() {
57975825 setMobileNavOpen ( false ) ;
57985826 setPendingCitation ( citation ) ;
57995827 setActiveReaderPath ( null ) ;
5828+ setActivePassageId ( null ) ;
5829+ setHighlightedPassageExcerpt ( null ) ;
58005830 setActiveProfileUserId ( null ) ;
58015831 setActiveWorkId ( citation . workId ) ;
58025832 setActiveView ( "book" ) ;
@@ -5806,6 +5836,10 @@ export default function App() {
58065836 pendingUrlWriteModeRef . current = "push" ;
58075837 setMobileNavOpen ( false ) ;
58085838 setActiveWorkId ( null ) ;
5839+ setActiveReaderPath ( null ) ;
5840+ setActiveChunkId ( null ) ;
5841+ setActivePassageId ( null ) ;
5842+ setHighlightedPassageExcerpt ( null ) ;
58095843 setPendingCitation ( null ) ;
58105844 setActiveProfileUserId ( userId ?? currentUserId ?? null ) ;
58115845 setActiveView ( "profile" ) ;
@@ -5842,16 +5876,9 @@ export default function App() {
58425876 highlighted : Boolean ( highlight ) ,
58435877 } ) ;
58445878 }
5879+ pendingUrlWriteModeRef . current = replaceHistory ? "replace" : "push" ;
58455880 setActivePassageId ( passageId ) ;
58465881 setHighlightedPassageExcerpt ( highlight ) ;
5847- const url = new URL ( window . location . href ) ;
5848- url . hash = passageId ;
5849- const nextUrl = `${ url . pathname } ${ url . search } ${ url . hash } ` ;
5850- if ( replaceHistory ) {
5851- window . history . replaceState ( { } , "" , nextUrl ) ;
5852- } else {
5853- window . history . pushState ( { } , "" , nextUrl ) ;
5854- }
58555882 }
58565883
58575884 function renderAssistantSurface ( props : {
0 commit comments