Polish UI

This commit is contained in:
Germain Souquet 2021-08-23 14:44:44 +01:00
parent 393bd4871f
commit 9facb0d963
4 changed files with 67 additions and 30 deletions

View file

@ -89,7 +89,7 @@ limitations under the License.
} }
.mx_MessageActionBar_replyButton::after { .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 { .mx_MessageActionBar_threadButton::after {

View file

@ -676,6 +676,10 @@ $hover-select-border: 4px;
} }
.mx_ThreadInfo:hover {
cursor: pointer;
}
.mx_ThreadView { .mx_ThreadView {
display: flex; display: flex;

View file

@ -30,6 +30,8 @@ import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks';
import { Layout } from '../../settings/Layout'; import { Layout } from '../../settings/Layout';
import TimelinePanel from './TimelinePanel'; import TimelinePanel from './TimelinePanel';
import { Thread } from '../../../../matrix-js-sdk/src/models/thread'; import { Thread } from '../../../../matrix-js-sdk/src/models/thread';
import dis from "../../dispatcher/dispatcher";
import { ActionPayload } from '../../dispatcher/payloads';
interface IProps { interface IProps {
roomId: string; roomId: string;
@ -49,32 +51,61 @@ interface IState {
*/ */
@replaceableComponent("structures.ThreadView") @replaceableComponent("structures.ThreadView")
class ThreadView extends React.Component<IProps, IState> { class ThreadView extends React.Component<IProps, IState> {
state = {}; private dispatcherRef: string;
constructor(props: IProps) {
super(props);
this.state = {};
}
public componentDidMount(): void { public componentDidMount(): void {
this.setupThread(); this.setupThread(this.props.mxEvent);
this.dispatcherRef = dis.register(this.onAction);
} }
public componentWillUnmount(): void { 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) { if (this.state.thread) {
this.state.thread.removeListener("Thread.update", this.updateThread); this.state.thread.removeListener("Thread.update", this.updateThread);
this.state.thread.removeListener("Thread.ready", 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 = () => { updateThread = (thread?: Thread) => {
this.setState({ if (thread) {
thread: this.props.mxEvent.getThread(), this.setState({ thread });
}); } else {
this.forceUpdate();
}
}; };
public renderEventTile(event: MatrixEvent): JSX.Element { public renderEventTile(event: MatrixEvent): JSX.Element {
@ -89,7 +120,6 @@ class ThreadView extends React.Component<IProps, IState> {
} }
public render() { public render() {
const thread = this.props.mxEvent.getThread();
const room = MatrixClientPeg.get().getRoom(this.props.roomId); const room = MatrixClientPeg.get().getRoom(this.props.roomId);
return ( return (
<BaseCard <BaseCard
@ -98,10 +128,11 @@ class ThreadView extends React.Component<IProps, IState> {
previousPhase={RightPanelPhases.RoomSummary} previousPhase={RightPanelPhases.RoomSummary}
withoutScrollContainer={true} withoutScrollContainer={true}
> >
{ this.state.thread && (
<TimelinePanel <TimelinePanel
manageReadReceipts={false} manageReadReceipts={false}
manageReadMarkers={false} manageReadMarkers={false}
timelineSet={thread.timelineSet} timelineSet={this.state?.thread?.timelineSet}
showUrlPreview={false} showUrlPreview={false}
tileShape={TileShape.Notif} tileShape={TileShape.Notif}
empty={<div>empty</div>} empty={<div>empty</div>}
@ -109,10 +140,11 @@ class ThreadView extends React.Component<IProps, IState> {
layout={Layout.Group} layout={Layout.Group}
hideThreadedMessages={false} hideThreadedMessages={false}
/> />
) }
<MessageComposer <MessageComposer
room={room} room={room}
resizeNotifier={this.props.resizeNotifier} resizeNotifier={this.props.resizeNotifier}
replyToEvent={thread?.replyToEvent} replyToEvent={this.state?.thread?.replyToEvent}
showReplyPreview={false} showReplyPreview={false}
permalinkCreator={this.props.permalinkCreator} permalinkCreator={this.props.permalinkCreator}
compact={true} compact={true}

View file

@ -531,6 +531,7 @@ export default class EventTile extends React.Component<IProps, IState> {
return ( return (
<div <div
className="mx_ThreadInfo"
onClick={() => { onClick={() => {
dis.dispatch({ dis.dispatch({
action: Action.SetRightPanelPhase, action: Action.SetRightPanelPhase,
@ -544,7 +545,7 @@ export default class EventTile extends React.Component<IProps, IState> {
<span className="mx_EventListSummary_avatars"> <span className="mx_EventListSummary_avatars">
{ avatars } { avatars }
</span> </span>
{ thread.length } { thread.length === 1 ? 'reply' : 'replies' } { thread.length - 1 } { thread.length === 2 ? 'reply' : 'replies' }
</div> </div>
); );
} }