Skip to content

Commit

Permalink
Include pending events in thread summary and count again (#2922)
Browse files Browse the repository at this point in the history
* Include pending events in thread summary and count again
* Pass through pending event status
  • Loading branch information
justjanne authored Dec 2, 2022
1 parent 43bfa0c commit 7202484
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 6 deletions.
50 changes: 48 additions & 2 deletions spec/unit/models/thread.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import { MatrixClient } from "../../../src/client";
import { MatrixClient, PendingEventOrdering } from "../../../src/client";
import { Room } from "../../../src/models/room";
import { Thread } from "../../../src/models/thread";
import { Thread, THREAD_RELATION_TYPE, ThreadEvent } from "../../../src/models/thread";
import { mkThread } from "../../test-utils/thread";
import { TestClient } from "../../TestClient";
import { emitPromise, mkMessage } from "../../test-utils/test-utils";
import { EventStatus } from "../../../src";

describe('Thread', () => {
describe("constructor", () => {
Expand All @@ -30,6 +32,50 @@ describe('Thread', () => {
});
});

it("includes pending events in replyCount", async () => {
const myUserId = "@bob:example.org";
const testClient = new TestClient(
myUserId,
"DEVICE",
"ACCESS_TOKEN",
undefined,
{ timelineSupport: false },
);
const client = testClient.client;
const room = new Room("123", client, myUserId, {
pendingEventOrdering: PendingEventOrdering.Detached,
});

jest.spyOn(client, "getRoom").mockReturnValue(room);

const { thread } = mkThread({
room,
client,
authorId: myUserId,
participantUserIds: ["@alice:example.org"],
length: 3,
});
await emitPromise(thread, ThreadEvent.Update);
expect(thread.length).toBe(2);

const event = mkMessage({
room: room.roomId,
user: myUserId,
msg: "thread reply",
relatesTo: {
rel_type: THREAD_RELATION_TYPE.name,
event_id: thread.id,
},
event: true,
});
await thread.processEvent(event);
event.setStatus(EventStatus.SENDING);
room.addPendingEvent(event, "txn01");

await emitPromise(thread, ThreadEvent.Update);
expect(thread.length).toBe(3);
});

describe("hasUserReadEvent", () => {
const myUserId = "@bob:example.org";
let client: MatrixClient;
Expand Down
1 change: 1 addition & 0 deletions src/models/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2017,6 +2017,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
const thread = new Thread(threadId, rootEvent, {
room: this,
client: this.client,
pendingEventOrdering: this.opts.pendingEventOrdering,
});

// This is necessary to be able to jump to events in threads:
Expand Down
26 changes: 22 additions & 4 deletions src/models/thread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ limitations under the License.

import { Optional } from "matrix-events-sdk";

import { MatrixClient } from "../client";
import { MatrixClient, PendingEventOrdering } from "../client";
import { TypedReEmitter } from "../ReEmitter";
import { RelationType } from "../@types/event";
import { IThreadBundledRelationship, MatrixEvent, MatrixEventEvent } from "./event";
import { EventStatus, IThreadBundledRelationship, MatrixEvent, MatrixEventEvent } from "./event";
import { EventTimeline } from "./event-timeline";
import { EventTimelineSet, EventTimelineSetHandlerMap } from './event-timeline-set';
import { NotificationCountType, Room, RoomEvent } from './room';
Expand Down Expand Up @@ -51,6 +51,7 @@ export type EventHandlerMap = {
interface IThreadOpts {
room: Room;
client: MatrixClient;
pendingEventOrdering?: PendingEventOrdering;
}

export enum FeatureSupport {
Expand Down Expand Up @@ -88,9 +89,12 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {

private lastEvent: MatrixEvent | undefined;
private replyCount = 0;
private lastPendingEvent: MatrixEvent | undefined;
private pendingReplyCount = 0;

public readonly room: Room;
public readonly client: MatrixClient;
private readonly pendingEventOrdering: PendingEventOrdering;

public initialEventsFetched = !Thread.hasServerSideSupport;

Expand All @@ -109,6 +113,7 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {

this.room = opts.room;
this.client = opts.client;
this.pendingEventOrdering = opts.pendingEventOrdering ?? PendingEventOrdering.Chronological;
this.timelineSet = new EventTimelineSet(this.room, {
timelineSupport: true,
pendingEvents: true,
Expand Down Expand Up @@ -300,6 +305,19 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
bundledRelationship = this.getRootEventBundledRelationship();
}

let pendingEvents: MatrixEvent[];
if (this.pendingEventOrdering === PendingEventOrdering.Detached) {
pendingEvents = this.room.getPendingEvents()
.filter(ev => ev.isRelation(THREAD_RELATION_TYPE.name) && this.id === ev.threadRootId);
await Promise.all(pendingEvents.map(ev => this.processEvent(ev)));
} else {
pendingEvents = this.events
.filter(ev => ev.isRelation(THREAD_RELATION_TYPE.name))
.filter(ev => ev.status !== EventStatus.SENT && ev.status !== EventStatus.CANCELLED);
}
this.lastPendingEvent = pendingEvents.length ? pendingEvents[pendingEvents.length - 1] : undefined;
this.pendingReplyCount = pendingEvents.length;

if (Thread.hasServerSideSupport && bundledRelationship) {
this.replyCount = bundledRelationship.count;
this._currentUserParticipated = !!bundledRelationship.current_user_participated;
Expand Down Expand Up @@ -393,14 +411,14 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
* exclude annotations from that number
*/
public get length(): number {
return this.replyCount;
return this.replyCount + this.pendingReplyCount;
}

/**
* A getter for the last event added to the thread, if known.
*/
public get replyToEvent(): Optional<MatrixEvent> {
return this.lastEvent ?? this.lastReply();
return this.lastPendingEvent ?? this.lastEvent ?? this.lastReply();
}

public get events(): MatrixEvent[] {
Expand Down

0 comments on commit 7202484

Please sign in to comment.