Skip to content

Commit 3b7c657

Browse files
committed
Update delayed events via widget
1 parent c824987 commit 3b7c657

File tree

2 files changed

+81
-14
lines changed

2 files changed

+81
-14
lines changed

spec/unit/embedded.spec.ts

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import {
3232
IOpenIDCredentials,
3333
} from "matrix-widget-api";
3434

35-
import { createRoomWidgetClient, MsgType } from "../../src/matrix";
35+
import { createRoomWidgetClient, MsgType, UpdateDelayedEventAction } from "../../src/matrix";
3636
import { MatrixClient, ClientEvent, ITurnServer as IClientTurnServer } from "../../src/client";
3737
import { SyncState } from "../../src/sync";
3838
import { ICapabilities } from "../../src/embedded";
@@ -78,6 +78,7 @@ class MockWidgetApi extends EventEmitter {
7878
? { event_id: `$${Math.random()}` }
7979
: { delay_id: `id-${Math.random()}` },
8080
);
81+
public updateDelayedEvent = jest.fn();
8182
public sendToDevice = jest.fn();
8283
public requestOpenIDConnectToken = jest.fn(() => {
8384
return testOIDCToken;
@@ -192,9 +193,8 @@ describe("RoomWidgetClient", () => {
192193
});
193194

194195
it("sends delayed message events", async () => {
195-
await makeClient({ sendEvent: ["org.matrix.rageshake_request"] });
196-
expect(widgetApi.requestCapabilityForRoomTimeline).toHaveBeenCalledWith("!1:example.org");
197-
expect(widgetApi.requestCapabilityToSendEvent).toHaveBeenCalledWith("org.matrix.rageshake_request");
196+
await makeClient({ sendDelayedEvents: true, sendEvent: ["org.matrix.rageshake_request"] });
197+
expect(widgetApi.requestCapability).toHaveBeenCalledWith(MatrixCapabilities.MSC4157SendDelayedEvent);
198198
await client._unstable_sendDelayedEvent(
199199
"!1:example.org",
200200
{ delay: 2000 },
@@ -212,9 +212,8 @@ describe("RoomWidgetClient", () => {
212212
});
213213

214214
it("sends child action delayed message events", async () => {
215-
await makeClient({ sendEvent: ["org.matrix.rageshake_request"] });
216-
expect(widgetApi.requestCapabilityForRoomTimeline).toHaveBeenCalledWith("!1:example.org");
217-
expect(widgetApi.requestCapabilityToSendEvent).toHaveBeenCalledWith("org.matrix.rageshake_request");
215+
await makeClient({ sendDelayedEvents: true, sendEvent: ["org.matrix.rageshake_request"] });
216+
expect(widgetApi.requestCapability).toHaveBeenCalledWith(MatrixCapabilities.MSC4157SendDelayedEvent);
218217
const parentDelayId = `id-${Math.random()}`;
219218
await client._unstable_sendDelayedEvent(
220219
"!1:example.org",
@@ -233,9 +232,8 @@ describe("RoomWidgetClient", () => {
233232
});
234233

235234
it("sends delayed state events", async () => {
236-
await makeClient({ sendState: [{ eventType: "org.example.foo", stateKey: "bar" }] });
237-
expect(widgetApi.requestCapabilityForRoomTimeline).toHaveBeenCalledWith("!1:example.org");
238-
expect(widgetApi.requestCapabilityToSendState).toHaveBeenCalledWith("org.example.foo", "bar");
235+
await makeClient({ sendDelayedEvents: true, sendState: [{ eventType: "org.example.foo", stateKey: "bar" }] });
236+
expect(widgetApi.requestCapability).toHaveBeenCalledWith(MatrixCapabilities.MSC4157SendDelayedEvent);
239237
await client._unstable_sendDelayedStateEvent(
240238
"!1:example.org",
241239
{ delay: 2000 },
@@ -254,9 +252,8 @@ describe("RoomWidgetClient", () => {
254252
});
255253

256254
it("sends child action delayed state events", async () => {
257-
await makeClient({ sendState: [{ eventType: "org.example.foo", stateKey: "bar" }] });
258-
expect(widgetApi.requestCapabilityForRoomTimeline).toHaveBeenCalledWith("!1:example.org");
259-
expect(widgetApi.requestCapabilityToSendState).toHaveBeenCalledWith("org.example.foo", "bar");
255+
await makeClient({ sendDelayedEvents: true, sendState: [{ eventType: "org.example.foo", stateKey: "bar" }] });
256+
expect(widgetApi.requestCapability).toHaveBeenCalledWith(MatrixCapabilities.MSC4157SendDelayedEvent);
260257
const parentDelayId = `fg-${Math.random()}`;
261258
await client._unstable_sendDelayedStateEvent(
262259
"!1:example.org",
@@ -274,6 +271,19 @@ describe("RoomWidgetClient", () => {
274271
parentDelayId,
275272
);
276273
});
274+
275+
it("updates delayed events", async () => {
276+
await makeClient({ updateDelayedEvents: true, sendEvent: ["org.matrix.rageshake_request"] });
277+
expect(widgetApi.requestCapability).toHaveBeenCalledWith(MatrixCapabilities.MSC4157UpdateDelayedEvent);
278+
for (const action of [
279+
UpdateDelayedEventAction.Cancel,
280+
UpdateDelayedEventAction.Restart,
281+
UpdateDelayedEventAction.Send,
282+
]) {
283+
await client._unstable_updateDelayedEvent("id", action);
284+
expect(widgetApi.updateDelayedEvent).toHaveBeenCalledWith("id", action);
285+
}
286+
});
277287
});
278288

279289
describe("when unsupported", () => {
@@ -302,6 +312,19 @@ describe("RoomWidgetClient", () => {
302312
),
303313
).rejects.toThrow("Server does not support");
304314
});
315+
316+
it("fails to update delayed state events", async () => {
317+
await makeClient({});
318+
for (const action of [
319+
UpdateDelayedEventAction.Cancel,
320+
UpdateDelayedEventAction.Restart,
321+
UpdateDelayedEventAction.Send,
322+
]) {
323+
await expect(
324+
client._unstable_updateDelayedEvent("id", action),
325+
).rejects.toThrow("Server does not support");
326+
}
327+
});
305328
});
306329
});
307330

src/embedded.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ import {
2626
} from "matrix-widget-api";
2727

2828
import { MatrixEvent, IEvent, IContent, EventStatus } from "./models/event";
29-
import { ISendEventResponse, SendDelayedEventRequestOpts, SendDelayedEventResponse } from "./@types/requests";
29+
import {
30+
ISendEventResponse,
31+
SendDelayedEventRequestOpts,
32+
SendDelayedEventResponse,
33+
UpdateDelayedEventAction,
34+
} from "./@types/requests";
3035
import { EventType, StateEvents } from "./@types/event";
3136
import { logger } from "./logger";
3237
import {
@@ -96,6 +101,20 @@ export interface ICapabilities {
96101
* @defaultValue false
97102
*/
98103
turnServers?: boolean;
104+
105+
/**
106+
* Whether this client needs to be able to send delayed events.
107+
* @experimental Part of MSC4140 & MSC4157
108+
* @defaultValue false
109+
*/
110+
sendDelayedEvents?: boolean;
111+
112+
/**
113+
* Whether this client needs to be able to update delayed events.
114+
* @experimental Part of MSC4140 & MSC4157
115+
* @defaultValue false
116+
*/
117+
updateDelayedEvents?: boolean;
99118
}
100119

101120
/**
@@ -163,6 +182,19 @@ export class RoomWidgetClient extends MatrixClient {
163182
);
164183
capabilities.sendToDevice?.forEach((eventType) => widgetApi.requestCapabilityToSendToDevice(eventType));
165184
capabilities.receiveToDevice?.forEach((eventType) => widgetApi.requestCapabilityToReceiveToDevice(eventType));
185+
if (
186+
capabilities.sendDelayedEvents && (
187+
capabilities.sendEvent?.length ||
188+
capabilities.sendMessage === true ||
189+
(Array.isArray(capabilities.sendMessage) && capabilities.sendMessage.length) ||
190+
capabilities.sendState?.length
191+
)
192+
) {
193+
widgetApi.requestCapability(MatrixCapabilities.MSC4157SendDelayedEvent);
194+
}
195+
if (capabilities.updateDelayedEvents) {
196+
widgetApi.requestCapability(MatrixCapabilities.MSC4157UpdateDelayedEvent);
197+
}
166198
if (capabilities.turnServers) {
167199
widgetApi.requestCapability(MatrixCapabilities.MSC3846TurnServers);
168200
}
@@ -320,6 +352,18 @@ export class RoomWidgetClient extends MatrixClient {
320352
return this.validateSendDelayedEventResponse(response);
321353
}
322354

355+
/**
356+
* @experimental This currently relies on an unstable MSC (MSC4140).
357+
*/
358+
// eslint-disable-next-line
359+
public async _unstable_updateDelayedEvent(delayId: string, action: UpdateDelayedEventAction): Promise<{}> {
360+
if (!(await this.doesServerSupportUnstableFeature(UNSTABLE_MSC4140_DELAYED_EVENTS))) {
361+
throw Error("Server does not support the delayed events API");
362+
}
363+
364+
return await this.widgetApi.updateDelayedEvent(delayId, action);
365+
}
366+
323367
private validateSendEventResponse(response: ISendEventFromWidgetResponseData): ISendEventResponse {
324368
if (response.event_id === undefined) {
325369
throw new Error("'event_id' absent from response to an event request");

0 commit comments

Comments
 (0)