@@ -189,8 +189,10 @@ export const SessionReview = (props: SessionReviewProps) => {
189189 const [ opened , setOpened ] = createSignal < SessionReviewFocus | null > ( null )
190190
191191 const open = ( ) => props . open ?? store . open
192+ const files = createMemo ( ( ) => props . diffs . map ( ( d ) => d . file ) )
193+ const diffs = createMemo ( ( ) => new Map ( props . diffs . map ( ( d ) => [ d . file , d ] as const ) ) )
192194 const diffStyle = ( ) => props . diffStyle ?? ( props . split ? "split" : "unified" )
193- const hasDiffs = ( ) => props . diffs . length > 0
195+ const hasDiffs = ( ) => files ( ) . length > 0
194196
195197 const handleChange = ( open : string [ ] ) => {
196198 props . onOpenChange ?.( open )
@@ -199,7 +201,7 @@ export const SessionReview = (props: SessionReviewProps) => {
199201 }
200202
201203 const handleExpandOrCollapseAll = ( ) => {
202- const next = open ( ) . length > 0 ? [ ] : props . diffs . map ( ( d ) => d . file )
204+ const next = open ( ) . length > 0 ? [ ] : files ( )
203205 handleChange ( next )
204206 }
205207
@@ -322,51 +324,54 @@ export const SessionReview = (props: SessionReviewProps) => {
322324 < div data-slot = "session-review-container" class = { props . classes ?. container } >
323325 < Show when = { hasDiffs ( ) } fallback = { props . empty } >
324326 < Accordion multiple value = { open ( ) } onChange = { handleChange } >
325- < For each = { props . diffs } >
326- { ( diff ) => {
327+ < For each = { files ( ) } >
328+ { ( file ) => {
327329 let wrapper : HTMLDivElement | undefined
328330
329- const expanded = createMemo ( ( ) => open ( ) . includes ( diff . file ) )
331+ const diff = createMemo ( ( ) => diffs ( ) . get ( file ) )
332+ const item = ( ) => diff ( ) !
333+
334+ const expanded = createMemo ( ( ) => open ( ) . includes ( file ) )
330335 const [ force , setForce ] = createSignal ( false )
331336
332- const comments = createMemo ( ( ) => ( props . comments ?? [ ] ) . filter ( ( c ) => c . file === diff . file ) )
337+ const comments = createMemo ( ( ) => ( props . comments ?? [ ] ) . filter ( ( c ) => c . file === file ) )
333338 const commentedLines = createMemo ( ( ) => comments ( ) . map ( ( c ) => c . selection ) )
334339
335- const beforeText = ( ) => ( typeof diff . before === "string" ? diff . before : "" )
336- const afterText = ( ) => ( typeof diff . after === "string" ? diff . after : "" )
337- const changedLines = ( ) => diff . additions + diff . deletions
340+ const beforeText = ( ) => ( typeof item ( ) . before === "string" ? item ( ) . before : "" )
341+ const afterText = ( ) => ( typeof item ( ) . after === "string" ? item ( ) . after : "" )
342+ const changedLines = ( ) => item ( ) . additions + item ( ) . deletions
338343
339344 const tooLarge = createMemo ( ( ) => {
340345 if ( ! expanded ( ) ) return false
341346 if ( force ( ) ) return false
342- if ( isImageFile ( diff . file ) ) return false
347+ if ( isImageFile ( file ) ) return false
343348 return changedLines ( ) > MAX_DIFF_CHANGED_LINES
344349 } )
345350
346- const isAdded = ( ) => diff . status === "added" || ( beforeText ( ) . length === 0 && afterText ( ) . length > 0 )
351+ const isAdded = ( ) => item ( ) . status === "added" || ( beforeText ( ) . length === 0 && afterText ( ) . length > 0 )
347352 const isDeleted = ( ) =>
348- diff . status === "deleted" || ( afterText ( ) . length === 0 && beforeText ( ) . length > 0 )
349- const isImage = ( ) => isImageFile ( diff . file )
350- const isAudio = ( ) => isAudioFile ( diff . file )
353+ item ( ) . status === "deleted" || ( afterText ( ) . length === 0 && beforeText ( ) . length > 0 )
354+ const isImage = ( ) => isImageFile ( file )
355+ const isAudio = ( ) => isAudioFile ( file )
351356
352- const diffImageSrc = dataUrlFromValue ( diff . after ) ?? dataUrlFromValue ( diff . before )
353- const [ imageSrc , setImageSrc ] = createSignal < string | undefined > ( diffImageSrc )
357+ const diffImageSrc = createMemo ( ( ) => dataUrlFromValue ( item ( ) . after ) ?? dataUrlFromValue ( item ( ) . before ) )
358+ const [ imageSrc , setImageSrc ] = createSignal < string | undefined > ( diffImageSrc ( ) )
354359 const [ imageStatus , setImageStatus ] = createSignal < "idle" | "loading" | "error" > ( "idle" )
355360
356- const diffAudioSrc = dataUrlFromValue ( diff . after ) ?? dataUrlFromValue ( diff . before )
357- const [ audioSrc , setAudioSrc ] = createSignal < string | undefined > ( diffAudioSrc )
361+ const diffAudioSrc = createMemo ( ( ) => dataUrlFromValue ( item ( ) . after ) ?? dataUrlFromValue ( item ( ) . before ) )
362+ const [ audioSrc , setAudioSrc ] = createSignal < string | undefined > ( diffAudioSrc ( ) )
358363 const [ audioStatus , setAudioStatus ] = createSignal < "idle" | "loading" | "error" > ( "idle" )
359364 const [ audioMime , setAudioMime ] = createSignal < string | undefined > ( undefined )
360365
361366 const selectedLines = createMemo ( ( ) => {
362367 const current = selection ( )
363- if ( ! current || current . file !== diff . file ) return null
368+ if ( ! current || current . file !== file ) return null
364369 return current . range
365370 } )
366371
367372 const draftRange = createMemo ( ( ) => {
368373 const current = commenting ( )
369- if ( ! current || current . file !== diff . file ) return null
374+ if ( ! current || current . file !== file ) return null
370375 return current . range
371376 } )
372377
@@ -417,6 +422,21 @@ export const SessionReview = (props: SessionReviewProps) => {
417422 requestAnimationFrame ( updateAnchors )
418423 }
419424
425+ createEffect ( ( ) => {
426+ if ( ! isImage ( ) ) return
427+ const src = diffImageSrc ( )
428+ setImageSrc ( src )
429+ setImageStatus ( "idle" )
430+ } )
431+
432+ createEffect ( ( ) => {
433+ if ( ! isAudio ( ) ) return
434+ const src = diffAudioSrc ( )
435+ setAudioSrc ( src )
436+ setAudioStatus ( "idle" )
437+ setAudioMime ( undefined )
438+ } )
439+
420440 createEffect ( ( ) => {
421441 comments ( )
422442 scheduleAnchors ( )
@@ -430,7 +450,7 @@ export const SessionReview = (props: SessionReviewProps) => {
430450 } )
431451
432452 createEffect ( ( ) => {
433- if ( ! open ( ) . includes ( diff . file ) ) return
453+ if ( ! open ( ) . includes ( file ) ) return
434454 if ( ! isImage ( ) ) return
435455 if ( imageSrc ( ) ) return
436456 if ( imageStatus ( ) !== "idle" ) return
@@ -440,7 +460,7 @@ export const SessionReview = (props: SessionReviewProps) => {
440460 if ( ! reader ) return
441461
442462 setImageStatus ( "loading" )
443- reader ( diff . file )
463+ reader ( file )
444464 . then ( ( result ) => {
445465 const src = dataUrl ( result )
446466 if ( ! src ) {
@@ -456,7 +476,7 @@ export const SessionReview = (props: SessionReviewProps) => {
456476 } )
457477
458478 createEffect ( ( ) => {
459- if ( ! open ( ) . includes ( diff . file ) ) return
479+ if ( ! open ( ) . includes ( file ) ) return
460480 if ( ! isAudio ( ) ) return
461481 if ( audioSrc ( ) ) return
462482 if ( audioStatus ( ) !== "idle" ) return
@@ -465,7 +485,7 @@ export const SessionReview = (props: SessionReviewProps) => {
465485 if ( ! reader ) return
466486
467487 setAudioStatus ( "loading" )
468- reader ( diff . file )
488+ reader ( file )
469489 . then ( ( result ) => {
470490 const src = dataUrl ( result )
471491 if ( ! src ) {
@@ -489,7 +509,7 @@ export const SessionReview = (props: SessionReviewProps) => {
489509 return
490510 }
491511
492- setSelection ( { file : diff . file , range } )
512+ setSelection ( { file, range } )
493513 }
494514
495515 const handleLineSelectionEnd = ( range : SelectedLineRange | null ) => {
@@ -500,8 +520,8 @@ export const SessionReview = (props: SessionReviewProps) => {
500520 return
501521 }
502522
503- setSelection ( { file : diff . file , range } )
504- setCommenting ( { file : diff . file , range } )
523+ setSelection ( { file, range } )
524+ setCommenting ( { file, range } )
505525 }
506526
507527 const openComment = ( comment : SessionReviewComment ) => {
@@ -517,22 +537,22 @@ export const SessionReview = (props: SessionReviewProps) => {
517537
518538 return (
519539 < Accordion . Item
520- value = { diff . file }
521- id = { diffId ( diff . file ) }
522- data-file = { diff . file }
540+ value = { file }
541+ id = { diffId ( file ) }
542+ data-file = { file }
523543 data-slot = "session-review-accordion-item"
524- data-selected = { props . focusedFile === diff . file ? "" : undefined }
544+ data-selected = { props . focusedFile === file ? "" : undefined }
525545 >
526546 < StickyAccordionHeader >
527547 < Accordion . Trigger >
528548 < div data-slot = "session-review-trigger-content" >
529549 < div data-slot = "session-review-file-info" >
530- < FileIcon node = { { path : diff . file , type : "file" } } />
550+ < FileIcon node = { { path : file , type : "file" } } />
531551 < div data-slot = "session-review-file-name-container" >
532- < Show when = { diff . file . includes ( "/" ) } >
533- < span data-slot = "session-review-directory" > { `\u202A${ getDirectory ( diff . file ) } \u202C` } </ span >
552+ < Show when = { file . includes ( "/" ) } >
553+ < span data-slot = "session-review-directory" > { `\u202A${ getDirectory ( file ) } \u202C` } </ span >
534554 </ Show >
535- < span data-slot = "session-review-filename" > { getFilename ( diff . file ) } </ span >
555+ < span data-slot = "session-review-filename" > { getFilename ( file ) } </ span >
536556 < Show when = { props . onViewFile } >
537557 < Tooltip value = "Open file" placement = "top" gutter = { 4 } >
538558 < button
@@ -541,7 +561,7 @@ export const SessionReview = (props: SessionReviewProps) => {
541561 aria-label = "Open file"
542562 onClick = { ( e ) => {
543563 e . stopPropagation ( )
544- props . onViewFile ?.( diff . file )
564+ props . onViewFile ?.( file )
545565 } }
546566 >
547567 < Icon name = "open-file" size = "small" />
@@ -557,7 +577,7 @@ export const SessionReview = (props: SessionReviewProps) => {
557577 < span data-slot = "session-review-change" data-type = "added" >
558578 { i18n . t ( "ui.sessionReview.change.added" ) }
559579 </ span >
560- < DiffChanges changes = { diff } />
580+ < DiffChanges changes = { item ( ) } />
561581 </ div >
562582 </ Match >
563583 < Match when = { isDeleted ( ) } >
@@ -571,7 +591,7 @@ export const SessionReview = (props: SessionReviewProps) => {
571591 </ span >
572592 </ Match >
573593 < Match when = { true } >
574- < DiffChanges changes = { diff } />
594+ < DiffChanges changes = { item ( ) } />
575595 </ Match >
576596 </ Switch >
577597 < span data-slot = "session-review-diff-chevron" >
@@ -586,15 +606,15 @@ export const SessionReview = (props: SessionReviewProps) => {
586606 data-slot = "session-review-diff-wrapper"
587607 ref = { ( el ) => {
588608 wrapper = el
589- anchors . set ( diff . file , el )
609+ anchors . set ( file , el )
590610 scheduleAnchors ( )
591611 } }
592612 >
593613 < Show when = { expanded ( ) } >
594614 < Switch >
595615 < Match when = { isImage ( ) && imageSrc ( ) } >
596616 < div data-slot = "session-review-image-container" >
597- < img data-slot = "session-review-image" src = { imageSrc ( ) } alt = { diff . file } />
617+ < img data-slot = "session-review-image" src = { imageSrc ( ) } alt = { file } />
598618 </ div >
599619 </ Match >
600620 < Match when = { isImage ( ) && isDeleted ( ) } >
@@ -634,7 +654,7 @@ export const SessionReview = (props: SessionReviewProps) => {
634654 < Match when = { ! isImage ( ) } >
635655 < Dynamic
636656 component = { diffComponent }
637- preloadedDiff = { diff . preloaded }
657+ preloadedDiff = { item ( ) . preloaded }
638658 diffStyle = { diffStyle ( ) }
639659 onRendered = { ( ) => {
640660 props . onDiffRendered ?.( )
@@ -646,12 +666,12 @@ export const SessionReview = (props: SessionReviewProps) => {
646666 selectedLines = { selectedLines ( ) }
647667 commentedLines = { commentedLines ( ) }
648668 before = { {
649- name : diff . file ! ,
650- contents : typeof diff . before === "string" ? diff . before : "" ,
669+ name : file ,
670+ contents : typeof item ( ) . before === "string" ? item ( ) . before : "" ,
651671 } }
652672 after = { {
653- name : diff . file ! ,
654- contents : typeof diff . after === "string" ? diff . after : "" ,
673+ name : file ,
674+ contents : typeof item ( ) . after === "string" ? item ( ) . after : "" ,
655675 } }
656676 />
657677 </ Match >
@@ -689,10 +709,10 @@ export const SessionReview = (props: SessionReviewProps) => {
689709 onCancel = { ( ) => setCommenting ( null ) }
690710 onSubmit = { ( comment ) => {
691711 props . onLineComment ?.( {
692- file : diff . file ,
712+ file,
693713 selection : range ( ) ,
694714 comment,
695- preview : selectionPreview ( diff , range ( ) ) ,
715+ preview : selectionPreview ( item ( ) , range ( ) ) ,
696716 } )
697717 setCommenting ( null )
698718 } }
0 commit comments