Update StopGapWidgetDriver to support sticky events (#31205)
* Update StopGapWidgetDriver to support sticky events * Update to-device * Update tests * Clean up duplication * lint * yarn lock
This commit is contained in:
@@ -39,6 +39,8 @@ import {
|
||||
type SendDelayedEventResponse,
|
||||
type StateEvents,
|
||||
type TimelineEvents,
|
||||
type SendDelayedEventRequestOpts,
|
||||
type MatrixClient,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import {
|
||||
@@ -122,6 +124,7 @@ export class ElementWidgetDriver extends WidgetDriver {
|
||||
this.allowedCapabilities.add(`org.matrix.msc2762.timeline:${inRoomId}`);
|
||||
this.allowedCapabilities.add(MatrixCapabilities.MSC4157SendDelayedEvent);
|
||||
this.allowedCapabilities.add(MatrixCapabilities.MSC4157UpdateDelayedEvent);
|
||||
this.allowedCapabilities.add(MatrixCapabilities.MSC4354SendStickyEvent);
|
||||
|
||||
this.allowedCapabilities.add(
|
||||
WidgetEventCapability.forStateEvent(EventDirection.Receive, EventType.RoomName).raw,
|
||||
@@ -288,6 +291,13 @@ export class ElementWidgetDriver extends WidgetDriver {
|
||||
return allAllowed;
|
||||
}
|
||||
|
||||
private getSendEventTarget(roomId: string | null = null): { client: MatrixClient; roomId: string } {
|
||||
const client = MatrixClientPeg.safeGet();
|
||||
roomId = roomId || SdkContextClass.instance.roomViewStore.getRoomId() || null;
|
||||
if (!roomId) throw new Error("No room specified and no room in RoomViewStore focus.");
|
||||
return { client, roomId };
|
||||
}
|
||||
|
||||
public async sendEvent<K extends keyof StateEvents>(
|
||||
eventType: K,
|
||||
content: StateEvents[K],
|
||||
@@ -306,10 +316,7 @@ export class ElementWidgetDriver extends WidgetDriver {
|
||||
stateKey: string | null = null,
|
||||
targetRoomId: string | null = null,
|
||||
): Promise<ISendEventDetails> {
|
||||
const client = MatrixClientPeg.get();
|
||||
const roomId = targetRoomId || SdkContextClass.instance.roomViewStore.getRoomId();
|
||||
|
||||
if (!client || !roomId) throw new Error("Not in a room or not attached to a client");
|
||||
const { client, roomId } = this.getSendEventTarget(targetRoomId);
|
||||
|
||||
let r: { event_id: string } | null;
|
||||
if (stateKey !== null) {
|
||||
@@ -348,6 +355,42 @@ export class ElementWidgetDriver extends WidgetDriver {
|
||||
return { roomId, eventId: r.event_id };
|
||||
}
|
||||
|
||||
/**
|
||||
* @experimental Part of MSC4354
|
||||
* @see {@link WidgetDriver#sendStickyEvent}
|
||||
*/
|
||||
public async sendStickyEvent(
|
||||
stickyDurationMs: number,
|
||||
eventType: string,
|
||||
content: unknown,
|
||||
targetRoomId?: string | null,
|
||||
): Promise<ISendEventDetails> {
|
||||
const { client, roomId } = this.getSendEventTarget(targetRoomId);
|
||||
|
||||
const r = await client._unstable_sendStickyEvent(
|
||||
roomId,
|
||||
stickyDurationMs,
|
||||
null,
|
||||
eventType as keyof TimelineEvents,
|
||||
content as TimelineEvents[keyof TimelineEvents] & { msc4354_sticky_key: string },
|
||||
);
|
||||
return { roomId, eventId: r.event_id };
|
||||
}
|
||||
|
||||
private getSendDelayedEventOpts(delay: number | null, parentDelayId: string | null): SendDelayedEventRequestOpts {
|
||||
if (delay !== null) {
|
||||
return {
|
||||
delay,
|
||||
...(parentDelayId !== null && { parent_delay_id: parentDelayId }),
|
||||
};
|
||||
} else if (parentDelayId !== null) {
|
||||
return {
|
||||
parent_delay_id: parentDelayId,
|
||||
};
|
||||
}
|
||||
throw new Error("Must provide at least one of delay or parentDelayId");
|
||||
}
|
||||
|
||||
/**
|
||||
* @experimental Part of MSC4140 & MSC4157
|
||||
* @see {@link WidgetDriver#sendDelayedEvent}
|
||||
@@ -379,24 +422,8 @@ export class ElementWidgetDriver extends WidgetDriver {
|
||||
stateKey: string | null = null,
|
||||
targetRoomId: string | null = null,
|
||||
): Promise<ISendDelayedEventDetails> {
|
||||
const client = MatrixClientPeg.get();
|
||||
const roomId = targetRoomId || SdkContextClass.instance.roomViewStore.getRoomId();
|
||||
|
||||
if (!client || !roomId) throw new Error("Not in a room or not attached to a client");
|
||||
|
||||
let delayOpts;
|
||||
if (delay !== null) {
|
||||
delayOpts = {
|
||||
delay,
|
||||
...(parentDelayId !== null && { parent_delay_id: parentDelayId }),
|
||||
};
|
||||
} else if (parentDelayId !== null) {
|
||||
delayOpts = {
|
||||
parent_delay_id: parentDelayId,
|
||||
};
|
||||
} else {
|
||||
throw new Error("Must provide at least one of delay or parentDelayId");
|
||||
}
|
||||
const { client, roomId } = this.getSendEventTarget(targetRoomId);
|
||||
const delayOpts = this.getSendDelayedEventOpts(delay, parentDelayId);
|
||||
|
||||
let r: SendDelayedEventResponse | null;
|
||||
if (stateKey !== null) {
|
||||
@@ -425,13 +452,39 @@ export class ElementWidgetDriver extends WidgetDriver {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @experimental Part of MSC4354
|
||||
* @see {@link WidgetDriver#sendStickyEvent}
|
||||
*/
|
||||
public async sendDelayedStickyEvent(
|
||||
delay: number | null,
|
||||
parentDelayId: string | null,
|
||||
stickyDurationMs: number,
|
||||
eventType: string,
|
||||
content: unknown,
|
||||
targetRoomId?: string | null,
|
||||
): Promise<ISendDelayedEventDetails> {
|
||||
const { client, roomId } = this.getSendEventTarget(targetRoomId);
|
||||
const delayOpts = this.getSendDelayedEventOpts(delay, parentDelayId);
|
||||
|
||||
const r = await client._unstable_sendStickyDelayedEvent(
|
||||
roomId,
|
||||
stickyDurationMs,
|
||||
delayOpts,
|
||||
null,
|
||||
eventType as keyof TimelineEvents,
|
||||
content as TimelineEvents[keyof TimelineEvents] & { msc4354_sticky_key: string },
|
||||
);
|
||||
return { roomId, delayId: r.delay_id };
|
||||
}
|
||||
|
||||
/**
|
||||
* @experimental Part of MSC4140 & MSC4157
|
||||
*/
|
||||
public async cancelScheduledDelayedEvent(delayId: string): Promise<void> {
|
||||
const client = MatrixClientPeg.get();
|
||||
|
||||
if (!client) throw new Error("Not in a room or not attached to a client");
|
||||
if (!client) throw new Error("Not attached to a client");
|
||||
|
||||
await client._unstable_cancelScheduledDelayedEvent(delayId);
|
||||
}
|
||||
@@ -442,7 +495,7 @@ export class ElementWidgetDriver extends WidgetDriver {
|
||||
public async restartScheduledDelayedEvent(delayId: string): Promise<void> {
|
||||
const client = MatrixClientPeg.get();
|
||||
|
||||
if (!client) throw new Error("Not in a room or not attached to a client");
|
||||
if (!client) throw new Error("Not attached to a client");
|
||||
|
||||
await client._unstable_restartScheduledDelayedEvent(delayId);
|
||||
}
|
||||
@@ -453,7 +506,7 @@ export class ElementWidgetDriver extends WidgetDriver {
|
||||
public async sendScheduledDelayedEvent(delayId: string): Promise<void> {
|
||||
const client = MatrixClientPeg.get();
|
||||
|
||||
if (!client) throw new Error("Not in a room or not attached to a client");
|
||||
if (!client) throw new Error("Not attached to a client");
|
||||
|
||||
await client._unstable_sendScheduledDelayedEvent(delayId);
|
||||
}
|
||||
|
||||
@@ -540,10 +540,8 @@ export class WidgetMessaging extends TypedEventEmitter<WidgetMessagingEvent, Wid
|
||||
});
|
||||
};
|
||||
|
||||
private onToDeviceMessage = async (payload: ReceivedToDeviceMessage): Promise<void> => {
|
||||
const { message, encryptionInfo } = payload;
|
||||
// TODO: Update the widget API to use a proper IToDeviceMessage instead of a IRoomEvent
|
||||
await this.widgetApi?.feedToDevice(message as IRoomEvent, encryptionInfo != null);
|
||||
private onToDeviceMessage = async ({ message, encryptionInfo }: ReceivedToDeviceMessage): Promise<void> => {
|
||||
await this.widgetApi?.feedToDevice(message, encryptionInfo != null);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user