@@ -26,6 +26,10 @@ import RoomAvatar from "../../views/avatars/RoomAvatar";
26
26
import Tooltip from "../../views/elements/Tooltip" ;
27
27
import dis from '../../../dispatcher' ;
28
28
import { Key } from "../../../Keyboard" ;
29
+ import * as RoomNotifs from '../../../RoomNotifs' ;
30
+ import { EffectiveMembership , getEffectiveMembership } from "../../../stores/room-list/membership" ;
31
+ import * as Unread from '../../../Unread' ;
32
+ import * as FormattingUtils from "../../../utils/FormattingUtils" ;
29
33
30
34
interface IProps {
31
35
room : Room ;
@@ -35,7 +39,14 @@ interface IProps {
35
39
// TODO: Incoming call?
36
40
}
37
41
38
- interface IState {
42
+ interface IBadgeState {
43
+ showBadge : boolean ; // if numUnread > 0 && !showBadge -> bold room
44
+ numUnread : number ; // used only if showBadge or showBadgeHighlight is true
45
+ showBadgeHighlight : boolean ; // make the badge red
46
+ isInvite : boolean ; // show a `!` instead of a number
47
+ }
48
+
49
+ interface IState extends IBadgeState {
39
50
hover : boolean ;
40
51
}
41
52
@@ -60,6 +71,35 @@ export default class RoomTile2 extends React.Component<IProps, IState> {
60
71
61
72
this . state = {
62
73
hover : false ,
74
+
75
+ ...this . getBadgeState ( ) ,
76
+ } ;
77
+ }
78
+
79
+ public componentWillUnmount ( ) {
80
+
81
+ }
82
+
83
+ private updateBadgeCount ( ) {
84
+ this . setState ( { ...this . getBadgeState ( ) } ) ;
85
+ }
86
+
87
+ private getBadgeState ( ) : IBadgeState {
88
+ // TODO: Make this code path faster
89
+ const highlightCount = RoomNotifs . getUnreadNotificationCount ( this . props . room , 'highlight' ) ;
90
+ const numUnread = RoomNotifs . getUnreadNotificationCount ( this . props . room ) ;
91
+ const showBadge = Unread . doesRoomHaveUnreadMessages ( this . props . room ) ;
92
+ const myMembership = getEffectiveMembership ( this . props . room . getMyMembership ( ) ) ;
93
+ const isInvite = myMembership === EffectiveMembership . Invite ;
94
+ const notifState = RoomNotifs . getRoomNotifsState ( this . props . room . roomId ) ;
95
+ const shouldShowNotifBadge = RoomNotifs . shouldShowNotifBadge ( notifState ) ;
96
+ const shouldShowHighlightBadge = RoomNotifs . shouldShowMentionBadge ( notifState ) ;
97
+
98
+ return {
99
+ showBadge : ( showBadge && shouldShowNotifBadge ) || isInvite ,
100
+ numUnread,
101
+ showBadgeHighlight : ( highlightCount > 0 && shouldShowHighlightBadge ) || isInvite ,
102
+ isInvite,
63
103
} ;
64
104
}
65
105
@@ -90,12 +130,12 @@ export default class RoomTile2 extends React.Component<IProps, IState> {
90
130
const classes = classNames ( {
91
131
'mx_RoomTile' : true ,
92
132
// 'mx_RoomTile_selected': this.state.selected,
93
- // 'mx_RoomTile_unread': this.props.unread ,
94
- // 'mx_RoomTile_unreadNotify': notifBadges ,
95
- // 'mx_RoomTile_highlight': mentionBadges ,
96
- // 'mx_RoomTile_invited': isInvite,
133
+ 'mx_RoomTile_unread' : this . state . numUnread > 0 ,
134
+ 'mx_RoomTile_unreadNotify' : this . state . showBadge ,
135
+ 'mx_RoomTile_highlight' : this . state . showBadgeHighlight ,
136
+ 'mx_RoomTile_invited' : this . state . isInvite ,
97
137
// 'mx_RoomTile_menuDisplayed': isMenuDisplayed,
98
- 'mx_RoomTile_noBadges' : true , // !badges
138
+ 'mx_RoomTile_noBadges' : ! this . state . showBadge ,
99
139
// 'mx_RoomTile_transparent': this.props.transparent,
100
140
// 'mx_RoomTile_hasSubtext': subtext && !this.props.collapsed,
101
141
} ) ;
@@ -104,15 +144,26 @@ export default class RoomTile2 extends React.Component<IProps, IState> {
104
144
'mx_RoomTile_avatar' : true ,
105
145
} ) ;
106
146
147
+
148
+ let badge ;
149
+ if ( this . state . showBadge ) {
150
+ const badgeClasses = classNames ( {
151
+ 'mx_RoomTile_badge' : true ,
152
+ 'mx_RoomTile_badgeButton' : false , // this.state.badgeHover || isMenuDisplayed
153
+ } ) ;
154
+ const formattedCount = this . state . isInvite ? `!` : FormattingUtils . formatCount ( this . state . numUnread ) ;
155
+ badge = < div className = { badgeClasses } > { formattedCount } </ div > ;
156
+ }
157
+
107
158
// TODO: the original RoomTile uses state for the room name. Do we need to?
108
159
let name = this . props . room . name ;
109
160
if ( typeof name !== 'string' ) name = '' ;
110
161
name = name . replace ( ":" , ":\u200b" ) ; // add a zero-width space to allow linewrapping after the colon
111
162
112
163
const nameClasses = classNames ( {
113
164
'mx_RoomTile_name' : true ,
114
- 'mx_RoomTile_invite' : false ,
115
- 'mx_RoomTile_badgeShown' : false ,
165
+ 'mx_RoomTile_invite' : this . state . isInvite ,
166
+ 'mx_RoomTile_badgeShown' : this . state . showBadge ,
116
167
} ) ;
117
168
118
169
let tooltip = null ;
@@ -147,6 +198,7 @@ export default class RoomTile2 extends React.Component<IProps, IState> {
147
198
{ name }
148
199
</ div >
149
200
</ div >
201
+ { badge }
150
202
</ div >
151
203
{ tooltip }
152
204
</ AccessibleButton >
0 commit comments