1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-09 10:22:46 +03:00

Support MSC4157: delayed events via Widget API (#4311)

This commit is contained in:
Andrew Ferrazzutti
2024-08-01 10:17:52 -04:00
committed by GitHub
parent 89a9a7fa38
commit e10c362ef0
6 changed files with 341 additions and 15 deletions

View File

@@ -535,7 +535,7 @@ export const UNSTABLE_MSC2666_SHARED_ROOMS = "uk.half-shot.msc2666";
export const UNSTABLE_MSC2666_MUTUAL_ROOMS = "uk.half-shot.msc2666.mutual_rooms";
export const UNSTABLE_MSC2666_QUERY_MUTUAL_ROOMS = "uk.half-shot.msc2666.query_mutual_rooms";
const UNSTABLE_MSC4140_DELAYED_EVENTS = "org.matrix.msc4140";
export const UNSTABLE_MSC4140_DELAYED_EVENTS = "org.matrix.msc4140";
enum CrossSigningKeyType {
MasterKey = "master_key",

View File

@@ -26,8 +26,13 @@ import {
} from "matrix-widget-api";
import { MatrixEvent, IEvent, IContent, EventStatus } from "./models/event";
import { ISendEventResponse, SendDelayedEventRequestOpts, SendDelayedEventResponse } from "./@types/requests";
import { EventType } from "./@types/event";
import {
ISendEventResponse,
SendDelayedEventRequestOpts,
SendDelayedEventResponse,
UpdateDelayedEventAction,
} from "./@types/requests";
import { EventType, StateEvents } from "./@types/event";
import { logger } from "./logger";
import {
MatrixClient,
@@ -36,6 +41,7 @@ import {
IStartClientOpts,
SendToDeviceContentMap,
IOpenIDToken,
UNSTABLE_MSC4140_DELAYED_EVENTS,
} from "./client";
import { SyncApi, SyncState } from "./sync";
import { SlidingSyncSdk } from "./sliding-sync-sdk";
@@ -95,6 +101,20 @@ export interface ICapabilities {
* @defaultValue false
*/
turnServers?: boolean;
/**
* Whether this client needs to be able to send delayed events.
* @experimental Part of MSC4140 & MSC4157
* @defaultValue false
*/
sendDelayedEvents?: boolean;
/**
* Whether this client needs to be able to update delayed events.
* @experimental Part of MSC4140 & MSC4157
* @defaultValue false
*/
updateDelayedEvents?: boolean;
}
/**
@@ -162,6 +182,18 @@ export class RoomWidgetClient extends MatrixClient {
);
capabilities.sendToDevice?.forEach((eventType) => widgetApi.requestCapabilityToSendToDevice(eventType));
capabilities.receiveToDevice?.forEach((eventType) => widgetApi.requestCapabilityToReceiveToDevice(eventType));
if (
capabilities.sendDelayedEvents &&
(capabilities.sendEvent?.length ||
capabilities.sendMessage === true ||
(Array.isArray(capabilities.sendMessage) && capabilities.sendMessage.length) ||
capabilities.sendState?.length)
) {
widgetApi.requestCapability(MatrixCapabilities.MSC4157SendDelayedEvent);
}
if (capabilities.updateDelayedEvents) {
widgetApi.requestCapability(MatrixCapabilities.MSC4157UpdateDelayedEvent);
}
if (capabilities.turnServers) {
widgetApi.requestCapability(MatrixCapabilities.MSC3846TurnServers);
}
@@ -260,8 +292,17 @@ export class RoomWidgetClient extends MatrixClient {
delayOpts?: SendDelayedEventRequestOpts,
): Promise<ISendEventResponse | SendDelayedEventResponse> {
if (delayOpts) {
throw new Error("Delayed event sending via widgets is not implemented");
// TODO: updatePendingEvent for delayed events?
const response = await this.widgetApi.sendRoomEvent(
event.getType(),
event.getContent(),
room.roomId,
"delay" in delayOpts ? delayOpts.delay : undefined,
"parent_delay_id" in delayOpts ? delayOpts.parent_delay_id : undefined,
);
return this.validateSendDelayedEventResponse(response);
}
let response: ISendEventFromWidgetResponseData;
try {
response = await this.widgetApi.sendRoomEvent(event.getType(), event.getContent(), room.roomId);
@@ -270,6 +311,7 @@ export class RoomWidgetClient extends MatrixClient {
throw e;
}
// This also checks for an event id on the response
room.updatePendingEvent(event, EventStatus.SENT, response.event_id);
return { event_id: response.event_id! };
}
@@ -280,7 +322,56 @@ export class RoomWidgetClient extends MatrixClient {
content: any,
stateKey = "",
): Promise<ISendEventResponse> {
return (await this.widgetApi.sendStateEvent(eventType, stateKey, content, roomId)) as ISendEventResponse;
const response = await this.widgetApi.sendStateEvent(eventType, stateKey, content, roomId);
if (response.event_id === undefined) {
throw new Error("'event_id' absent from response to an event request");
}
return { event_id: response.event_id };
}
/**
* @experimental This currently relies on an unstable MSC (MSC4140).
*/
// eslint-disable-next-line
public async _unstable_sendDelayedStateEvent<K extends keyof StateEvents>(
roomId: string,
delayOpts: SendDelayedEventRequestOpts,
eventType: K,
content: StateEvents[K],
stateKey = "",
): Promise<SendDelayedEventResponse> {
if (!(await this.doesServerSupportUnstableFeature(UNSTABLE_MSC4140_DELAYED_EVENTS))) {
throw Error("Server does not support the delayed events API");
}
const response = await this.widgetApi.sendStateEvent(
eventType,
stateKey,
content,
roomId,
"delay" in delayOpts ? delayOpts.delay : undefined,
"parent_delay_id" in delayOpts ? delayOpts.parent_delay_id : undefined,
);
return this.validateSendDelayedEventResponse(response);
}
private validateSendDelayedEventResponse(response: ISendEventFromWidgetResponseData): SendDelayedEventResponse {
if (response.delay_id === undefined) {
throw new Error("'delay_id' absent from response to a delayed event request");
}
return { delay_id: response.delay_id };
}
/**
* @experimental This currently relies on an unstable MSC (MSC4140).
*/
// eslint-disable-next-line
public async _unstable_updateDelayedEvent(delayId: string, action: UpdateDelayedEventAction): Promise<{}> {
if (!(await this.doesServerSupportUnstableFeature(UNSTABLE_MSC4140_DELAYED_EVENTS))) {
throw Error("Server does not support the delayed events API");
}
return await this.widgetApi.updateDelayedEvent(delayId, action);
}
public async sendToDevice(eventType: string, contentMap: SendToDeviceContentMap): Promise<{}> {