@@ -69,6 +69,7 @@ export function shouldFormContinuation(
6969 prevEvent : MatrixEvent ,
7070 mxEvent : MatrixEvent ,
7171 showHiddenEvents : boolean ,
72+ threadsEnabled : boolean ,
7273 timelineRenderingType ?: TimelineRenderingType ,
7374) : boolean {
7475 if ( timelineRenderingType === TimelineRenderingType . ThreadsList ) return false ;
@@ -90,6 +91,10 @@ export function shouldFormContinuation(
9091 mxEvent . sender . name !== prevEvent . sender . name ||
9192 mxEvent . sender . getMxcAvatarUrl ( ) !== prevEvent . sender . getMxcAvatarUrl ( ) ) return false ;
9293
94+ // Thread summaries in the main timeline should break up a continuation
95+ if ( threadsEnabled && prevEvent . isThreadRoot &&
96+ timelineRenderingType !== TimelineRenderingType . Thread ) return false ;
97+
9398 // if we don't have tile for previous event then it was shown by showHiddenEvents and has no SenderProfile
9499 if ( ! haveTileForEvent ( prevEvent , showHiddenEvents ) ) return false ;
95100
@@ -241,6 +246,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
241246 private readReceiptsByUserId : Record < string , IReadReceiptForUser > = { } ;
242247
243248 private readonly showHiddenEventsInTimeline : boolean ;
249+ private readonly threadsEnabled : boolean ;
244250 private isMounted = false ;
245251
246252 private readMarkerNode = createRef < HTMLLIElement > ( ) ;
@@ -264,10 +270,11 @@ export default class MessagePanel extends React.Component<IProps, IState> {
264270 hideSender : this . shouldHideSender ( ) ,
265271 } ;
266272
267- // Cache hidden events setting on mount since Settings is expensive to
268- // query, and we check this in a hot code path. This is also cached in
269- // our RoomContext, however we still need a fallback for roomless MessagePanels.
273+ // Cache these settings on mount since Settings is expensive to query,
274+ // and we check this in a hot code path. This is also cached in our
275+ // RoomContext, however we still need a fallback for roomless MessagePanels.
270276 this . showHiddenEventsInTimeline = SettingsStore . getValue ( "showHiddenEventsInTimeline" ) ;
277+ this . threadsEnabled = SettingsStore . getValue ( "feature_thread" ) ;
271278
272279 this . showTypingNotificationsWatcherRef =
273280 SettingsStore . watchSetting ( "showTypingNotifications" , null , this . onShowTypingNotificationsChange ) ;
@@ -465,7 +472,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
465472
466473 // TODO: Implement granular (per-room) hide options
467474 public shouldShowEvent ( mxEv : MatrixEvent , forceHideEvents = false ) : boolean {
468- if ( this . props . hideThreadedMessages && SettingsStore . getValue ( "feature_thread" ) ) {
475+ if ( this . props . hideThreadedMessages && this . threadsEnabled ) {
469476 if ( mxEv . isThreadRelation ) {
470477 return false ;
471478 }
@@ -744,12 +751,16 @@ export default class MessagePanel extends React.Component<IProps, IState> {
744751 lastInSection = willWantDateSeparator ||
745752 mxEv . getSender ( ) !== nextEv . getSender ( ) ||
746753 getEventDisplayInfo ( nextEv ) . isInfoMessage ||
747- ! shouldFormContinuation ( mxEv , nextEv , this . showHiddenEvents , this . context . timelineRenderingType ) ;
754+ ! shouldFormContinuation (
755+ mxEv , nextEv , this . showHiddenEvents , this . threadsEnabled , this . context . timelineRenderingType ,
756+ ) ;
748757 }
749758
750759 // is this a continuation of the previous message?
751760 const continuation = ! wantsDateSeparator &&
752- shouldFormContinuation ( prevEvent , mxEv , this . showHiddenEvents , this . context . timelineRenderingType ) ;
761+ shouldFormContinuation (
762+ prevEvent , mxEv , this . showHiddenEvents , this . threadsEnabled , this . context . timelineRenderingType ,
763+ ) ;
753764
754765 const eventId = mxEv . getId ( ) ;
755766 const highlight = ( eventId === this . props . highlightedEventId ) ;
0 commit comments