diff --git a/res/css/views/messages/_MessageActionBar.scss b/res/css/views/messages/_MessageActionBar.scss index 3e5ab87ca9..c2f3c2ebca 100644 --- a/res/css/views/messages/_MessageActionBar.scss +++ b/res/css/views/messages/_MessageActionBar.scss @@ -89,7 +89,7 @@ limitations under the License. } .mx_MessageActionBar_replyButton::after { - mask-image: url('$(res)/img/element-icons/room/files.svg'); + mask-image: url('$(res)/img/element-icons/room/message-bar/reply.svg'); } .mx_MessageActionBar_threadButton::after { diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 4b48ec971b..1bf62d3fb1 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -676,6 +676,10 @@ $hover-select-border: 4px; } +.mx_ThreadInfo:hover { + cursor: pointer; +} + .mx_ThreadView { display: flex; diff --git a/src/components/structures/ThreadView.tsx b/src/components/structures/ThreadView.tsx index 5d07b7feaa..cac4054dfb 100644 --- a/src/components/structures/ThreadView.tsx +++ b/src/components/structures/ThreadView.tsx @@ -30,6 +30,8 @@ import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks'; import { Layout } from '../../settings/Layout'; import TimelinePanel from './TimelinePanel'; import { Thread } from '../../../../matrix-js-sdk/src/models/thread'; +import dis from "../../dispatcher/dispatcher"; +import { ActionPayload } from '../../dispatcher/payloads'; interface IProps { roomId: string; @@ -49,32 +51,61 @@ interface IState { */ @replaceableComponent("structures.ThreadView") class ThreadView extends React.Component { - state = {}; + private dispatcherRef: string; + + constructor(props: IProps) { + super(props); + this.state = {}; + } public componentDidMount(): void { - this.setupThread(); + this.setupThread(this.props.mxEvent); + this.dispatcherRef = dis.register(this.onAction); } public componentWillUnmount(): void { + this.teardownThread(); + dis.unregister(this.dispatcherRef); + } + + public componentDidUpdate(prevProps) { + if (prevProps.mxEvent !== this.props.mxEvent) { + this.teardownThread(); + this.setupThread(this.props.mxEvent); + } + } + + private onAction = (payload: ActionPayload): void => { + if (payload.phase == RightPanelPhases.ThreadView && payload.event) { + if (payload.event !== this.props.mxEvent) { + this.teardownThread(); + this.setupThread(payload.event); + } + } + }; + + setupThread = (mxEv: MatrixEvent) => { + const thread = mxEv.getThread(); + if (thread) { + thread.on("Thread.update", this.updateThread); + thread.once("Thread.ready", this.updateThread); + this.updateThread(thread); + } + }; + + teardownThread = () => { if (this.state.thread) { this.state.thread.removeListener("Thread.update", this.updateThread); this.state.thread.removeListener("Thread.ready", this.updateThread); } - } - - setupThread = () => { - const thread = this.props.mxEvent.getThread(); - if (thread) { - thread.on("Thread.update", this.updateThread); - thread.once("Thread.ready", this.updateThread); - this.updateThread(); - } }; - updateThread = () => { - this.setState({ - thread: this.props.mxEvent.getThread(), - }); + updateThread = (thread?: Thread) => { + if (thread) { + this.setState({ thread }); + } else { + this.forceUpdate(); + } }; public renderEventTile(event: MatrixEvent): JSX.Element { @@ -89,7 +120,6 @@ class ThreadView extends React.Component { } public render() { - const thread = this.props.mxEvent.getThread(); const room = MatrixClientPeg.get().getRoom(this.props.roomId); return ( { previousPhase={RightPanelPhases.RoomSummary} withoutScrollContainer={true} > - empty} - alwaysShowTimestamps={true} - layout={Layout.Group} - hideThreadedMessages={false} - /> + { this.state.thread && ( + empty} + alwaysShowTimestamps={true} + layout={Layout.Group} + hideThreadedMessages={false} + /> + ) } { return (
{ dis.dispatch({ action: Action.SetRightPanelPhase, @@ -544,7 +545,7 @@ export default class EventTile extends React.Component { { avatars } - { thread.length } { thread.length === 1 ? 'reply' : 'replies' } + { thread.length - 1 } { thread.length === 2 ? 'reply' : 'replies' }
); }