@@ -69,6 +69,7 @@ export function shouldFormContinuation(
69
69
prevEvent : MatrixEvent ,
70
70
mxEvent : MatrixEvent ,
71
71
showHiddenEvents : boolean ,
72
+ threadsEnabled : boolean ,
72
73
timelineRenderingType ?: TimelineRenderingType ,
73
74
) : boolean {
74
75
if ( timelineRenderingType === TimelineRenderingType . ThreadsList ) return false ;
@@ -90,6 +91,10 @@ export function shouldFormContinuation(
90
91
mxEvent . sender . name !== prevEvent . sender . name ||
91
92
mxEvent . sender . getMxcAvatarUrl ( ) !== prevEvent . sender . getMxcAvatarUrl ( ) ) return false ;
92
93
94
+ // Thread summaries in the main timeline should break up a continuation
95
+ if ( threadsEnabled && prevEvent . isThreadRoot &&
96
+ timelineRenderingType !== TimelineRenderingType . Thread ) return false ;
97
+
93
98
// if we don't have tile for previous event then it was shown by showHiddenEvents and has no SenderProfile
94
99
if ( ! haveTileForEvent ( prevEvent , showHiddenEvents ) ) return false ;
95
100
@@ -241,6 +246,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
241
246
private readReceiptsByUserId : Record < string , IReadReceiptForUser > = { } ;
242
247
243
248
private readonly showHiddenEventsInTimeline : boolean ;
249
+ private readonly threadsEnabled : boolean ;
244
250
private isMounted = false ;
245
251
246
252
private readMarkerNode = createRef < HTMLLIElement > ( ) ;
@@ -264,10 +270,11 @@ export default class MessagePanel extends React.Component<IProps, IState> {
264
270
hideSender : this . shouldHideSender ( ) ,
265
271
} ;
266
272
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.
270
276
this . showHiddenEventsInTimeline = SettingsStore . getValue ( "showHiddenEventsInTimeline" ) ;
277
+ this . threadsEnabled = SettingsStore . getValue ( "feature_thread" ) ;
271
278
272
279
this . showTypingNotificationsWatcherRef =
273
280
SettingsStore . watchSetting ( "showTypingNotifications" , null , this . onShowTypingNotificationsChange ) ;
@@ -465,7 +472,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
465
472
466
473
// TODO: Implement granular (per-room) hide options
467
474
public shouldShowEvent ( mxEv : MatrixEvent , forceHideEvents = false ) : boolean {
468
- if ( this . props . hideThreadedMessages && SettingsStore . getValue ( "feature_thread" ) ) {
475
+ if ( this . props . hideThreadedMessages && this . threadsEnabled ) {
469
476
if ( mxEv . isThreadRelation ) {
470
477
return false ;
471
478
}
@@ -744,12 +751,16 @@ export default class MessagePanel extends React.Component<IProps, IState> {
744
751
lastInSection = willWantDateSeparator ||
745
752
mxEv . getSender ( ) !== nextEv . getSender ( ) ||
746
753
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
+ ) ;
748
757
}
749
758
750
759
// is this a continuation of the previous message?
751
760
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
+ ) ;
753
764
754
765
const eventId = mxEv . getId ( ) ;
755
766
const highlight = ( eventId === this . props . highlightedEventId ) ;
0 commit comments