@@ -79,15 +79,19 @@ export default class ThreadView extends React.Component<IProps, IState> {
7979 public static contextType = RoomContext ;
8080 public context ! : React . ContextType < typeof RoomContext > ;
8181
82- private dispatcherRef : string ;
82+ private dispatcherRef : string | null = null ;
8383 private readonly layoutWatcherRef : string ;
8484 private timelinePanel = createRef < TimelinePanel > ( ) ;
8585 private card = createRef < HTMLDivElement > ( ) ;
8686
87+ // Set by setEventId in ctor.
88+ private eventId ! : string ;
89+
8790 public constructor ( props : IProps ) {
8891 super ( props ) ;
8992
90- const thread = this . props . room . getThread ( this . props . mxEvent . getId ( ) ) ;
93+ this . setEventId ( this . props . mxEvent ) ;
94+ const thread = this . props . room . getThread ( this . eventId ) ?? undefined ;
9195
9296 this . setupThreadListeners ( thread ) ;
9397 this . state = {
@@ -108,18 +112,26 @@ export default class ThreadView extends React.Component<IProps, IState> {
108112 if ( this . state . thread ) {
109113 this . postThreadUpdate ( this . state . thread ) ;
110114 }
115+
111116 this . setupThread ( this . props . mxEvent ) ;
112117 this . dispatcherRef = dis . register ( this . onAction ) ;
113118
114119 const room = MatrixClientPeg . get ( ) . getRoom ( this . props . mxEvent . getRoomId ( ) ) ;
120+
121+ if ( ! room ) {
122+ throw new Error (
123+ `Unable to find room ${ this . props . mxEvent . getRoomId ( ) } for thread ${ this . props . mxEvent . getId ( ) } ` ,
124+ ) ;
125+ }
126+
115127 room . on ( ThreadEvent . New , this . onNewThread ) ;
116128 }
117129
118130 public componentWillUnmount ( ) : void {
119131 if ( this . dispatcherRef ) dis . unregister ( this . dispatcherRef ) ;
120132 const roomId = this . props . mxEvent . getRoomId ( ) ;
121133 const room = MatrixClientPeg . get ( ) . getRoom ( roomId ) ;
122- room . removeListener ( ThreadEvent . New , this . onNewThread ) ;
134+ room ? .removeListener ( ThreadEvent . New , this . onNewThread ) ;
123135 SettingsStore . unwatchSetting ( this . layoutWatcherRef ) ;
124136
125137 const hasRoomChanged = SdkContextClass . instance . roomViewStore . getRoomId ( ) !== roomId ;
@@ -139,6 +151,7 @@ export default class ThreadView extends React.Component<IProps, IState> {
139151
140152 public componentDidUpdate ( prevProps : IProps ) : void {
141153 if ( prevProps . mxEvent !== this . props . mxEvent ) {
154+ this . setEventId ( this . props . mxEvent ) ;
142155 this . setupThread ( this . props . mxEvent ) ;
143156 }
144157
@@ -147,6 +160,14 @@ export default class ThreadView extends React.Component<IProps, IState> {
147160 }
148161 }
149162
163+ private setEventId ( event : MatrixEvent ) : void {
164+ if ( ! event . getId ( ) ) {
165+ throw new Error ( "Got thread event without id" ) ;
166+ }
167+
168+ this . eventId = event . getId ( ) ! ;
169+ }
170+
150171 private onAction = ( payload : ActionPayload ) : void => {
151172 if ( payload . phase == RightPanelPhases . ThreadView && payload . event ) {
152173 this . setupThread ( payload . event ) ;
@@ -193,10 +214,15 @@ export default class ThreadView extends React.Component<IProps, IState> {
193214 } ;
194215
195216 private setupThread = ( mxEv : MatrixEvent ) : void => {
196- let thread = this . props . room . getThread ( mxEv . getId ( ) ) ;
217+ /** presence of event Id has been ensured by {@link setEventId} */
218+ const eventId = mxEv . getId ( ) ! ;
219+
220+ let thread = this . props . room . getThread ( eventId ) ;
221+
197222 if ( ! thread ) {
198- thread = this . props . room . createThread ( mxEv . getId ( ) , mxEv , [ mxEv ] , true ) ;
223+ thread = this . props . room . createThread ( eventId , mxEv , [ mxEv ] , true ) ;
199224 }
225+
200226 this . updateThread ( thread ) ;
201227 } ;
202228
@@ -420,7 +446,7 @@ export default class ThreadView extends React.Component<IProps, IState> {
420446 PosthogTrackers . trackInteraction ( "WebThreadViewBackButton" , ev ) ;
421447 } }
422448 >
423- < Measured sensor = { this . card . current } onMeasurement = { this . onMeasurement } />
449+ { this . card . current && < Measured sensor = { this . card . current } onMeasurement = { this . onMeasurement } /> }
424450 < div className = "mx_ThreadView_timelinePanelWrapper" > { timeline } </ div >
425451
426452 { ContentMessages . sharedInstance ( ) . getCurrentUploads ( threadRelation ) . length > 0 && (
0 commit comments