Show the local echo in previews (#12451)
* show the local echo in previews * a bit more coverage
This commit is contained in:
parent
158e1110b1
commit
644bf78e2a
2 changed files with 114 additions and 4 deletions
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Room, RelationType, MatrixEvent, Thread, M_POLL_START } from "matrix-js-sdk/src/matrix";
|
import { Room, RelationType, MatrixEvent, Thread, M_POLL_START, RoomEvent } from "matrix-js-sdk/src/matrix";
|
||||||
import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
|
import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
import { ActionPayload } from "../../dispatcher/payloads";
|
import { ActionPayload } from "../../dispatcher/payloads";
|
||||||
|
@ -186,7 +186,7 @@ export class MessagePreviewStore extends AsyncStoreWithClient<IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async generatePreview(room: Room, tagId?: TagID): Promise<void> {
|
private async generatePreview(room: Room, tagId?: TagID): Promise<void> {
|
||||||
const events = [...room.getLiveTimeline().getEvents()];
|
const events = [...room.getLiveTimeline().getEvents(), ...room.getPendingEvents()];
|
||||||
|
|
||||||
// add last reply from each thread
|
// add last reply from each thread
|
||||||
room.getThreads().forEach((thread: Thread): void => {
|
room.getThreads().forEach((thread: Thread): void => {
|
||||||
|
@ -279,4 +279,19 @@ export class MessagePreviewStore extends AsyncStoreWithClient<IState> {
|
||||||
await this.generatePreview(room, TAG_ANY);
|
await this.generatePreview(room, TAG_ANY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async onReady(): Promise<void> {
|
||||||
|
if (!this.matrixClient) return;
|
||||||
|
this.matrixClient.on(RoomEvent.LocalEchoUpdated, this.onLocalEchoUpdated);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async onNotReady(): Promise<void> {
|
||||||
|
if (!this.matrixClient) return;
|
||||||
|
this.matrixClient.off(RoomEvent.LocalEchoUpdated, this.onLocalEchoUpdated);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onLocalEchoUpdated = async (ev: MatrixEvent, room: Room): Promise<void> => {
|
||||||
|
if (!this.previews.has(room.roomId)) return;
|
||||||
|
await this.generatePreview(room, TAG_ANY);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,16 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Mocked, mocked } from "jest-mock";
|
import { Mocked, mocked } from "jest-mock";
|
||||||
import { EventTimeline, EventType, MatrixClient, MatrixEvent, RelationType, Room } from "matrix-js-sdk/src/matrix";
|
import {
|
||||||
|
EventStatus,
|
||||||
|
EventTimeline,
|
||||||
|
EventType,
|
||||||
|
MatrixClient,
|
||||||
|
MatrixEvent,
|
||||||
|
PendingEventOrdering,
|
||||||
|
RelationType,
|
||||||
|
Room,
|
||||||
|
} from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
import { MessagePreviewStore } from "../../../src/stores/room-list/MessagePreviewStore";
|
import { MessagePreviewStore } from "../../../src/stores/room-list/MessagePreviewStore";
|
||||||
import { mkEvent, mkMessage, mkReaction, setupAsyncStoreWithClient, stubClient } from "../../test-utils";
|
import { mkEvent, mkMessage, mkReaction, setupAsyncStoreWithClient, stubClient } from "../../test-utils";
|
||||||
|
@ -25,6 +34,7 @@ import { mkThread } from "../../test-utils/threads";
|
||||||
describe("MessagePreviewStore", () => {
|
describe("MessagePreviewStore", () => {
|
||||||
let client: Mocked<MatrixClient>;
|
let client: Mocked<MatrixClient>;
|
||||||
let room: Room;
|
let room: Room;
|
||||||
|
let nonRenderedRoom: Room;
|
||||||
let store: MessagePreviewStore;
|
let store: MessagePreviewStore;
|
||||||
|
|
||||||
async function addEvent(
|
async function addEvent(
|
||||||
|
@ -46,9 +56,35 @@ describe("MessagePreviewStore", () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function addPendingEvent(
|
||||||
|
store: MessagePreviewStore,
|
||||||
|
room: Room,
|
||||||
|
event: MatrixEvent,
|
||||||
|
fireAction = true,
|
||||||
|
): Promise<void> {
|
||||||
|
room.addPendingEvent(event, "txid");
|
||||||
|
if (fireAction) {
|
||||||
|
// @ts-ignore private access
|
||||||
|
await store.onLocalEchoUpdated(event, room);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updatePendingEvent(event: MatrixEvent, eventStatus: EventStatus, fireAction = true): Promise<void> {
|
||||||
|
room.updatePendingEvent(event, eventStatus);
|
||||||
|
if (fireAction) {
|
||||||
|
// @ts-ignore private access
|
||||||
|
await store.onLocalEchoUpdated(event, room);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
client = mocked(stubClient());
|
client = mocked(stubClient());
|
||||||
room = new Room("!roomId:server", client, client.getSafeUserId());
|
room = new Room("!roomId:server", client, client.getSafeUserId(), {
|
||||||
|
pendingEventOrdering: PendingEventOrdering.Detached,
|
||||||
|
});
|
||||||
|
nonRenderedRoom = new Room("!roomId2:server", client, client.getSafeUserId(), {
|
||||||
|
pendingEventOrdering: PendingEventOrdering.Detached,
|
||||||
|
});
|
||||||
mocked(client.getRoom).mockReturnValue(room);
|
mocked(client.getRoom).mockReturnValue(room);
|
||||||
|
|
||||||
store = MessagePreviewStore.testInstance();
|
store = MessagePreviewStore.testInstance();
|
||||||
|
@ -286,4 +322,63 @@ describe("MessagePreviewStore", () => {
|
||||||
expect(preview?.isThreadReply).toBe(false);
|
expect(preview?.isThreadReply).toBe(false);
|
||||||
expect(preview?.text).toContain("You reacted 🙃 to root event message");
|
expect(preview?.text).toContain("You reacted 🙃 to root event message");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should handle local echos correctly", async () => {
|
||||||
|
const firstMessage = mkMessage({
|
||||||
|
user: "@sender:server",
|
||||||
|
event: true,
|
||||||
|
room: room.roomId,
|
||||||
|
msg: "First message",
|
||||||
|
});
|
||||||
|
|
||||||
|
await addEvent(store, room, firstMessage);
|
||||||
|
|
||||||
|
expect((await store.getPreviewForRoom(room, DefaultTagID.Untagged))?.text).toMatchInlineSnapshot(
|
||||||
|
`"@sender:server: First message"`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const secondMessage = mkMessage({
|
||||||
|
user: "@sender:server",
|
||||||
|
event: true,
|
||||||
|
room: room.roomId,
|
||||||
|
msg: "Second message",
|
||||||
|
});
|
||||||
|
secondMessage.status = EventStatus.NOT_SENT;
|
||||||
|
|
||||||
|
await addPendingEvent(store, room, secondMessage);
|
||||||
|
|
||||||
|
expect((await store.getPreviewForRoom(room, DefaultTagID.Untagged))?.text).toMatchInlineSnapshot(
|
||||||
|
`"@sender:server: Second message"`,
|
||||||
|
);
|
||||||
|
|
||||||
|
await updatePendingEvent(secondMessage, EventStatus.CANCELLED);
|
||||||
|
|
||||||
|
expect((await store.getPreviewForRoom(room, DefaultTagID.Untagged))?.text).toMatchInlineSnapshot(
|
||||||
|
`"@sender:server: First message"`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not generate previews for rooms not rendered", async () => {
|
||||||
|
const firstMessage = mkMessage({
|
||||||
|
user: "@sender:server",
|
||||||
|
event: true,
|
||||||
|
room: nonRenderedRoom.roomId,
|
||||||
|
msg: "First message",
|
||||||
|
});
|
||||||
|
|
||||||
|
await addEvent(store, room, firstMessage);
|
||||||
|
|
||||||
|
const secondMessage = mkMessage({
|
||||||
|
user: "@sender:server",
|
||||||
|
event: true,
|
||||||
|
room: nonRenderedRoom.roomId,
|
||||||
|
msg: "Second message",
|
||||||
|
});
|
||||||
|
secondMessage.status = EventStatus.NOT_SENT;
|
||||||
|
|
||||||
|
await addPendingEvent(store, room, secondMessage);
|
||||||
|
|
||||||
|
// @ts-ignore private access
|
||||||
|
expect(store.previews.has(nonRenderedRoom.roomId)).toBeFalsy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue