You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-07-31 15:24:23 +03:00
Include pending events in thread summary and count again (#2922)
* Include pending events in thread summary and count again * Pass through pending event status
This commit is contained in:
committed by
GitHub
parent
43bfa0c020
commit
720248466f
@ -14,11 +14,13 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { MatrixClient } from "../../../src/client";
|
import { MatrixClient, PendingEventOrdering } from "../../../src/client";
|
||||||
import { Room } from "../../../src/models/room";
|
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 { mkThread } from "../../test-utils/thread";
|
||||||
import { TestClient } from "../../TestClient";
|
import { TestClient } from "../../TestClient";
|
||||||
|
import { emitPromise, mkMessage } from "../../test-utils/test-utils";
|
||||||
|
import { EventStatus } from "../../../src";
|
||||||
|
|
||||||
describe('Thread', () => {
|
describe('Thread', () => {
|
||||||
describe("constructor", () => {
|
describe("constructor", () => {
|
||||||
@ -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", () => {
|
describe("hasUserReadEvent", () => {
|
||||||
const myUserId = "@bob:example.org";
|
const myUserId = "@bob:example.org";
|
||||||
let client: MatrixClient;
|
let client: MatrixClient;
|
||||||
|
@ -2017,6 +2017,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
|
|||||||
const thread = new Thread(threadId, rootEvent, {
|
const thread = new Thread(threadId, rootEvent, {
|
||||||
room: this,
|
room: this,
|
||||||
client: this.client,
|
client: this.client,
|
||||||
|
pendingEventOrdering: this.opts.pendingEventOrdering,
|
||||||
});
|
});
|
||||||
|
|
||||||
// This is necessary to be able to jump to events in threads:
|
// This is necessary to be able to jump to events in threads:
|
||||||
|
@ -16,10 +16,10 @@ limitations under the License.
|
|||||||
|
|
||||||
import { Optional } from "matrix-events-sdk";
|
import { Optional } from "matrix-events-sdk";
|
||||||
|
|
||||||
import { MatrixClient } from "../client";
|
import { MatrixClient, PendingEventOrdering } from "../client";
|
||||||
import { TypedReEmitter } from "../ReEmitter";
|
import { TypedReEmitter } from "../ReEmitter";
|
||||||
import { RelationType } from "../@types/event";
|
import { RelationType } from "../@types/event";
|
||||||
import { IThreadBundledRelationship, MatrixEvent, MatrixEventEvent } from "./event";
|
import { EventStatus, IThreadBundledRelationship, MatrixEvent, MatrixEventEvent } from "./event";
|
||||||
import { EventTimeline } from "./event-timeline";
|
import { EventTimeline } from "./event-timeline";
|
||||||
import { EventTimelineSet, EventTimelineSetHandlerMap } from './event-timeline-set';
|
import { EventTimelineSet, EventTimelineSetHandlerMap } from './event-timeline-set';
|
||||||
import { NotificationCountType, Room, RoomEvent } from './room';
|
import { NotificationCountType, Room, RoomEvent } from './room';
|
||||||
@ -51,6 +51,7 @@ export type EventHandlerMap = {
|
|||||||
interface IThreadOpts {
|
interface IThreadOpts {
|
||||||
room: Room;
|
room: Room;
|
||||||
client: MatrixClient;
|
client: MatrixClient;
|
||||||
|
pendingEventOrdering?: PendingEventOrdering;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum FeatureSupport {
|
export enum FeatureSupport {
|
||||||
@ -88,9 +89,12 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
|
|||||||
|
|
||||||
private lastEvent: MatrixEvent | undefined;
|
private lastEvent: MatrixEvent | undefined;
|
||||||
private replyCount = 0;
|
private replyCount = 0;
|
||||||
|
private lastPendingEvent: MatrixEvent | undefined;
|
||||||
|
private pendingReplyCount = 0;
|
||||||
|
|
||||||
public readonly room: Room;
|
public readonly room: Room;
|
||||||
public readonly client: MatrixClient;
|
public readonly client: MatrixClient;
|
||||||
|
private readonly pendingEventOrdering: PendingEventOrdering;
|
||||||
|
|
||||||
public initialEventsFetched = !Thread.hasServerSideSupport;
|
public initialEventsFetched = !Thread.hasServerSideSupport;
|
||||||
|
|
||||||
@ -109,6 +113,7 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
|
|||||||
|
|
||||||
this.room = opts.room;
|
this.room = opts.room;
|
||||||
this.client = opts.client;
|
this.client = opts.client;
|
||||||
|
this.pendingEventOrdering = opts.pendingEventOrdering ?? PendingEventOrdering.Chronological;
|
||||||
this.timelineSet = new EventTimelineSet(this.room, {
|
this.timelineSet = new EventTimelineSet(this.room, {
|
||||||
timelineSupport: true,
|
timelineSupport: true,
|
||||||
pendingEvents: true,
|
pendingEvents: true,
|
||||||
@ -300,6 +305,19 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
|
|||||||
bundledRelationship = this.getRootEventBundledRelationship();
|
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) {
|
if (Thread.hasServerSideSupport && bundledRelationship) {
|
||||||
this.replyCount = bundledRelationship.count;
|
this.replyCount = bundledRelationship.count;
|
||||||
this._currentUserParticipated = !!bundledRelationship.current_user_participated;
|
this._currentUserParticipated = !!bundledRelationship.current_user_participated;
|
||||||
@ -393,14 +411,14 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
|
|||||||
* exclude annotations from that number
|
* exclude annotations from that number
|
||||||
*/
|
*/
|
||||||
public get length(): 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.
|
* A getter for the last event added to the thread, if known.
|
||||||
*/
|
*/
|
||||||
public get replyToEvent(): Optional<MatrixEvent> {
|
public get replyToEvent(): Optional<MatrixEvent> {
|
||||||
return this.lastEvent ?? this.lastReply();
|
return this.lastPendingEvent ?? this.lastEvent ?? this.lastReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public get events(): MatrixEvent[] {
|
public get events(): MatrixEvent[] {
|
||||||
|
Reference in New Issue
Block a user