@@ -14,9 +14,19 @@ See the License for the specific language governing permissions and
14
14
limitations under the License.
15
15
*/
16
16
17
- import React , { useCallback , useContext , useEffect , useMemo , useState } from "react" ;
17
+ import React , { SyntheticEvent , useCallback , useContext , useEffect , useMemo , useState } from "react" ;
18
18
import classNames from "classnames" ;
19
- import { MenuItem , Tooltip , Separator , ToggleMenuItem , Text , Badge , Heading } from "@vector-im/compound-web" ;
19
+ import {
20
+ MenuItem ,
21
+ Tooltip ,
22
+ Separator ,
23
+ ToggleMenuItem ,
24
+ Text ,
25
+ Badge ,
26
+ Heading ,
27
+ IconButton ,
28
+ Link ,
29
+ } from "@vector-im/compound-web" ;
20
30
import { Icon as SearchIcon } from "@vector-im/compound-design-tokens/icons/search.svg" ;
21
31
import { Icon as FavouriteIcon } from "@vector-im/compound-design-tokens/icons/favourite.svg" ;
22
32
import { Icon as UserAddIcon } from "@vector-im/compound-design-tokens/icons/user-add.svg" ;
@@ -32,6 +42,7 @@ import { Icon as LockIcon } from "@vector-im/compound-design-tokens/icons/lock-s
32
42
import { Icon as LockOffIcon } from "@vector-im/compound-design-tokens/icons/lock-off.svg" ;
33
43
import { Icon as PublicIcon } from "@vector-im/compound-design-tokens/icons/public.svg" ;
34
44
import { Icon as ErrorIcon } from "@vector-im/compound-design-tokens/icons/error.svg" ;
45
+ import { Icon as ChevronDownIcon } from "@vector-im/compound-design-tokens/icons/chevron-down.svg" ;
35
46
import { EventType , JoinRule , Room , RoomStateEvent } from "matrix-js-sdk/src/matrix" ;
36
47
37
48
import MatrixClientContext from "../../../contexts/MatrixClientContext" ;
@@ -74,6 +85,10 @@ import { canInviteTo } from "../../../utils/room/canInviteTo";
74
85
import { inviteToRoom } from "../../../utils/room/inviteToRoom" ;
75
86
import { useAccountData } from "../../../hooks/useAccountData" ;
76
87
import { useRoomState } from "../../../hooks/useRoomState" ;
88
+ import { useTopic } from "../../../hooks/room/useTopic" ;
89
+ import { Linkify , topicToHtml } from "../../../HtmlUtils" ;
90
+ import { Box } from "../../utils/Box" ;
91
+ import { onRoomTopicLinkClick } from "../elements/RoomTopic" ;
77
92
78
93
interface IProps {
79
94
room : Room ;
@@ -271,6 +286,84 @@ const onRoomSettingsClick = (ev: Event): void => {
271
286
PosthogTrackers . trackInteraction ( "WebRightPanelRoomInfoSettingsButton" , ev ) ;
272
287
} ;
273
288
289
+ const RoomTopic : React . FC < Pick < IProps , "room" > > = ( { room } ) : JSX . Element | null => {
290
+ const [ expanded , setExpanded ] = useState ( false ) ;
291
+
292
+ const topic = useTopic ( room ) ;
293
+ const body = topicToHtml ( topic ?. text , topic ?. html ) ;
294
+
295
+ const onEditClick = ( e : SyntheticEvent ) : void => {
296
+ e . preventDefault ( ) ;
297
+ e . stopPropagation ( ) ;
298
+ defaultDispatcher . dispatch ( { action : "open_room_settings" } ) ;
299
+ } ;
300
+
301
+ if ( ! body ) {
302
+ return (
303
+ < Flex
304
+ as = "section"
305
+ direction = "column"
306
+ justify = "center"
307
+ gap = "var(--cpd-space-2x)"
308
+ className = "mx_RoomSummaryCard_topic"
309
+ >
310
+ < Box flex = "1" >
311
+ < Link kind = "primary" onClick = { onEditClick } >
312
+ < Text size = "sm" weight = "regular" >
313
+ { _t ( "right_panel|add_topic" ) }
314
+ </ Text >
315
+ </ Link >
316
+ </ Box >
317
+ </ Flex >
318
+ ) ;
319
+ }
320
+
321
+ const content = expanded ? < Linkify > { body } </ Linkify > : body ;
322
+ return (
323
+ < Flex
324
+ as = "section"
325
+ direction = "column"
326
+ justify = "center"
327
+ gap = "var(--cpd-space-2x)"
328
+ className = { classNames ( "mx_RoomSummaryCard_topic" , {
329
+ mx_RoomSummaryCard_topic_collapsed : ! expanded ,
330
+ } ) }
331
+ >
332
+ < Box flex = "1" className = "mx_RoomSummaryCard_topic_container" >
333
+ < Text
334
+ size = "sm"
335
+ weight = "regular"
336
+ onClick = { ( ev : React . MouseEvent ) : void => {
337
+ if ( ev . target instanceof HTMLAnchorElement ) {
338
+ onRoomTopicLinkClick ( ev ) ;
339
+ return ;
340
+ }
341
+ setExpanded ( ! expanded ) ;
342
+ } }
343
+ >
344
+ { content }
345
+ </ Text >
346
+ < IconButton
347
+ className = "mx_RoomSummaryCard_topic_chevron"
348
+ size = "24px"
349
+ onClick = { ( ) => setExpanded ( ! expanded ) }
350
+ >
351
+ < ChevronDownIcon />
352
+ </ IconButton >
353
+ </ Box >
354
+ { expanded && (
355
+ < Box flex = "1" className = "mx_RoomSummaryCard_topic_edit" >
356
+ < Link kind = "primary" onClick = { onEditClick } >
357
+ < Text size = "sm" weight = "regular" >
358
+ { _t ( "action|edit" ) }
359
+ </ Text >
360
+ </ Link >
361
+ </ Box >
362
+ ) }
363
+ </ Flex >
364
+ ) ;
365
+ } ;
366
+
274
367
const RoomSummaryCard : React . FC < IProps > = ( { room, permalinkCreator, onClose, onSearchClick } ) => {
275
368
const cli = useContext ( MatrixClientContext ) ;
276
369
@@ -382,6 +475,8 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, permalinkCreator, onClose, on
382
475
</ Badge >
383
476
) }
384
477
</ Flex >
478
+
479
+ < RoomTopic room = { room } />
385
480
</ header >
386
481
) ;
387
482
0 commit comments