Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 2bfffab

Browse files
toger5t3chguyjryans
authored
Add edits and replies to the right panel timeline & prepare the timelineCard to share code with threads (#7262)
Co-authored-by: Michael Telatynski <[email protected]> Co-authored-by: J. Ryan Stinnett <[email protected]>
1 parent 43f264c commit 2bfffab

File tree

2 files changed

+149
-41
lines changed

2 files changed

+149
-41
lines changed

src/components/structures/RightPanel.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,12 @@ export default class RightPanel extends React.Component<IProps, IState> {
339339
if (!SettingsStore.getValue("feature_maximised_widgets")) break;
340340
panel = <TimelineCard
341341
room={this.props.room}
342+
timelineSet={this.props.room.getUnfilteredTimelineSet()}
342343
resizeNotifier={this.props.resizeNotifier}
343-
onClose={this.onClose} />;
344+
onClose={this.onClose}
345+
permalinkCreator={this.props.permalinkCreator}
346+
e2eStatus={this.props.e2eStatus}
347+
/>;
344348
break;
345349
case RightPanelPhases.FilePanel:
346350
panel = <FilePanel roomId={roomId} resizeNotifier={this.props.resizeNotifier} onClose={this.onClose} />;

src/components/views/right_panel/TimelineCard.tsx

Lines changed: 144 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ limitations under the License.
1515
*/
1616

1717
import React from 'react';
18-
import { MatrixEvent, Room } from 'matrix-js-sdk/src';
18+
import { EventSubscription } from "fbemitter";
19+
import { EventTimelineSet, IEventRelation, MatrixEvent, Room } from 'matrix-js-sdk/src';
1920
import { Thread } from 'matrix-js-sdk/src/models/thread';
2021

2122
import BaseCard from "./BaseCard";
@@ -27,77 +28,180 @@ import { Layout } from '../../../settings/enums/Layout';
2728
import TimelinePanel from '../../structures/TimelinePanel';
2829
import { E2EStatus } from '../../../utils/ShieldUtils';
2930
import EditorStateTransfer from '../../../utils/EditorStateTransfer';
30-
import RoomContext from '../../../contexts/RoomContext';
31-
31+
import RoomContext, { TimelineRenderingType } from '../../../contexts/RoomContext';
32+
import dis from '../../../dispatcher/dispatcher';
3233
import { _t } from '../../../languageHandler';
3334
import { replaceableComponent } from '../../../utils/replaceableComponent';
35+
import { ActionPayload } from '../../../dispatcher/payloads';
36+
import { Action } from '../../../dispatcher/actions';
37+
import RoomViewStore from '../../../stores/RoomViewStore';
38+
import ContentMessages from '../../../ContentMessages';
39+
import UploadBar from '../../structures/UploadBar';
40+
import SettingsStore from '../../../settings/SettingsStore';
3441

3542
interface IProps {
3643
room: Room;
3744
onClose: () => void;
3845
resizeNotifier: ResizeNotifier;
3946
permalinkCreator?: RoomPermalinkCreator;
4047
e2eStatus?: E2EStatus;
41-
initialEvent?: MatrixEvent;
42-
initialEventHighlighted?: boolean;
48+
timelineSet?: EventTimelineSet;
49+
timelineRenderingType?: TimelineRenderingType;
50+
showComposer?: boolean;
51+
composerRelation?: IEventRelation;
4352
}
4453
interface IState {
4554
thread?: Thread;
4655
editState?: EditorStateTransfer;
4756
replyToEvent?: MatrixEvent;
57+
initialEventId?: string;
58+
initialEventHighlighted?: boolean;
59+
60+
// settings:
61+
showReadReceipts?: boolean;
4862
}
4963

5064
@replaceableComponent("structures.TimelineCard")
5165
export default class TimelineCard extends React.Component<IProps, IState> {
5266
static contextType = RoomContext;
5367

68+
private dispatcherRef: string;
69+
private timelinePanelRef: React.RefObject<TimelinePanel> = React.createRef();
70+
private roomStoreToken: EventSubscription;
71+
private settingWatchers: string[];
72+
5473
constructor(props: IProps) {
5574
super(props);
56-
this.state = {};
75+
this.state = {
76+
showReadReceipts: false,
77+
};
78+
this.settingWatchers = [];
5779
}
5880

81+
public componentDidMount(): void {
82+
this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate);
83+
this.dispatcherRef = dis.register(this.onAction);
84+
}
85+
86+
public componentWillUnmount(): void {
87+
// Remove RoomStore listener
88+
if (this.roomStoreToken) {
89+
this.roomStoreToken.remove();
90+
}
91+
dis.unregister(this.dispatcherRef);
92+
for (const watcher of this.settingWatchers) {
93+
SettingsStore.unwatchSetting(watcher);
94+
}
95+
}
96+
97+
private onRoomViewStoreUpdate = async (initial?: boolean): Promise<void> => {
98+
const roomId = this.props.room.roomId;
99+
const newState: Pick<IState, any> = {
100+
// roomLoading: RoomViewStore.isRoomLoading(),
101+
// roomLoadError: RoomViewStore.getRoomLoadError(),
102+
103+
showReadReceipts: SettingsStore.getValue("showReadReceipts", roomId),
104+
initialEventId: RoomViewStore.getInitialEventId(),
105+
initialEventHighlighted: RoomViewStore.isInitialEventHighlighted(),
106+
replyToEvent: RoomViewStore.getQuotingEvent(),
107+
};
108+
109+
this.settingWatchers = this.settingWatchers.concat([
110+
SettingsStore.watchSetting("showReadReceipts", roomId, (...[,,, value]) =>
111+
this.setState({ showReadReceipts: value as boolean }),
112+
),
113+
]);
114+
this.setState(newState);
115+
};
116+
117+
private onAction = (payload: ActionPayload): void => {
118+
switch (payload.action) {
119+
case Action.EditEvent:
120+
this.setState({
121+
editState: payload.event ? new EditorStateTransfer(payload.event) : null,
122+
}, () => {
123+
if (payload.event) {
124+
this.timelinePanelRef.current?.scrollToEventIfNeeded(payload.event.getId());
125+
}
126+
});
127+
break;
128+
default:
129+
break;
130+
}
131+
};
132+
133+
private onScroll = (): void => {
134+
if (this.state.initialEventId && this.state.initialEventHighlighted) {
135+
dis.dispatch({
136+
action: Action.ViewRoom,
137+
room_id: this.props.room.roomId,
138+
event_id: this.state.initialEventId,
139+
highlighted: false,
140+
replyingToEvent: this.state.replyToEvent,
141+
});
142+
}
143+
};
144+
59145
private renderTimelineCardHeader = (): JSX.Element => {
60146
return <div className="mx_TimelineCard__header">
61147
<span>{ _t("Chat") }</span>
62148
</div>;
63149
};
64150

65151
public render(): JSX.Element {
152+
const highlightedEventId = this.state.initialEventHighlighted
153+
? this.state.initialEventId
154+
: null;
155+
66156
return (
67-
<BaseCard
68-
className="mx_ThreadPanel mx_TimelineCard"
69-
onClose={this.props.onClose}
70-
withoutScrollContainer={true}
71-
header={this.renderTimelineCardHeader()}
72-
>
73-
<TimelinePanel
74-
showReadReceipts={false} // TODO: RR's cause issues with limited horizontal space
75-
manageReadReceipts={true}
76-
manageReadMarkers={false} // No RM support in the TimelineCard
77-
sendReadReceiptOnLoad={true}
78-
timelineSet={this.props.room.getUnfilteredTimelineSet()}
79-
showUrlPreview={true}
80-
layout={Layout.Group}
81-
hideThreadedMessages={false}
82-
hidden={false}
83-
showReactions={true}
84-
className="mx_RoomView_messagePanel mx_GroupLayout"
85-
permalinkCreator={this.props.permalinkCreator}
86-
membersLoaded={true}
87-
editState={this.state.editState}
88-
eventId={this.props.initialEvent?.getId()}
89-
resizeNotifier={this.props.resizeNotifier}
90-
/>
91-
92-
<MessageComposer
93-
room={this.props.room}
94-
resizeNotifier={this.props.resizeNotifier}
95-
replyToEvent={this.state.replyToEvent}
96-
permalinkCreator={this.props.permalinkCreator}
97-
e2eStatus={this.props.e2eStatus}
98-
compact={true}
99-
/>
100-
</BaseCard>
157+
<RoomContext.Provider value={{
158+
...this.context,
159+
timelineRenderingType: this.props.timelineRenderingType ?? this.context.timelineRenderingType,
160+
liveTimeline: this.props.timelineSet.getLiveTimeline(),
161+
}}>
162+
<BaseCard
163+
className="mx_ThreadPanel mx_TimelineCard"
164+
onClose={this.props.onClose}
165+
withoutScrollContainer={true}
166+
header={this.renderTimelineCardHeader()}
167+
>
168+
<TimelinePanel
169+
ref={this.timelinePanelRef}
170+
showReadReceipts={/*this.state.showReadReceipts*/ false} // TODO: RR's cause issues with limited horizontal space
171+
manageReadReceipts={true}
172+
manageReadMarkers={false} // No RM support in the TimelineCard
173+
sendReadReceiptOnLoad={true}
174+
timelineSet={this.props.timelineSet}
175+
showUrlPreview={true}
176+
layout={Layout.Group}
177+
hideThreadedMessages={false}
178+
hidden={false}
179+
showReactions={true}
180+
className="mx_RoomView_messagePanel mx_GroupLayout"
181+
permalinkCreator={this.props.permalinkCreator}
182+
membersLoaded={true}
183+
editState={this.state.editState}
184+
eventId={this.state.initialEventId}
185+
resizeNotifier={this.props.resizeNotifier}
186+
highlightedEventId={highlightedEventId}
187+
onUserScroll={this.onScroll}
188+
/>
189+
190+
{ ContentMessages.sharedInstance().getCurrentUploads(this.props.composerRelation).length > 0 && (
191+
<UploadBar room={this.props.room} relation={this.props.composerRelation} />
192+
) }
193+
194+
<MessageComposer
195+
room={this.props.room}
196+
relation={this.props.composerRelation}
197+
resizeNotifier={this.props.resizeNotifier}
198+
replyToEvent={this.state.replyToEvent}
199+
permalinkCreator={this.props.permalinkCreator}
200+
e2eStatus={this.props.e2eStatus}
201+
compact={true}
202+
/>
203+
</BaseCard>
204+
</RoomContext.Provider>
101205
);
102206
}
103207
}

0 commit comments

Comments
 (0)