11/*
2- Copyright 2021 The Matrix.org Foundation C.I.C.
2+ Copyright 2021 - 2022 The Matrix.org Foundation C.I.C.
33
44Licensed under the Apache License, Version 2.0 (the "License");
55you may not use this file except in compliance with the License.
@@ -14,35 +14,87 @@ See the License for the specific language governing permissions and
1414limitations under the License.
1515*/
1616
17- import React , { useEffect , useState } from "react" ;
18- import { EventType } from "matrix-js-sdk/src/@types/event" ;
17+ import React , { useCallback , useContext , useEffect , useRef } from "react" ;
1918import { Room } from "matrix-js-sdk/src/models/room" ;
20- import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state " ;
21- import { MatrixEvent } from "matrix-js-sdk/src/models /event" ;
19+ import classNames from "classnames " ;
20+ import { EventType } from "matrix-js-sdk/src/@types /event" ;
2221
23- import { useTypedEventEmitter } from "../../../hooks/useEventEmitter" ;
2422import { linkifyElement } from "../../../HtmlUtils" ;
23+ import { useTopic } from "../../../hooks/room/useTopic" ;
24+ import useHover from "../../../hooks/useHover" ;
25+ import Tooltip , { Alignment } from "./Tooltip" ;
26+ import { _t } from "../../../languageHandler" ;
27+ import dis from "../../../dispatcher/dispatcher" ;
28+ import { Action } from "../../../dispatcher/actions" ;
29+ import Modal from "../../../Modal" ;
30+ import InfoDialog from "../dialogs/InfoDialog" ;
31+ import { useDispatcher } from "../../../hooks/useDispatcher" ;
32+ import MatrixClientContext from "../../../contexts/MatrixClientContext" ;
33+ import AccessibleButton from "./AccessibleButton" ;
34+ import { Linkify } from "./Linkify" ;
2535
26- interface IProps {
36+ interface IProps extends React . HTMLProps < HTMLDivElement > {
2737 room ?: Room ;
28- children ?( topic : string , ref : ( element : HTMLElement ) => void ) : JSX . Element ;
2938}
3039
31- export const getTopic = room => room ?. currentState ?. getStateEvents ( EventType . RoomTopic , "" ) ?. getContent ( ) ?. topic ;
40+ export default function RoomTopic ( {
41+ room,
42+ ...props
43+ } : IProps ) {
44+ const client = useContext ( MatrixClientContext ) ;
45+ const ref = useRef < HTMLDivElement > ( ) ;
46+ const hovered = useHover ( ref ) ;
47+
48+ const topic = useTopic ( room ) ;
49+
50+ const onClick = useCallback ( ( e : React . MouseEvent < HTMLDivElement > ) => {
51+ props . onClick ?.( e ) ;
52+ const target = e . target as HTMLElement ;
53+ if ( target . tagName . toUpperCase ( ) === "A" ) {
54+ return ;
55+ }
3256
33- const RoomTopic = ( { room, children } : IProps ) : JSX . Element => {
34- const [ topic , setTopic ] = useState ( getTopic ( room ) ) ;
35- useTypedEventEmitter ( room . currentState , RoomStateEvent . Events , ( ev : MatrixEvent ) => {
36- if ( ev . getType ( ) !== EventType . RoomTopic ) return ;
37- setTopic ( getTopic ( room ) ) ;
57+ dis . fire ( Action . ShowRoomTopic ) ;
58+ } , [ props ] ) ;
59+
60+ useDispatcher ( dis , ( payload ) => {
61+ if ( payload . action === Action . ShowRoomTopic ) {
62+ const canSetTopic = room . currentState . maySendStateEvent ( EventType . RoomTopic , client . getUserId ( ) ) ;
63+
64+ const modal = Modal . createDialog ( InfoDialog , {
65+ title : room . name ,
66+ description : < div >
67+ < Linkify as = "p" > { topic } </ Linkify >
68+ { canSetTopic && < AccessibleButton
69+ kind = "primary_outline"
70+ onClick = { ( ) => {
71+ modal . close ( ) ;
72+ dis . dispatch ( { action : "open_room_settings" } ) ;
73+ } } >
74+ { _t ( "Edit topic" ) }
75+ </ AccessibleButton > }
76+ </ div > ,
77+ hasCloseButton : true ,
78+ button : false ,
79+ } ) ;
80+ }
3881 } ) ;
82+
3983 useEffect ( ( ) => {
40- setTopic ( getTopic ( room ) ) ;
41- } , [ room ] ) ;
84+ linkifyElement ( ref . current ) ;
85+ } , [ topic ] ) ;
4286
43- const ref = e => e && linkifyElement ( e ) ;
44- if ( children ) return children ( topic , ref ) ;
45- return < span ref = { ref } > { topic } </ span > ;
46- } ;
87+ const className = classNames ( props . className , "mx_RoomTopic" ) ;
4788
48- export default RoomTopic ;
89+ return < div { ...props }
90+ ref = { ref }
91+ onClick = { onClick }
92+ dir = "auto"
93+ className = { className }
94+ >
95+ { topic }
96+ { hovered && (
97+ < Tooltip label = { _t ( "Click to read topic" ) } alignment = { Alignment . Bottom } />
98+ ) }
99+ </ div > ;
100+ }
0 commit comments