1
1
/*
2
2
Copyright 2015, 2016 OpenMarket Ltd
3
- Copyright 2017 New Vector Ltd
3
+ Copyright 2017, 2018 New Vector Ltd
4
4
5
5
Licensed under the Apache License, Version 2.0 (the "License");
6
6
you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import dis from '../../../dispatcher';
25
25
import RoomViewStore from '../../../stores/RoomViewStore' ;
26
26
import SettingsStore , { SettingLevel } from "../../../settings/SettingsStore" ;
27
27
import Stickerpicker from './Stickerpicker' ;
28
+ import { makeRoomPermalink } from '../../../matrix-to' ;
28
29
29
30
const formatButtonList = [
30
31
_td ( "bold" ) ,
@@ -51,7 +52,9 @@ export default class MessageComposer extends React.Component {
51
52
this . onToggleMarkdownClicked = this . onToggleMarkdownClicked . bind ( this ) ;
52
53
this . onInputStateChanged = this . onInputStateChanged . bind ( this ) ;
53
54
this . onEvent = this . onEvent . bind ( this ) ;
55
+ this . _onRoomStateEvents = this . _onRoomStateEvents . bind ( this ) ;
54
56
this . _onRoomViewStoreUpdate = this . _onRoomViewStoreUpdate . bind ( this ) ;
57
+ this . _onTombstoneClick = this . _onTombstoneClick . bind ( this ) ;
55
58
56
59
this . state = {
57
60
inputState : {
@@ -61,6 +64,7 @@ export default class MessageComposer extends React.Component {
61
64
} ,
62
65
showFormatting : SettingsStore . getValue ( 'MessageComposer.showFormatting' ) ,
63
66
isQuoting : Boolean ( RoomViewStore . getQuotingEvent ( ) ) ,
67
+ tombstone : this . _getRoomTombstone ( ) ,
64
68
} ;
65
69
}
66
70
@@ -70,6 +74,7 @@ export default class MessageComposer extends React.Component {
70
74
// marked as encrypted.
71
75
// XXX: fragile as all hell - fixme somehow, perhaps with a dedicated Room.encryption event or something.
72
76
MatrixClientPeg . get ( ) . on ( "event" , this . onEvent ) ;
77
+ MatrixClientPeg . get ( ) . on ( "RoomState.events" , this . _onRoomStateEvents ) ;
73
78
this . _roomStoreToken = RoomViewStore . addListener ( this . _onRoomViewStoreUpdate ) ;
74
79
this . _waitForOwnMember ( ) ;
75
80
}
@@ -93,6 +98,7 @@ export default class MessageComposer extends React.Component {
93
98
componentWillUnmount ( ) {
94
99
if ( MatrixClientPeg . get ( ) ) {
95
100
MatrixClientPeg . get ( ) . removeListener ( "event" , this . onEvent ) ;
101
+ MatrixClientPeg . get ( ) . removeListener ( "RoomState.events" , this . _onRoomStateEvents ) ;
96
102
}
97
103
if ( this . _roomStoreToken ) {
98
104
this . _roomStoreToken . remove ( ) ;
@@ -105,6 +111,18 @@ export default class MessageComposer extends React.Component {
105
111
this . forceUpdate ( ) ;
106
112
}
107
113
114
+ _onRoomStateEvents ( ev , state ) {
115
+ if ( ev . getRoomId ( ) !== this . props . room . roomId ) return ;
116
+
117
+ if ( ev . getType ( ) === 'm.room.tombstone' ) {
118
+ this . setState ( { tombstone : this . _getRoomTombstone ( ) } ) ;
119
+ }
120
+ }
121
+
122
+ _getRoomTombstone ( ) {
123
+ return this . props . room . currentState . getStateEvents ( 'm.room.tombstone' , '' ) ;
124
+ }
125
+
108
126
_onRoomViewStoreUpdate ( ) {
109
127
const isQuoting = Boolean ( RoomViewStore . getQuotingEvent ( ) ) ;
110
128
if ( this . state . isQuoting === isQuoting ) return ;
@@ -224,6 +242,17 @@ export default class MessageComposer extends React.Component {
224
242
this . messageComposerInput . enableRichtext ( ! this . state . inputState . isRichTextEnabled ) ;
225
243
}
226
244
245
+ _onTombstoneClick ( ev ) {
246
+ ev . preventDefault ( ) ;
247
+
248
+ const replacementRoomId = this . state . tombstone . getContent ( ) [ 'replacement_room' ] ;
249
+ dis . dispatch ( {
250
+ action : 'view_room' ,
251
+ highlighted : true ,
252
+ room_id : replacementRoomId ,
253
+ } ) ;
254
+ }
255
+
227
256
render ( ) {
228
257
const uploadInputStyle = { display : 'none' } ;
229
258
const MemberAvatar = sdk . getComponent ( 'avatars.MemberAvatar' ) ;
@@ -280,7 +309,7 @@ export default class MessageComposer extends React.Component {
280
309
</ div > ;
281
310
}
282
311
283
- const canSendMessages = this . props . room . currentState . maySendMessage (
312
+ const canSendMessages = ! this . state . tombstone && this . props . room . currentState . maySendMessage (
284
313
MatrixClientPeg . get ( ) . credentials . userId ) ;
285
314
286
315
if ( canSendMessages ) {
@@ -340,6 +369,24 @@ export default class MessageComposer extends React.Component {
340
369
callButton ,
341
370
videoCallButton ,
342
371
) ;
372
+ } else if ( this . state . tombstone ) {
373
+ const replacementRoomId = this . state . tombstone . getContent ( ) [ 'replacement_room' ] ;
374
+
375
+ const AccessibleButton = sdk . getComponent ( 'elements.AccessibleButton' ) ;
376
+ controls . push ( < div className = "mx_MessageComposer_replaced_wrapper" >
377
+ < div className = "mx_MessageComposer_replaced_valign" >
378
+ < img className = "mx_MessageComposer_roomReplaced_icon" src = "img/room_replaced.svg" />
379
+ < span className = "mx_MessageComposer_roomReplaced_header" >
380
+ { _t ( "This room has been replaced and is no longer active." ) }
381
+ </ span > < br />
382
+ < a href = { makeRoomPermalink ( replacementRoomId ) }
383
+ className = "mx_MessageComposer_roomReplaced_link"
384
+ onClick = { this . _onTombstoneClick }
385
+ >
386
+ { _t ( "The conversation continues here." ) }
387
+ </ a >
388
+ </ div >
389
+ </ div > ) ;
343
390
} else {
344
391
controls . push (
345
392
< div key = "controls_error" className = "mx_MessageComposer_noperm_error" >
0 commit comments