hide thread events from the timeline
This commit is contained in:
parent
e5024c4b71
commit
d1dbfbd014
7 changed files with 110 additions and 11 deletions
|
@ -173,6 +173,8 @@ interface IProps {
|
|||
onUnfillRequest?(backwards: boolean, scrollToken: string): void;
|
||||
|
||||
getRelationsForEvent?(eventId: string, relationType: string, eventType: string): Relations;
|
||||
|
||||
hideThreadedMessages?: boolean;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
|
@ -443,6 +445,11 @@ export default class MessagePanel extends React.Component<IProps, IState> {
|
|||
// Always show highlighted event
|
||||
if (this.props.highlightedEventId === mxEv.getId()) return true;
|
||||
|
||||
const threadingEnabled = SettingsStore.getValue("feature_threading");
|
||||
if (threadingEnabled && mxEv.replyEventId && this.props.hideThreadedMessages === true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !shouldHideEvent(mxEv, this.context);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,11 @@ import { replaceableComponent } from "../../utils/replaceableComponent";
|
|||
import { MatrixClientPeg } from '../../MatrixClientPeg';
|
||||
|
||||
import ResizeNotifier from '../../utils/ResizeNotifier';
|
||||
import EventTile from '../views/rooms/EventTile';
|
||||
import EventTile, { TileShape } from '../views/rooms/EventTile';
|
||||
import MessageComposer from '../views/rooms/MessageComposer';
|
||||
import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks';
|
||||
import { Layout } from '../../settings/Layout';
|
||||
import TimelinePanel from './TimelinePanel';
|
||||
|
||||
interface IProps {
|
||||
roomId: string;
|
||||
|
@ -37,6 +39,7 @@ interface IProps {
|
|||
}
|
||||
|
||||
interface IState {
|
||||
replyToEvent?: MatrixEvent;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -65,6 +68,7 @@ class ThreadView extends React.Component<IProps, IState> {
|
|||
mxEvent={event}
|
||||
enableFlair={false}
|
||||
showReadReceipts={false}
|
||||
tileShape={TileShape.FileGrid}
|
||||
as="div"
|
||||
/>;
|
||||
}
|
||||
|
@ -77,19 +81,24 @@ class ThreadView extends React.Component<IProps, IState> {
|
|||
className="mx_ThreadView"
|
||||
onClose={this.props.onClose}
|
||||
previousPhase={RightPanelPhases.RoomSummary}
|
||||
withoutScrollContainer={true}
|
||||
>
|
||||
{ this.renderEventTile(this.props.mxEvent) }
|
||||
|
||||
{ thread && (
|
||||
thread.eventTimeline.map((event: MatrixEvent) => {
|
||||
return this.renderEventTile(event);
|
||||
})
|
||||
) }
|
||||
|
||||
<TimelinePanel
|
||||
manageReadReceipts={false}
|
||||
manageReadMarkers={false}
|
||||
timelineSet={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={this.props.mxEvent}
|
||||
replyToEvent={thread?.replyToEvent}
|
||||
showReplyPreview={false}
|
||||
permalinkCreator={this.props.permalinkCreator}
|
||||
/>
|
||||
</BaseCard>
|
||||
|
|
|
@ -126,6 +126,8 @@ interface IProps {
|
|||
|
||||
// callback which is called when we wish to paginate the timeline window.
|
||||
onPaginationRequest?(timelineWindow: TimelineWindow, direction: string, size: number): Promise<boolean>;
|
||||
|
||||
hideThreadedMessages?: boolean;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
|
@ -214,6 +216,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
|||
timelineCap: Number.MAX_VALUE,
|
||||
className: 'mx_RoomView_messagePanel',
|
||||
sendReadReceiptOnLoad: true,
|
||||
hideThreadedMessages: true,
|
||||
};
|
||||
|
||||
private lastRRSentEventId: string = undefined;
|
||||
|
@ -1511,6 +1514,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
|||
showReactions={this.props.showReactions}
|
||||
layout={this.props.layout}
|
||||
enableFlair={SettingsStore.getValue(UIFeature.Flair)}
|
||||
hideThreadedMessages={this.props.hideThreadedMessages}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ import ReadReceiptMarker from "./ReadReceiptMarker";
|
|||
import MessageActionBar from "../messages/MessageActionBar";
|
||||
import ReactionsRow from '../messages/ReactionsRow';
|
||||
import { getEventDisplayInfo } from '../../../utils/EventUtils';
|
||||
import { RightPanelPhases } from "../../../stores/RightPanelStorePhases";
|
||||
|
||||
const eventTileTypes = {
|
||||
[EventType.RoomMessage]: 'messages.MessageEvent',
|
||||
|
@ -299,6 +300,9 @@ interface IProps {
|
|||
|
||||
// whether or not to display the sender
|
||||
hideSender?: boolean;
|
||||
|
||||
// whether or not to display thread info
|
||||
showThreadInfo?: boolean;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
|
@ -451,6 +455,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
client.on("Room.receipt", this.onRoomReceipt);
|
||||
this.isListeningForReceipts = true;
|
||||
}
|
||||
this.props.mxEvent.on("Thread.update", this.forceUpdate);
|
||||
}
|
||||
|
||||
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
|
||||
|
@ -491,6 +496,38 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
}
|
||||
}
|
||||
|
||||
private renderThreadInfo(): React.ReactNode {
|
||||
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||
const thread = room.getThread(this.props.mxEvent.getId());
|
||||
if (!thread || this.props.showThreadInfo === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const avatars = Array.from(thread.participants).map((mxId: string) => {
|
||||
const member = room.getMember(mxId);
|
||||
return <MemberAvatar key={member.userId} member={member} width={14} height={14} />;
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={() => {
|
||||
dis.dispatch({
|
||||
action: Action.SetRightPanelPhase,
|
||||
phase: RightPanelPhases.ThreadView,
|
||||
refireParams: {
|
||||
event: this.props.mxEvent,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<span className="mx_EventListSummary_avatars">
|
||||
{ avatars }
|
||||
</span>
|
||||
{ thread.length } { thread.length === 1 ? 'reply' : 'replies' }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private onRoomReceipt = (ev, room) => {
|
||||
// ignore events for other rooms
|
||||
const tileRoom = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||
|
@ -1167,6 +1204,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
{ keyRequestInfo }
|
||||
{ actionBar }
|
||||
{ this.props.layout === Layout.IRC && (reactionsRow) }
|
||||
{ this.renderThreadInfo() }
|
||||
</div>
|
||||
{ this.props.layout !== Layout.IRC && (reactionsRow) }
|
||||
{ msgOption }
|
||||
|
|
|
@ -183,6 +183,7 @@ interface IProps {
|
|||
resizeNotifier: ResizeNotifier;
|
||||
permalinkCreator: RoomPermalinkCreator;
|
||||
replyToEvent?: MatrixEvent;
|
||||
showReplyPreview?: boolean;
|
||||
e2eStatus?: E2EStatus;
|
||||
}
|
||||
|
||||
|
@ -201,6 +202,10 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
|||
private messageComposerInput: SendMessageComposer;
|
||||
private voiceRecordingButton: VoiceRecordComposerTile;
|
||||
|
||||
static defaultProps = {
|
||||
showReplyPreview: true,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
VoiceRecordingStore.instance.on(UPDATE_EVENT, this.onVoiceStoreUpdate);
|
||||
|
@ -454,7 +459,9 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
|||
<div className="mx_MessageComposer mx_GroupLayout">
|
||||
{ recordingTooltip }
|
||||
<div className="mx_MessageComposer_wrapper">
|
||||
<ReplyPreview permalinkCreator={this.props.permalinkCreator} />
|
||||
{ this.props.showReplyPreview && (
|
||||
<ReplyPreview permalinkCreator={this.props.permalinkCreator} />
|
||||
) }
|
||||
<div className="mx_MessageComposer_row">
|
||||
{ controls }
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue