1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-23 17:02:25 +03:00

Update filters to reflect MSC3440 (threads) (#2065)

This commit is contained in:
Germain
2021-12-22 13:58:21 +00:00
committed by GitHub
parent 2aae2362e3
commit bae883a891
6 changed files with 58 additions and 37 deletions

View File

@@ -4839,12 +4839,11 @@ export class MatrixClient extends EventEmitter {
* <code>null</code>. * <code>null</code>.
* @return {module:http-api.MatrixError} Rejects: with an error response. * @return {module:http-api.MatrixError} Rejects: with an error response.
*/ */
public scrollback(room: Room, limit: number, callback?: Callback): Promise<Room> { public scrollback(room: Room, limit = 30, callback?: Callback): Promise<Room> {
if (utils.isFunction(limit)) { if (utils.isFunction(limit)) {
callback = limit as any as Callback; // legacy callback = limit as any as Callback; // legacy
limit = undefined; limit = undefined;
} }
limit = limit || 30;
let timeToWaitMs = 0; let timeToWaitMs = 0;
let info = this.ongoingScrollbacks[room.roomId] || {}; let info = this.ongoingScrollbacks[room.roomId] || {};
@@ -5025,7 +5024,7 @@ export class MatrixClient extends EventEmitter {
// XXX: Intended private, used in code. // XXX: Intended private, used in code.
public createMessagesRequest( public createMessagesRequest(
roomId: string, roomId: string,
fromToken: string, fromToken: string | null,
limit = 30, limit = 30,
dir: Direction, dir: Direction,
timelineFilter?: Filter, timelineFilter?: Filter,
@@ -5033,11 +5032,14 @@ export class MatrixClient extends EventEmitter {
const path = utils.encodeUri("/rooms/$roomId/messages", { $roomId: roomId }); const path = utils.encodeUri("/rooms/$roomId/messages", { $roomId: roomId });
const params: Record<string, string> = { const params: Record<string, string> = {
from: fromToken,
limit: limit.toString(), limit: limit.toString(),
dir, dir: dir,
}; };
if (fromToken) {
params.from = fromToken;
}
let filter = null; let filter = null;
if (this.clientOpts.lazyLoadMembers) { if (this.clientOpts.lazyLoadMembers) {
// create a shallow copy of LAZY_LOADING_MESSAGES_FILTER, // create a shallow copy of LAZY_LOADING_MESSAGES_FILTER,
@@ -5086,11 +5088,6 @@ export class MatrixClient extends EventEmitter {
const dir = backwards ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS; const dir = backwards ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS;
const token = eventTimeline.getPaginationToken(dir); const token = eventTimeline.getPaginationToken(dir);
if (!token) {
// no token - no results.
return Promise.resolve(false);
}
const pendingRequest = eventTimeline.paginationRequests[dir]; const pendingRequest = eventTimeline.paginationRequests[dir];
if (pendingRequest) { if (pendingRequest) {

View File

@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { UNSTABLE_FILTER_RELATION_SENDERS, UNSTABLE_FILTER_RELATION_TYPES } from "./filter";
import { MatrixEvent } from "./models/event"; import { MatrixEvent } from "./models/event";
/** /**
@@ -89,6 +90,8 @@ export class FilterComponent {
senders: this.filterJson.senders || null, senders: this.filterJson.senders || null,
not_senders: this.filterJson.not_senders || [], not_senders: this.filterJson.not_senders || [],
contains_url: this.filterJson.contains_url || null, contains_url: this.filterJson.contains_url || null,
[UNSTABLE_FILTER_RELATION_SENDERS.name]: UNSTABLE_FILTER_RELATION_SENDERS.findIn(this.filterJson),
[UNSTABLE_FILTER_RELATION_TYPES.name]: UNSTABLE_FILTER_RELATION_TYPES.findIn(this.filterJson),
}; };
} }

View File

@@ -65,7 +65,7 @@ export interface IFilterDefinition {
export interface IRoomEventFilter extends IFilterComponent { export interface IRoomEventFilter extends IFilterComponent {
lazy_load_members?: boolean; lazy_load_members?: boolean;
include_redundant_members?: boolean; include_redundant_members?: boolean;
types?: EventType[] | string[]; types?: Array<EventType | string>;
[UNSTABLE_FILTER_RELATION_TYPES.name]?: Array<RelationType | string>; [UNSTABLE_FILTER_RELATION_TYPES.name]?: Array<RelationType | string>;
[UNSTABLE_FILTER_RELATION_SENDERS.name]?: string[]; [UNSTABLE_FILTER_RELATION_SENDERS.name]?: string[];
} }

View File

@@ -209,7 +209,7 @@ export class EventTimelineSet extends EventEmitter {
* *
* @fires module:client~MatrixClient#event:"Room.timelineReset" * @fires module:client~MatrixClient#event:"Room.timelineReset"
*/ */
public resetLiveTimeline(backPaginationToken: string, forwardPaginationToken?: string): void { public resetLiveTimeline(backPaginationToken?: string, forwardPaginationToken?: string): void {
// Each EventTimeline has RoomState objects tracking the state at the start // Each EventTimeline has RoomState objects tracking the state at the start
// and end of that timeline. The copies at the end of the live timeline are // and end of that timeline. The copies at the end of the live timeline are
// special because they will have listeners attached to monitor changes to // special because they will have listeners attached to monitor changes to

View File

@@ -34,13 +34,13 @@ export class EventTimeline {
* Symbolic constant for methods which take a 'direction' argument: * Symbolic constant for methods which take a 'direction' argument:
* refers to the start of the timeline, or backwards in time. * refers to the start of the timeline, or backwards in time.
*/ */
static BACKWARDS = Direction.Backward; public static readonly BACKWARDS = Direction.Backward;
/** /**
* Symbolic constant for methods which take a 'direction' argument: * Symbolic constant for methods which take a 'direction' argument:
* refers to the end of the timeline, or forwards in time. * refers to the end of the timeline, or forwards in time.
*/ */
static FORWARDS = Direction.Forward; public static readonly FORWARDS = Direction.Forward;
/** /**
* Static helper method to set sender and target properties * Static helper method to set sender and target properties

View File

@@ -20,8 +20,8 @@ limitations under the License.
import { EventEmitter } from "events"; import { EventEmitter } from "events";
import { DuplicateStrategy, EventTimelineSet } from "./event-timeline-set"; import { EventTimelineSet, DuplicateStrategy } from "./event-timeline-set";
import { EventTimeline } from "./event-timeline"; import { Direction, EventTimeline } from "./event-timeline";
import { getHttpUriForMxc } from "../content-repo"; import { getHttpUriForMxc } from "../content-repo";
import * as utils from "../utils"; import * as utils from "../utils";
import { normalize } from "../utils"; import { normalize } from "../utils";
@@ -110,6 +110,13 @@ export enum NotificationCountType {
Total = "total", Total = "total",
} }
export interface ICreateFilterOpts {
// Populate the filtered timeline with already loaded events in the room
// timeline. Useful to disable for some filters that can't be achieved by the
// client in an efficient manner
prepopulateTimeline?: boolean;
}
export class Room extends EventEmitter { export class Room extends EventEmitter {
private readonly reEmitter: ReEmitter; private readonly reEmitter: ReEmitter;
private txnToEvent: Record<string, MatrixEvent> = {}; // Pending in-flight requests { string: MatrixEvent } private txnToEvent: Record<string, MatrixEvent> = {}; // Pending in-flight requests { string: MatrixEvent }
@@ -793,7 +800,7 @@ export class Room extends EventEmitter {
* timeline which would otherwise be unable to paginate forwards without this token). * timeline which would otherwise be unable to paginate forwards without this token).
* Removing just the old live timeline whilst preserving previous ones is not supported. * Removing just the old live timeline whilst preserving previous ones is not supported.
*/ */
public resetLiveTimeline(backPaginationToken: string, forwardPaginationToken: string): void { public resetLiveTimeline(backPaginationToken: string | null, forwardPaginationToken: string | null): void {
for (let i = 0; i < this.timelineSets.length; i++) { for (let i = 0; i < this.timelineSets.length; i++) {
this.timelineSets[i].resetLiveTimeline( this.timelineSets[i].resetLiveTimeline(
backPaginationToken, forwardPaginationToken, backPaginationToken, forwardPaginationToken,
@@ -1222,9 +1229,14 @@ export class Room extends EventEmitter {
/** /**
* Add a timelineSet for this room with the given filter * Add a timelineSet for this room with the given filter
* @param {Filter} filter The filter to be applied to this timelineSet * @param {Filter} filter The filter to be applied to this timelineSet
* @param {Object=} opts Configuration options
* @param {*} opts.storageToken Optional.
* @return {EventTimelineSet} The timelineSet * @return {EventTimelineSet} The timelineSet
*/ */
public getOrCreateFilteredTimelineSet(filter: Filter): EventTimelineSet { public getOrCreateFilteredTimelineSet(
filter: Filter,
{ prepopulateTimeline = true }: ICreateFilterOpts = {},
): EventTimelineSet {
if (this.filteredTimelineSets[filter.filterId]) { if (this.filteredTimelineSets[filter.filterId]) {
return this.filteredTimelineSets[filter.filterId]; return this.filteredTimelineSets[filter.filterId];
} }
@@ -1234,30 +1246,39 @@ export class Room extends EventEmitter {
this.filteredTimelineSets[filter.filterId] = timelineSet; this.filteredTimelineSets[filter.filterId] = timelineSet;
this.timelineSets.push(timelineSet); this.timelineSets.push(timelineSet);
// populate up the new timelineSet with filtered events from our live
// unfiltered timeline.
//
// XXX: This is risky as our timeline
// may have grown huge and so take a long time to filter.
// see https://github.com/vector-im/vector-web/issues/2109
const unfilteredLiveTimeline = this.getLiveTimeline(); const unfilteredLiveTimeline = this.getLiveTimeline();
// Not all filter are possible to replicate client-side only
// When that's the case we do not want to prepopulate from the live timeline
// as we would get incorrect results compared to what the server would send back
if (prepopulateTimeline) {
// populate up the new timelineSet with filtered events from our live
// unfiltered timeline.
//
// XXX: This is risky as our timeline
// may have grown huge and so take a long time to filter.
// see https://github.com/vector-im/vector-web/issues/2109
unfilteredLiveTimeline.getEvents().forEach(function(event) { unfilteredLiveTimeline.getEvents().forEach(function(event) {
timelineSet.addLiveEvent(event); timelineSet.addLiveEvent(event);
}); });
// find the earliest unfiltered timeline // find the earliest unfiltered timeline
let timeline = unfilteredLiveTimeline; let timeline = unfilteredLiveTimeline;
while (timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS)) { while (timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS)) {
timeline = timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS); timeline = timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS);
}
timelineSet.getLiveTimeline().setPaginationToken(
timeline.getPaginationToken(EventTimeline.BACKWARDS),
EventTimeline.BACKWARDS,
);
} else {
const livePaginationToken = unfilteredLiveTimeline.getPaginationToken(Direction.Forward);
timelineSet
.getLiveTimeline()
.setPaginationToken(livePaginationToken, Direction.Backward);
} }
timelineSet.getLiveTimeline().setPaginationToken(
timeline.getPaginationToken(EventTimeline.BACKWARDS),
EventTimeline.BACKWARDS,
);
// alternatively, we could try to do something like this to try and re-paginate // alternatively, we could try to do something like this to try and re-paginate
// in the filtered events from nothing, but Mark says it's an abuse of the API // in the filtered events from nothing, but Mark says it's an abuse of the API
// to do so: // to do so: