@@ -47,11 +47,14 @@ import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
47
47
import Spinner from "../views/elements/Spinner" ;
48
48
import EditorStateTransfer from '../../utils/EditorStateTransfer' ;
49
49
import ErrorDialog from '../views/dialogs/ErrorDialog' ;
50
+ import { debounce } from 'lodash' ;
50
51
51
52
const PAGINATE_SIZE = 20 ;
52
53
const INITIAL_SIZE = 20 ;
53
54
const READ_RECEIPT_INTERVAL_MS = 500 ;
54
55
56
+ const READ_MARKER_DEBOUNCE_MS = 100 ;
57
+
55
58
const DEBUG = false ;
56
59
57
60
let debuglog = function ( ...s : any [ ] ) { } ;
@@ -475,22 +478,35 @@ class TimelinePanel extends React.Component<IProps, IState> {
475
478
}
476
479
477
480
if ( this . props . manageReadMarkers ) {
478
- const rmPosition = this . getReadMarkerPosition ( ) ;
479
- // we hide the read marker when it first comes onto the screen, but if
480
- // it goes back off the top of the screen (presumably because the user
481
- // clicks on the 'jump to bottom' button), we need to re-enable it.
482
- if ( rmPosition < 0 ) {
483
- this . setState ( { readMarkerVisible : true } ) ;
484
- }
485
-
486
- // if read marker position goes between 0 and -1/1,
487
- // (and user is active), switch timeout
488
- const timeout = this . readMarkerTimeout ( rmPosition ) ;
489
- // NO-OP when timeout already has set to the given value
490
- this . readMarkerActivityTimer . changeTimeout ( timeout ) ;
481
+ this . doManageReadMarkers ( ) ;
491
482
}
492
483
} ;
493
484
485
+ /*
486
+ * Debounced function to manage read markers because we don't need to
487
+ * do this on every tiny scroll update. It also sets state which causes
488
+ * a component update, which can in turn reset the scroll position, so
489
+ * it's important we allow the browser to scroll a bit before running this
490
+ * (hence trailing edge only and debounce rather than throttle because
491
+ * we really only need to update this once the user has finished scrolling,
492
+ * not periodically while they scroll).
493
+ */
494
+ private doManageReadMarkers = debounce ( ( ) => {
495
+ const rmPosition = this . getReadMarkerPosition ( ) ;
496
+ // we hide the read marker when it first comes onto the screen, but if
497
+ // it goes back off the top of the screen (presumably because the user
498
+ // clicks on the 'jump to bottom' button), we need to re-enable it.
499
+ if ( rmPosition < 0 ) {
500
+ this . setState ( { readMarkerVisible : true } ) ;
501
+ }
502
+
503
+ // if read marker position goes between 0 and -1/1,
504
+ // (and user is active), switch timeout
505
+ const timeout = this . readMarkerTimeout ( rmPosition ) ;
506
+ // NO-OP when timeout already has set to the given value
507
+ this . readMarkerActivityTimer . changeTimeout ( timeout ) ;
508
+ } , READ_MARKER_DEBOUNCE_MS , { leading : false , trailing : true } ) ;
509
+
494
510
private onAction = ( payload : ActionPayload ) : void => {
495
511
switch ( payload . action ) {
496
512
case "ignore_state_changed" :
0 commit comments