@@ -19,6 +19,7 @@ import React, { useContext, useEffect, useRef, useState } from "react";
19
19
import { EventTimelineSet , Room , Thread } from "matrix-js-sdk/src/matrix" ;
20
20
import { IconButton , Tooltip } from "@vector-im/compound-web" ;
21
21
import { logger } from "matrix-js-sdk/src/logger" ;
22
+ import { Icon as ThreadsIcon } from "@vector-im/compound-design-tokens/icons/threads.svg" ;
22
23
23
24
import { Icon as MarkAllThreadsReadIcon } from "../../../res/img/element-icons/check-all.svg" ;
24
25
import BaseCard from "../views/right_panel/BaseCard" ;
@@ -37,6 +38,7 @@ import { ButtonEvent } from "../views/elements/AccessibleButton";
37
38
import Spinner from "../views/elements/Spinner" ;
38
39
import Heading from "../views/typography/Heading" ;
39
40
import { clearRoomNotification } from "../../utils/notifications" ;
41
+ import EmptyState from "../views/right_panel/EmptyState" ;
40
42
41
43
interface IProps {
42
44
roomId : string ;
@@ -73,8 +75,7 @@ export const ThreadPanelHeaderFilterOptionItem: React.FC<
73
75
export const ThreadPanelHeader : React . FC < {
74
76
filterOption : ThreadFilterType ;
75
77
setFilterOption : ( filterOption : ThreadFilterType ) => void ;
76
- empty : boolean ;
77
- } > = ( { filterOption, setFilterOption, empty } ) => {
78
+ } > = ( { filterOption, setFilterOption } ) => {
78
79
const mxClient = useMatrixClientContext ( ) ;
79
80
const roomContext = useRoomContext ( ) ;
80
81
const [ menuDisplayed , button , openMenu , closeMenu ] = useContextMenu < HTMLElement > ( ) ;
@@ -140,86 +141,24 @@ export const ThreadPanelHeader: React.FC<{
140
141
< Heading size = "4" className = "mx_BaseCard_header_title_heading" >
141
142
{ _t ( "common|threads" ) }
142
143
</ Heading >
143
- { ! empty && (
144
- < >
145
- < Tooltip label = { _t ( "threads|mark_all_read" ) } >
146
- < IconButton
147
- onClick = { onMarkAllThreadsReadClick }
148
- aria-label = { _t ( "threads|mark_all_read" ) }
149
- size = "24px"
150
- >
151
- < MarkAllThreadsReadIcon />
152
- </ IconButton >
153
- </ Tooltip >
154
- < div className = "mx_ThreadPanel_vertical_separator" />
155
- < ContextMenuButton
156
- className = "mx_ThreadPanel_dropdown"
157
- ref = { button }
158
- isExpanded = { menuDisplayed }
159
- onClick = { ( ev : ButtonEvent ) => {
160
- openMenu ( ) ;
161
- PosthogTrackers . trackInteraction ( "WebRightPanelThreadPanelFilterDropdown" , ev ) ;
162
- } }
163
- >
164
- { `${ _t ( "threads|show_thread_filter" ) } ${ value ?. label } ` }
165
- </ ContextMenuButton >
166
- { contextMenu }
167
- </ >
168
- ) }
169
- </ div >
170
- ) ;
171
- } ;
172
-
173
- interface EmptyThreadIProps {
174
- hasThreads : boolean ;
175
- filterOption : ThreadFilterType ;
176
- showAllThreadsCallback : ( ) => void ;
177
- }
178
-
179
- const EmptyThread : React . FC < EmptyThreadIProps > = ( { hasThreads, filterOption, showAllThreadsCallback } ) => {
180
- let body : JSX . Element ;
181
- if ( hasThreads ) {
182
- body = (
183
- < >
184
- < p >
185
- { _t ( "threads|empty_has_threads_tip" , {
186
- replyInThread : _t ( "action|reply_in_thread" ) ,
187
- } ) }
188
- </ p >
189
- < p >
190
- { /* Always display that paragraph to prevent layout shift when hiding the button */ }
191
- { filterOption === ThreadFilterType . My ? (
192
- < button onClick = { showAllThreadsCallback } > { _t ( "threads|show_all_threads" ) } </ button >
193
- ) : (
194
- < > </ >
195
- ) }
196
- </ p >
197
- </ >
198
- ) ;
199
- } else {
200
- body = (
201
- < >
202
- < p > { _t ( "threads|empty_explainer" ) } </ p >
203
- < p className = "mx_ThreadPanel_empty_tip" >
204
- { _t (
205
- "threads|empty_tip" ,
206
- {
207
- replyInThread : _t ( "action|reply_in_thread" ) ,
208
- } ,
209
- {
210
- b : ( sub ) => < b > { sub } </ b > ,
211
- } ,
212
- ) }
213
- </ p >
214
- </ >
215
- ) ;
216
- }
217
-
218
- return (
219
- < div className = "mx_ThreadPanel_empty" >
220
- < div className = "mx_ThreadPanel_largeIcon" />
221
- < h2 > { _t ( "threads|empty_heading" ) } </ h2 >
222
- { body }
144
+ < Tooltip label = { _t ( "threads|mark_all_read" ) } >
145
+ < IconButton onClick = { onMarkAllThreadsReadClick } aria-label = { _t ( "threads|mark_all_read" ) } size = "24px" >
146
+ < MarkAllThreadsReadIcon />
147
+ </ IconButton >
148
+ </ Tooltip >
149
+ < div className = "mx_ThreadPanel_vertical_separator" />
150
+ < ContextMenuButton
151
+ className = "mx_ThreadPanel_dropdown"
152
+ ref = { button }
153
+ isExpanded = { menuDisplayed }
154
+ onClick = { ( ev : ButtonEvent ) => {
155
+ openMenu ( ) ;
156
+ PosthogTrackers . trackInteraction ( "WebRightPanelThreadPanelFilterDropdown" , ev ) ;
157
+ } }
158
+ >
159
+ { `${ _t ( "threads|show_thread_filter" ) } ${ value ?. label } ` }
160
+ </ ContextMenuButton >
161
+ { contextMenu }
223
162
</ div >
224
163
) ;
225
164
} ;
@@ -268,11 +207,7 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
268
207
< BaseCard
269
208
hideHeaderButtons
270
209
header = {
271
- < ThreadPanelHeader
272
- filterOption = { filterOption }
273
- setFilterOption = { setFilterOption }
274
- empty = { ! hasThreads }
275
- />
210
+ hasThreads && < ThreadPanelHeader filterOption = { filterOption } setFilterOption = { setFilterOption } />
276
211
}
277
212
id = "thread-panel"
278
213
className = "mx_ThreadPanel"
@@ -295,10 +230,12 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
295
230
timelineSet = { timelineSet }
296
231
showUrlPreview = { false } // No URL previews at the threads list level
297
232
empty = {
298
- < EmptyThread
299
- hasThreads = { hasThreads }
300
- filterOption = { filterOption }
301
- showAllThreadsCallback = { ( ) => setFilterOption ( ThreadFilterType . All ) }
233
+ < EmptyState
234
+ Icon = { ThreadsIcon }
235
+ title = { _t ( "threads|empty_title" ) }
236
+ description = { _t ( "threads|empty_description" , {
237
+ replyInThread : _t ( "action|reply_in_thread" ) ,
238
+ } ) }
302
239
/>
303
240
}
304
241
alwaysShowTimestamps = { true }
0 commit comments