Move timeline set creation logic to the JS SDK (#8070)

This commit is contained in:
Germain 2022-03-18 11:59:03 +00:00 committed by GitHub
parent da097d42ef
commit 12d26555af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 204 deletions

View file

@ -16,20 +16,7 @@ limitations under the License.
import React, { useContext, useEffect, useRef, useState } from 'react';
import { EventTimelineSet } from 'matrix-js-sdk/src/models/event-timeline-set';
import { Room } from 'matrix-js-sdk/src/models/room';
import { MatrixClient } from 'matrix-js-sdk/src/client';
import {
Filter,
IFilterDefinition,
} from 'matrix-js-sdk/src/filter';
import {
FILTER_RELATED_BY_REL_TYPES,
FILTER_RELATED_BY_SENDERS,
Thread,
ThreadEvent,
THREAD_RELATION_TYPE,
} from 'matrix-js-sdk/src/models/thread';
import { EventTimeline } from 'matrix-js-sdk/src/models/event-timeline';
import { Thread, ThreadEvent } from 'matrix-js-sdk/src/models/thread';
import BaseCard from "../views/right_panel/BaseCard";
import ResizeNotifier from '../../utils/ResizeNotifier';
@ -45,72 +32,13 @@ import Measured from '../views/elements/Measured';
import PosthogTrackers from "../../PosthogTrackers";
import { ButtonEvent } from "../views/elements/AccessibleButton";
export async function getThreadTimelineSet(
client: MatrixClient,
room: Room,
filterType = ThreadFilterType.All,
): Promise<EventTimelineSet> {
if (Thread.hasServerSideSupport) {
const myUserId = client.getUserId();
const filter = new Filter(myUserId);
const definition: IFilterDefinition = {
"room": {
"timeline": {
[FILTER_RELATED_BY_REL_TYPES.name]: [THREAD_RELATION_TYPE.name],
},
},
};
if (filterType === ThreadFilterType.My) {
definition.room.timeline[FILTER_RELATED_BY_SENDERS.name] = [myUserId];
}
filter.setDefinition(definition);
const filterId = await client.getOrCreateFilter(
`THREAD_PANEL_${room.roomId}_${filterType}`,
filter,
);
filter.filterId = filterId;
const timelineSet = room.getOrCreateFilteredTimelineSet(
filter,
{
prepopulateTimeline: false,
pendingEvents: false,
},
);
// An empty pagination token allows to paginate from the very bottom of
// the timeline set.
timelineSet.getLiveTimeline().setPaginationToken("", EventTimeline.BACKWARDS);
return timelineSet;
} else {
// Filter creation fails if HomeServer does not support the new relation
// filter fields. We fallback to the threads that have been discovered in
// the main timeline
const timelineSet = new EventTimelineSet(room, {
pendingEvents: false,
});
Array.from(room.threads)
.forEach(([, thread]) => {
if (thread.length === 0) return;
const currentUserParticipated = thread.events.some(event => event.getSender() === client.getUserId());
if (filterType !== ThreadFilterType.My || currentUserParticipated) {
timelineSet.getLiveTimeline().addEvent(thread.rootEvent, false);
}
});
return timelineSet;
}
}
interface IProps {
roomId: string;
onClose: () => void;
resizeNotifier: ResizeNotifier;
permalinkCreator: RoomPermalinkCreator;
allThreadsTimelineSet: EventTimelineSet;
myThreadsTimelineSet: EventTimelineSet;
}
export enum ThreadFilterType {
@ -224,7 +152,13 @@ const EmptyThread: React.FC<EmptyThreadIProps> = ({ filterOption, showAllThreads
</aside>;
};
const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) => {
const ThreadPanel: React.FC<IProps> = ({
roomId,
onClose,
permalinkCreator,
myThreadsTimelineSet,
allThreadsTimelineSet,
}) => {
const mxClient = useContext(MatrixClientContext);
const roomContext = useContext(RoomContext);
const timelinePanel = useRef<TimelinePanel>();
@ -241,17 +175,8 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
}, [mxClient, roomId]);
useEffect(() => {
async function onNewThread(thread: Thread, toStartOfTimeline: boolean): Promise<void> {
function onNewThread(): void {
setThreadCount(room.threads.size);
if (timelineSet) {
// When the server support threads we're only interested in adding
// the newly created threads to the list.
// The ones discovered when scrolling back should be discarded as
// they will be discovered by the `/messages` filter
if (!Thread.hasServerSideSupport || !toStartOfTimeline) {
timelineSet.addEventToTimeline(thread.rootEvent, timelineSet.getLiveTimeline(), toStartOfTimeline);
}
}
}
function refreshTimeline() {
@ -270,13 +195,17 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
}, [room, mxClient, timelineSet]);
useEffect(() => {
getThreadTimelineSet(mxClient, room, filterOption)
.then(timelineSet => { setTimelineSet(timelineSet); })
.catch(() => setTimelineSet(null));
}, [mxClient, room, filterOption]);
if (filterOption === ThreadFilterType.My) {
setTimelineSet(myThreadsTimelineSet);
} else {
setTimelineSet(allThreadsTimelineSet);
}
}, [filterOption, allThreadsTimelineSet, myThreadsTimelineSet]);
useEffect(() => {
if (timelineSet) timelinePanel.current.refreshTimeline();
if (timelineSet && !Thread.hasServerSideSupport) {
timelinePanel.current.refreshTimeline();
}
}, [timelineSet, timelinePanel]);
return (