mirror of
https://github.com/element-hq/element-web
synced 2024-11-23 09:46:09 +03:00
Polish UI
This commit is contained in:
parent
393bd4871f
commit
9facb0d963
4 changed files with 67 additions and 30 deletions
|
@ -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 {
|
||||
|
|
|
@ -676,6 +676,10 @@ $hover-select-border: 4px;
|
|||
}
|
||||
|
||||
|
||||
.mx_ThreadInfo:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_ThreadView {
|
||||
|
||||
display: flex;
|
||||
|
|
|
@ -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<IProps, IState> {
|
||||
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<IProps, IState> {
|
|||
}
|
||||
|
||||
public render() {
|
||||
const thread = this.props.mxEvent.getThread();
|
||||
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
||||
return (
|
||||
<BaseCard
|
||||
|
@ -98,21 +128,23 @@ class ThreadView extends React.Component<IProps, IState> {
|
|||
previousPhase={RightPanelPhases.RoomSummary}
|
||||
withoutScrollContainer={true}
|
||||
>
|
||||
<TimelinePanel
|
||||
manageReadReceipts={false}
|
||||
manageReadMarkers={false}
|
||||
timelineSet={thread.timelineSet}
|
||||
showUrlPreview={false}
|
||||
tileShape={TileShape.Notif}
|
||||
empty={<div>empty</div>}
|
||||
alwaysShowTimestamps={true}
|
||||
layout={Layout.Group}
|
||||
hideThreadedMessages={false}
|
||||
/>
|
||||
{ this.state.thread && (
|
||||
<TimelinePanel
|
||||
manageReadReceipts={false}
|
||||
manageReadMarkers={false}
|
||||
timelineSet={this.state?.thread?.timelineSet}
|
||||
showUrlPreview={false}
|
||||
tileShape={TileShape.Notif}
|
||||
empty={<div>empty</div>}
|
||||
alwaysShowTimestamps={true}
|
||||
layout={Layout.Group}
|
||||
hideThreadedMessages={false}
|
||||
/>
|
||||
) }
|
||||
<MessageComposer
|
||||
room={room}
|
||||
resizeNotifier={this.props.resizeNotifier}
|
||||
replyToEvent={thread?.replyToEvent}
|
||||
replyToEvent={this.state?.thread?.replyToEvent}
|
||||
showReplyPreview={false}
|
||||
permalinkCreator={this.props.permalinkCreator}
|
||||
compact={true}
|
||||
|
|
|
@ -531,6 +531,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
|
||||
return (
|
||||
<div
|
||||
className="mx_ThreadInfo"
|
||||
onClick={() => {
|
||||
dis.dispatch({
|
||||
action: Action.SetRightPanelPhase,
|
||||
|
@ -544,7 +545,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
<span className="mx_EventListSummary_avatars">
|
||||
{ avatars }
|
||||
</span>
|
||||
{ thread.length } { thread.length === 1 ? 'reply' : 'replies' }
|
||||
{ thread.length - 1 } { thread.length === 2 ? 'reply' : 'replies' }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue