mirror of https://github.com/vector-im/riot-web
hide thread events from the timeline
parent
e5024c4b71
commit
d1dbfbd014
|
@ -670,3 +670,33 @@ $hover-select-border: 4px;
|
|||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.mx_ThreadView {
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.mx_ThreadView_List {
|
||||
flex: 1;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.mx_EventTile_roomName {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_EventTile_line {
|
||||
padding-left: 0 !important;
|
||||
order: 10 !important;
|
||||
}
|
||||
.mx_EventTile {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-bottom: 1px solid #888;
|
||||
margin-top: 0;
|
||||
padding-bottom: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 8V8C1.89543 8 1 7.10457 1 6V3C1 1.89543 1.89543 1 3 1H15C16.1046 1 17 1.89484 17 2.9994C17 3.88147 17 4.95392 17 6.00008C17 7.10465 16.1046 8 15 8H10.5" stroke="#737D8C" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.2011 16.7176C12.9087 17.011 12.9088 17.4866 13.2012 17.78C13.4936 18.0734 13.9677 18.0733 14.2601 17.78C14.9484 17.0894 15.6519 16.3829 16.1834 15.8491L16.8282 15.2014L17.0099 15.0188L17.0579 14.9706L17.0702 14.9582L17.0733 14.955L17.0741 14.9542L17.0743 14.954L17.0743 14.954L16.5444 14.4233L17.0744 14.954C17.3663 14.6606 17.3661 14.1855 17.0741 13.8922L14.2539 11.061C13.9616 10.7675 13.4875 10.7674 13.195 11.0606C12.9024 11.3539 12.9023 11.8295 13.1946 12.123L14.7442 13.6787L10.1137 13.6787C8.69795 13.6787 7.49996 12.4759 7.49996 10.9288L7.49996 7.00002C7.49996 6.58581 7.16417 6.25002 6.74996 6.25002C6.33574 6.25002 5.99996 6.58581 5.99996 7.00002L5.99996 10.9288C5.99996 13.2476 7.81395 15.1787 10.1137 15.1787H14.7341C14.2713 15.6436 13.7316 16.1854 13.2011 16.7176Z" fill="#737D8C"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -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…
Reference in New Issue