@@ -21,6 +21,7 @@ const React = require('react');
21
21
const ReactDOM = require ( "react-dom" ) ;
22
22
import PropTypes from 'prop-types' ;
23
23
const classNames = require ( 'classnames' ) ;
24
+ import dis from '../../../dispatcher' ;
24
25
const MatrixClientPeg = require ( '../../../MatrixClientPeg' ) ;
25
26
import DMRoomMap from '../../../utils/DMRoomMap' ;
26
27
const sdk = require ( '../../../index' ) ;
@@ -58,7 +59,9 @@ module.exports = React.createClass({
58
59
hover : false ,
59
60
badgeHover : false ,
60
61
menuDisplayed : false ,
62
+ roomName : this . props . room . name ,
61
63
notifState : RoomNotifs . getRoomNotifsState ( this . props . room . roomId ) ,
64
+ notificationCount : this . props . room . getUnreadNotificationCount ( ) ,
62
65
selected : this . props . room . roomId === RoomViewStore . getRoomId ( ) ,
63
66
} ) ;
64
67
} ,
@@ -81,6 +84,20 @@ module.exports = React.createClass({
81
84
}
82
85
} ,
83
86
87
+ onRoomTimeline : function ( ev , room ) {
88
+ if ( room !== this . props . room ) return ;
89
+ this . setState ( {
90
+ notificationCount : this . props . room . getUnreadNotificationCount ( ) ,
91
+ } ) ;
92
+ } ,
93
+
94
+ onRoomName : function ( room ) {
95
+ if ( room !== this . props . room ) return ;
96
+ this . setState ( {
97
+ roomName : this . props . room . name ,
98
+ } ) ;
99
+ } ,
100
+
84
101
onAccountData : function ( accountDataEvent ) {
85
102
if ( accountDataEvent . getType ( ) == 'm.push_rules' ) {
86
103
this . setState ( {
@@ -89,6 +106,21 @@ module.exports = React.createClass({
89
106
}
90
107
} ,
91
108
109
+ onAction : function ( payload ) {
110
+ switch ( payload . action ) {
111
+ // XXX: slight hack in order to zero the notification count when a room
112
+ // is read. Ideally this state would be given to this via props (as we
113
+ // do with `unread`). This is still better than forceUpdating the entire
114
+ // RoomList when a room is read.
115
+ case 'on_room_read' :
116
+ if ( payload . roomId !== this . props . room . roomId ) break ;
117
+ this . setState ( {
118
+ notificationCount : this . props . room . getUnreadNotificationCount ( ) ,
119
+ } ) ;
120
+ break ;
121
+ }
122
+ } ,
123
+
92
124
_onActiveRoomChange : function ( ) {
93
125
this . setState ( {
94
126
selected : this . props . room . roomId === RoomViewStore . getRoomId ( ) ,
@@ -97,15 +129,37 @@ module.exports = React.createClass({
97
129
98
130
componentWillMount : function ( ) {
99
131
MatrixClientPeg . get ( ) . on ( "accountData" , this . onAccountData ) ;
132
+ MatrixClientPeg . get ( ) . on ( "Room.timeline" , this . onRoomTimeline ) ;
133
+ MatrixClientPeg . get ( ) . on ( "Room.name" , this . onRoomName ) ;
100
134
ActiveRoomObserver . addListener ( this . props . room . roomId , this . _onActiveRoomChange ) ;
135
+ this . dispatcherRef = dis . register ( this . onAction ) ;
101
136
} ,
102
137
103
138
componentWillUnmount : function ( ) {
104
139
const cli = MatrixClientPeg . get ( ) ;
105
140
if ( cli ) {
106
141
MatrixClientPeg . get ( ) . removeListener ( "accountData" , this . onAccountData ) ;
142
+ MatrixClientPeg . get ( ) . removeListener ( "Room.timeline" , this . onRoomTimeline ) ;
143
+ MatrixClientPeg . get ( ) . removeListener ( "Room.name" , this . onRoomName ) ;
107
144
}
108
145
ActiveRoomObserver . removeListener ( this . props . room . roomId , this . _onActiveRoomChange ) ;
146
+ dis . unregister ( this . dispatcherRef ) ;
147
+ } ,
148
+
149
+ // Do a simple shallow comparison of props and state to avoid unnecessary
150
+ // renders. The assumption made here is that only state and props are used
151
+ // in rendering this component and children.
152
+ //
153
+ // RoomList is frequently made to forceUpdate, so this decreases number of
154
+ // RoomTile renderings.
155
+ shouldComponentUpdate : function ( newProps , newState ) {
156
+ if ( Object . keys ( newProps ) . some ( ( k ) => newProps [ k ] !== this . props [ k ] ) ) {
157
+ return true ;
158
+ }
159
+ if ( Object . keys ( newState ) . some ( ( k ) => newState [ k ] !== this . state [ k ] ) ) {
160
+ return true ;
161
+ }
162
+ return false ;
109
163
} ,
110
164
111
165
onClick : function ( ev ) {
@@ -174,7 +228,7 @@ module.exports = React.createClass({
174
228
const myUserId = MatrixClientPeg . get ( ) . credentials . userId ;
175
229
const me = this . props . room . currentState . members [ myUserId ] ;
176
230
177
- const notificationCount = this . props . room . getUnreadNotificationCount ( ) ;
231
+ const notificationCount = this . state . notificationCount ;
178
232
// var highlightCount = this.props.room.getUnreadNotificationCount("highlight");
179
233
180
234
const notifBadges = notificationCount > 0 && this . _shouldShowNotifBadge ( ) ;
@@ -202,9 +256,7 @@ module.exports = React.createClass({
202
256
'mx_RoomTile_badgeButton' : this . state . badgeHover || this . state . menuDisplayed ,
203
257
} ) ;
204
258
205
- // XXX: We should never display raw room IDs, but sometimes the
206
- // room name js sdk gives is undefined (cannot repro this -- k)
207
- let name = this . props . room . name || this . props . room . roomId ;
259
+ let name = this . state . roomName ;
208
260
name = name . replace ( ":" , ":\u200b" ) ; // add a zero-width space to allow linewrapping after the colon
209
261
210
262
let badge ;
0 commit comments