fix pagination
This commit is contained in:
parent
7a553917ed
commit
b9f6b82611
5 changed files with 112 additions and 126 deletions
12
dist/src/timeline.d.ts
vendored
12
dist/src/timeline.d.ts
vendored
|
@ -5,22 +5,25 @@ import { Thread } from "./thread.js";
|
|||
export interface Timeline {
|
||||
isLive: boolean;
|
||||
events: Array<Event>;
|
||||
paginate(dir: "f" | "b", limit: number): Promise<boolean>;
|
||||
}
|
||||
export declare class RoomTimeline implements Timeline {
|
||||
room: Room;
|
||||
events: Array<Event>;
|
||||
isLive: boolean;
|
||||
prevBatch: string | null;
|
||||
nextBatch: string | null;
|
||||
prevBatch: string | null | undefined;
|
||||
nextBatch: string | null | undefined;
|
||||
constructor(room: Room);
|
||||
paginate(dir: "f" | "b", limit?: number): Promise<boolean>;
|
||||
}
|
||||
export declare class ThreadTimeline implements Timeline {
|
||||
thread: Thread;
|
||||
events: Array<Event>;
|
||||
isLive: boolean;
|
||||
prevBatch: string | null;
|
||||
nextBatch: string | null;
|
||||
prevBatch: string | null | undefined;
|
||||
nextBatch: string | null | undefined;
|
||||
constructor(thread: Thread);
|
||||
paginate(dir: "f" | "b", limit?: number): Promise<boolean>;
|
||||
}
|
||||
export declare class TimelineSet {
|
||||
room: Room;
|
||||
|
@ -28,6 +31,5 @@ export declare class TimelineSet {
|
|||
private timelines;
|
||||
constructor(room: Room);
|
||||
forEvent(eventId: EventId): Promise<RoomTimeline>;
|
||||
paginate(timeline: Timeline, dir: "f" | "b", limit?: number): Promise<boolean>;
|
||||
_appendEvents(events: Array<Event>): void;
|
||||
}
|
||||
|
|
113
dist/src/timeline.js
vendored
113
dist/src/timeline.js
vendored
|
@ -33,6 +33,30 @@ export class RoomTimeline {
|
|||
value: null
|
||||
});
|
||||
}
|
||||
async paginate(dir, limit = 50) {
|
||||
const from = (dir === "f" ? this.nextBatch : this.prevBatch) || undefined; // FIXME: don't paginate at ends
|
||||
const data = await this.room.client.net.fetchMessages({
|
||||
roomId: this.room.id,
|
||||
dir,
|
||||
limit,
|
||||
from,
|
||||
});
|
||||
if (dir === "f") {
|
||||
const events = data.chunk.map(raw => new Event(this.room, raw));
|
||||
this.nextBatch = data.end || null;
|
||||
this.events.push(...events);
|
||||
for (const event of events)
|
||||
this.room.events.set(event.id, event);
|
||||
}
|
||||
else {
|
||||
const events = data.chunk.reverse().map(raw => new Event(this.room, raw));
|
||||
this.prevBatch = data.end || null;
|
||||
this.events.push(...events);
|
||||
for (const event of events)
|
||||
this.room.events.set(event.id, event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
export class ThreadTimeline {
|
||||
constructor(thread) {
|
||||
|
@ -58,15 +82,39 @@ export class ThreadTimeline {
|
|||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: null
|
||||
value: undefined
|
||||
});
|
||||
Object.defineProperty(this, "nextBatch", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: null
|
||||
value: undefined
|
||||
});
|
||||
}
|
||||
async paginate(dir, limit = 50) {
|
||||
const { room } = this.thread;
|
||||
const from = (dir === "f" ? this.nextBatch : this.prevBatch) || undefined; // FIXME: don't paginate at ends
|
||||
const data = await room.client.net.fetchRelations(room.id, this.thread.baseEvent.id, {
|
||||
dir,
|
||||
from,
|
||||
limit,
|
||||
});
|
||||
if (dir === "f") {
|
||||
const events = data.chunk.map(raw => new Event(room, raw));
|
||||
this.nextBatch = data.next_batch || null;
|
||||
this.events.push(...events);
|
||||
for (const event of events)
|
||||
room.events.set(event.id, event);
|
||||
}
|
||||
else {
|
||||
const events = data.chunk.map(raw => new Event(room, raw));
|
||||
this.prevBatch = data.prev_batch || null;
|
||||
this.events.push(...events);
|
||||
for (const event of events)
|
||||
room.events.set(event.id, event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
export class TimelineSet {
|
||||
// private eventIdToTimeline: Map<EventId, Timeline> = new Map();
|
||||
|
@ -115,67 +163,6 @@ export class TimelineSet {
|
|||
this.timelines.add(tl);
|
||||
return tl;
|
||||
}
|
||||
// Paginate a timeline for more events
|
||||
// TODO: fuse two neighboring timelines together
|
||||
// TODO: don't bother paginating if a timeline is at the end
|
||||
// NOTE: whether a thread starts at the beginning or end depends on whether it's first paginated with "b" or "f"
|
||||
async paginate(timeline, dir, limit = 50) {
|
||||
const { net } = this.room.client;
|
||||
if (timeline instanceof ThreadTimeline) {
|
||||
const from = (dir === "f" ? timeline.nextBatch : timeline.prevBatch) || undefined;
|
||||
if (!from)
|
||||
return false;
|
||||
const data = await net.fetchRelations(this.room.id, timeline.thread.baseEvent.id, {
|
||||
dir,
|
||||
from,
|
||||
limit,
|
||||
});
|
||||
if (dir === "f") {
|
||||
const events = data.chunk.map(raw => new Event(this.room, raw));
|
||||
timeline.nextBatch = data.next_batch;
|
||||
timeline.events.push(...events);
|
||||
for (const event of events)
|
||||
this.room.events.set(event.id, event);
|
||||
}
|
||||
else {
|
||||
const events = data.chunk.map(raw => new Event(this.room, raw));
|
||||
timeline.prevBatch = data.prev_batch;
|
||||
timeline.events.push(...events);
|
||||
for (const event of events)
|
||||
this.room.events.set(event.id, event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (timeline instanceof RoomTimeline) {
|
||||
const from = (dir === "f" ? timeline.nextBatch : timeline.prevBatch) || undefined;
|
||||
if (!from)
|
||||
return false;
|
||||
const data = await net.fetchMessages({
|
||||
roomId: this.room.id,
|
||||
dir,
|
||||
limit,
|
||||
from,
|
||||
});
|
||||
if (dir === "f") {
|
||||
const events = data.chunk.map(raw => new Event(this.room, raw));
|
||||
timeline.nextBatch = data.end;
|
||||
timeline.events.push(...events);
|
||||
for (const event of events)
|
||||
this.room.events.set(event.id, event);
|
||||
}
|
||||
else {
|
||||
const events = data.chunk.reverse().map(raw => new Event(this.room, raw));
|
||||
timeline.prevBatch = data.end;
|
||||
timeline.events.push(...events);
|
||||
for (const event of events)
|
||||
this.room.events.set(event.id, event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
throw new Error("todo");
|
||||
}
|
||||
}
|
||||
_appendEvents(events) {
|
||||
// FIXME: there should only be one live timeline for each room and
|
||||
// thread, they need to be merged together
|
||||
|
|
2
dist/src/timeline.js.map
vendored
2
dist/src/timeline.js.map
vendored
|
@ -1 +1 @@
|
|||
{"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../src/timeline.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../src/timeline.ts"],"names":[],"mappings":"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"}
|
2
dist/tsconfig.tsbuildinfo
vendored
2
dist/tsconfig.tsbuildinfo
vendored
File diff suppressed because one or more lines are too long
109
src/timeline.ts
109
src/timeline.ts
|
@ -14,17 +14,44 @@ export interface Timeline {
|
|||
|
||||
// the events in this timeline
|
||||
events: Array<Event>,
|
||||
|
||||
// Paginate a timeline for more events
|
||||
// TODO: fuse two neighboring timelines together
|
||||
// TODO: don't bother paginating if a timeline is at the end
|
||||
paginate(dir: "f" | "b", limit: number): Promise<boolean>;
|
||||
}
|
||||
|
||||
export class RoomTimeline implements Timeline {
|
||||
public events: Array<Event> = [];
|
||||
public isLive: boolean = false;
|
||||
|
||||
prevBatch: string | null = null;
|
||||
nextBatch: string | null = null;
|
||||
prevBatch: string | null | undefined = null;
|
||||
nextBatch: string | null | undefined = null;
|
||||
|
||||
constructor(public room: Room) {}
|
||||
|
||||
public async paginate(dir: "f" | "b", limit: number = 50): Promise<boolean> {
|
||||
const from = (dir === "f" ? this.nextBatch : this.prevBatch) || undefined; // FIXME: don't paginate at ends
|
||||
const data = await this.room.client.net.fetchMessages({
|
||||
roomId: this.room.id,
|
||||
dir,
|
||||
limit,
|
||||
from,
|
||||
});
|
||||
if (dir === "f") {
|
||||
const events = data.chunk.map(raw => new Event(this.room, raw));
|
||||
this.nextBatch = data.end || null;
|
||||
this.events.push(...events);
|
||||
for (const event of events) this.room.events.set(event.id, event);
|
||||
} else {
|
||||
const events = data.chunk.reverse().map(raw => new Event(this.room, raw));
|
||||
this.prevBatch = data.end || null;
|
||||
this.events.push(...events);
|
||||
for (const event of events) this.room.events.set(event.id, event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// concat(other: RoomTimeline): RoomTimeline {
|
||||
// if (this.events.length === 0) return other;
|
||||
// if (other.events.length === 0) return this;
|
||||
|
@ -37,10 +64,32 @@ export class ThreadTimeline implements Timeline {
|
|||
public events: Array<Event> = [];
|
||||
public isLive: boolean = false;
|
||||
|
||||
prevBatch: string | null = null;
|
||||
nextBatch: string | null = null;
|
||||
prevBatch: string | null | undefined = undefined;
|
||||
nextBatch: string | null | undefined = undefined;
|
||||
|
||||
constructor(public thread: Thread) {}
|
||||
|
||||
public async paginate(dir: "f" | "b", limit: number = 50): Promise<boolean> {
|
||||
const { room } = this.thread;
|
||||
const from = (dir === "f" ? this.nextBatch : this.prevBatch) || undefined; // FIXME: don't paginate at ends
|
||||
const data = await room.client.net.fetchRelations(room.id, this.thread.baseEvent.id, {
|
||||
dir,
|
||||
from,
|
||||
limit,
|
||||
});
|
||||
if (dir === "f") {
|
||||
const events = data.chunk.map(raw => new Event(room, raw));
|
||||
this.nextBatch = data.next_batch || null;
|
||||
this.events.push(...events);
|
||||
for (const event of events) room.events.set(event.id, event);
|
||||
} else {
|
||||
const events = data.chunk.map(raw => new Event(room, raw));
|
||||
this.prevBatch = data.prev_batch || null;
|
||||
this.events.push(...events);
|
||||
for (const event of events) room.events.set(event.id, event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class TimelineSet {
|
||||
|
@ -78,58 +127,6 @@ export class TimelineSet {
|
|||
return tl;
|
||||
}
|
||||
|
||||
// Paginate a timeline for more events
|
||||
// TODO: fuse two neighboring timelines together
|
||||
// TODO: don't bother paginating if a timeline is at the end
|
||||
// NOTE: whether a thread starts at the beginning or end depends on whether it's first paginated with "b" or "f"
|
||||
public async paginate(timeline: Timeline, dir: "f" | "b", limit: number = 50): Promise<boolean> {
|
||||
const { net } = this.room.client;
|
||||
if (timeline instanceof ThreadTimeline) {
|
||||
const from = (dir === "f" ? timeline.nextBatch : timeline.prevBatch) || undefined;
|
||||
if (!from) return false;
|
||||
const data = await net.fetchRelations(this.room.id, timeline.thread.baseEvent.id, {
|
||||
dir,
|
||||
from,
|
||||
limit,
|
||||
});
|
||||
if (dir === "f") {
|
||||
const events = data.chunk.map(raw => new Event(this.room, raw));
|
||||
timeline.nextBatch = data.next_batch;
|
||||
timeline.events.push(...events);
|
||||
for (const event of events) this.room.events.set(event.id, event);
|
||||
} else {
|
||||
const events = data.chunk.map(raw => new Event(this.room, raw));
|
||||
timeline.prevBatch = data.prev_batch;
|
||||
timeline.events.push(...events);
|
||||
for (const event of events) this.room.events.set(event.id, event);
|
||||
}
|
||||
return true;
|
||||
} else if (timeline instanceof RoomTimeline) {
|
||||
const from = (dir === "f" ? timeline.nextBatch : timeline.prevBatch) || undefined;
|
||||
if (!from) return false;
|
||||
const data = await net.fetchMessages({
|
||||
roomId: this.room.id,
|
||||
dir,
|
||||
limit,
|
||||
from,
|
||||
});
|
||||
if (dir === "f") {
|
||||
const events = data.chunk.map(raw => new Event(this.room, raw));
|
||||
timeline.nextBatch = data.end;
|
||||
timeline.events.push(...events);
|
||||
for (const event of events) this.room.events.set(event.id, event);
|
||||
} else {
|
||||
const events = data.chunk.reverse().map(raw => new Event(this.room, raw));
|
||||
timeline.prevBatch = data.end;
|
||||
timeline.events.push(...events);
|
||||
for (const event of events) this.room.events.set(event.id, event);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
throw new Error("todo");
|
||||
}
|
||||
}
|
||||
|
||||
_appendEvents(events: Array<Event>) {
|
||||
// FIXME: there should only be one live timeline for each room and
|
||||
// thread, they need to be merged together
|
||||
|
|
Loading…
Reference in a new issue