@@ -127,6 +127,8 @@ interface IProps {
127127 // callback which is called when the panel is scrolled.
128128 onScroll ?( event : Event ) : void ;
129129
130+ onEventScrolledIntoView ?( eventId ?: string ) : void ;
131+
130132 // callback which is called when the read-up-to mark is updated.
131133 onReadMarkerUpdated ?( ) : void ;
132134
@@ -1128,6 +1130,40 @@ class TimelinePanel extends React.Component<IProps, IState> {
11281130 return this . loadTimeline ( initialEvent , pixelOffset , offsetBase , props . eventScrollIntoView ) ;
11291131 }
11301132
1133+ private scrollIntoView ( eventId ?: string , pixelOffset ?: number , offsetBase ?: number ) : void {
1134+ const doScroll = ( ) => {
1135+ if ( eventId ) {
1136+ debuglog ( "TimelinePanel scrolling to eventId " + eventId +
1137+ " at position " + ( offsetBase * 100 ) + "% + " + pixelOffset ) ;
1138+ this . messagePanel . current . scrollToEvent (
1139+ eventId ,
1140+ pixelOffset ,
1141+ offsetBase ,
1142+ ) ;
1143+ } else {
1144+ debuglog ( "TimelinePanel scrolling to bottom" ) ;
1145+ this . messagePanel . current . scrollToBottom ( ) ;
1146+ }
1147+ } ;
1148+
1149+ debuglog ( "TimelinePanel scheduling scroll to event" ) ;
1150+ this . props . onEventScrolledIntoView ?.( eventId ) ;
1151+ // Ensure the correct scroll position pre render, if the messages have already been loaded to DOM,
1152+ // to avoid it jumping around
1153+ doScroll ( ) ;
1154+
1155+ // Ensure the correct scroll position post render for correct behaviour.
1156+ //
1157+ // requestAnimationFrame runs our code immediately after the DOM update but before the next repaint.
1158+ //
1159+ // If the messages have just been loaded for the first time, this ensures we'll repeat setting the
1160+ // correct scroll position after React has re-rendered the TimelinePanel and MessagePanel and
1161+ // updated the DOM.
1162+ window . requestAnimationFrame ( ( ) => {
1163+ doScroll ( ) ;
1164+ } ) ;
1165+ }
1166+
11311167 /**
11321168 * (re)-load the event timeline, and initialise the scroll state, centered
11331169 * around the given event.
@@ -1180,37 +1216,8 @@ class TimelinePanel extends React.Component<IProps, IState> {
11801216 return ;
11811217 }
11821218
1183- const doScroll = ( ) => {
1184- if ( eventId ) {
1185- debuglog ( "TimelinePanel scrolling to eventId " + eventId +
1186- " at position " + ( offsetBase * 100 ) + "% + " + pixelOffset ) ;
1187- this . messagePanel . current . scrollToEvent (
1188- eventId ,
1189- pixelOffset ,
1190- offsetBase ,
1191- ) ;
1192- } else {
1193- debuglog ( "TimelinePanel scrolling to bottom" ) ;
1194- this . messagePanel . current . scrollToBottom ( ) ;
1195- }
1196- } ;
1197-
11981219 if ( scrollIntoView ) {
1199- debuglog ( "TimelinePanel scheduling scroll to event" ) ;
1200- // Ensure the correct scroll position pre render, if the messages have already been loaded to DOM, to
1201- // avoid it jumping around
1202- doScroll ( ) ;
1203-
1204- // Ensure the correct scroll position post render for correct behaviour.
1205- //
1206- // requestAnimationFrame runs our code immediately after the DOM update but before the next repaint.
1207- //
1208- // If the messages have just been loaded for the first time, this ensures we'll repeat setting the
1209- // correct scroll position after React has re-rendered the TimelinePanel and MessagePanel and updated
1210- // the DOM.
1211- window . requestAnimationFrame ( doScroll ) ;
1212- } else {
1213- debuglog ( "TimelinePanel ignoring scroll, as requested" ) ;
1220+ this . scrollIntoView ( eventId , pixelOffset , offsetBase ) ;
12141221 }
12151222
12161223 if ( this . props . sendReadReceiptOnLoad ) {
0 commit comments