@@ -17,6 +17,7 @@ import {
1717 RTCConnection ,
1818 TlsTunnel
1919} from '../../types' ;
20+ import { UiStore } from '../../model/ui/ui-store' ;
2021
2122import {
2223 getSummaryColor ,
@@ -54,6 +55,7 @@ interface ViewEventListProps {
5455 isPaused : boolean ;
5556
5657 contextMenuBuilder : ViewEventContextMenuBuilder ;
58+ uiStore : UiStore ;
5759
5860 moveSelection : ( distance : number ) => void ;
5961 onSelected : ( event : CollectedEvent | undefined ) => void ;
@@ -879,19 +881,37 @@ export class ViewEventList extends React.Component<ViewEventListProps> {
879881 if ( ! listWindow ) return true ; // This means no rows, so we are effectively at the bottom
880882 else return ( listWindow . scrollTop + SCROLL_BOTTOM_MARGIN ) >= ( listWindow . scrollHeight - listWindow . offsetHeight ) ;
881883 }
882-
883884 private wasListAtBottom = true ;
884885 private updateScrolledState = ( ) => {
885886 requestAnimationFrame ( ( ) => { // Measure async, once the scroll has actually happened
886887 this . wasListAtBottom = this . isListAtBottom ( ) ;
888+
889+ // Only save scroll position after we've restored the initial state
890+ if ( this . hasRestoredInitialState ) {
891+ const listWindow = this . listBodyRef . current ?. parentElement ;
892+ if ( listWindow ) {
893+ this . props . uiStore . setViewScrollPosition ( listWindow . scrollTop ) ;
894+ }
895+ }
887896 } ) ;
888897 }
889898
899+ private hasRestoredInitialState = false ;
890900 componentDidMount ( ) {
891- this . updateScrolledState ( ) ;
901+ // Don't save scroll state immediately - wait until we've restored first
902+
903+ // Use a more aggressive delay to ensure DOM is fully ready
904+ setTimeout ( ( ) => {
905+ this . restoreScrollPosition ( ) ;
906+
907+ // Only start tracking scroll changes after we've restored
908+ setTimeout ( ( ) => {
909+ this . hasRestoredInitialState = true ;
910+ } , 100 ) ;
911+ } , 100 ) ;
892912 }
893913
894- componentDidUpdate ( ) {
914+ componentDidUpdate ( prevProps : ViewEventListProps ) {
895915 if ( this . listBodyRef . current ?. parentElement ?. contains ( document . activeElement ) ) {
896916 // If we previously had something here focused, and we've updated, update
897917 // the focus too, to make sure it's in the right place.
@@ -901,7 +921,29 @@ export class ViewEventList extends React.Component<ViewEventListProps> {
901921 // If we previously were scrolled to the bottom of the list, but now we're not,
902922 // scroll there again ourselves now.
903923 if ( this . wasListAtBottom && ! this . isListAtBottom ( ) ) {
904- this . listRef . current ?. scrollToItem ( this . props . events . length - 1 ) ;
924+ this . listRef . current ?. scrollToItem ( this . props . events . length - 1 ) ;
925+ } else if ( prevProps . selectedEvent !== this . props . selectedEvent && this . props . selectedEvent ) {
926+ // If the selected event changed and we have a selected event, scroll to it
927+ // This handles restoring the selected event when returning to the tab
928+ this . scrollToEvent ( this . props . selectedEvent ) ;
929+ } else if ( prevProps . filteredEvents . length !== this . props . filteredEvents . length ) {
930+ // If the filtered events changed (e.g., new events loaded), try to restore scroll position
931+ setTimeout ( ( ) => {
932+ this . restoreScrollPosition ( ) ;
933+ } , 50 ) ;
934+ }
935+ }
936+
937+ private restoreScrollPosition = ( ) => {
938+ // Only restore if we have a saved position
939+ const savedPosition = this . props . uiStore . viewScrollPosition ;
940+ if ( savedPosition > 0 ) {
941+ const listWindow = this . listBodyRef . current ?. parentElement ;
942+ if ( listWindow ) { // Only restore if we're not close to the current position (avoid unnecessary scrolling)
943+ if ( Math . abs ( listWindow . scrollTop - savedPosition ) > 10 ) {
944+ listWindow . scrollTop = savedPosition ;
945+ }
946+ }
905947 }
906948 }
907949
@@ -1005,5 +1047,12 @@ export class ViewEventList extends React.Component<ViewEventListProps> {
10051047 }
10061048
10071049 event . preventDefault ( ) ;
1050+ } // Public method to force scroll and selection restoration
1051+ public restoreViewState = ( ) => {
1052+ if ( this . props . selectedEvent ) {
1053+ this . scrollToEvent ( this . props . selectedEvent ) ;
1054+ } else {
1055+ this . restoreScrollPosition ( ) ;
1056+ }
10081057 }
10091058}
0 commit comments