-
-
Notifications
You must be signed in to change notification settings - Fork 609
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Target widget actions at a specific room #2670
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ import { | |
ISendToDeviceToWidgetActionRequest, | ||
} from "matrix-widget-api"; | ||
|
||
import type { IEvent, IContent } from "./models/event"; | ||
import { ISendEventResponse } from "./@types/requests"; | ||
import { EventType } from "./@types/event"; | ||
import { logger } from "./logger"; | ||
|
@@ -69,27 +70,30 @@ export class RoomWidgetClient extends MatrixClient { | |
super(opts); | ||
|
||
// Request capabilities for the functionality this client needs to support | ||
this.capabilities.sendState?.forEach(({ eventType, stateKey }) => | ||
this.widgetApi.requestCapabilityToSendState(eventType, stateKey), | ||
if (capabilities.sendState?.length || capabilities.receiveState?.length) { | ||
widgetApi.requestCapabilityForRoomTimeline(roomId); | ||
} | ||
capabilities.sendState?.forEach(({ eventType, stateKey }) => | ||
widgetApi.requestCapabilityToSendState(eventType, stateKey), | ||
); | ||
this.capabilities.receiveState?.forEach(({ eventType, stateKey }) => | ||
this.widgetApi.requestCapabilityToReceiveState(eventType, stateKey), | ||
capabilities.receiveState?.forEach(({ eventType, stateKey }) => | ||
widgetApi.requestCapabilityToReceiveState(eventType, stateKey), | ||
); | ||
this.capabilities.sendToDevice?.forEach(eventType => | ||
this.widgetApi.requestCapabilityToSendToDevice(eventType), | ||
capabilities.sendToDevice?.forEach(eventType => | ||
widgetApi.requestCapabilityToSendToDevice(eventType), | ||
); | ||
this.capabilities.receiveToDevice?.forEach(eventType => | ||
this.widgetApi.requestCapabilityToReceiveToDevice(eventType), | ||
capabilities.receiveToDevice?.forEach(eventType => | ||
widgetApi.requestCapabilityToReceiveToDevice(eventType), | ||
); | ||
if (this.capabilities.turnServers) { | ||
this.widgetApi.requestCapability(MatrixCapabilities.MSC3846TurnServers); | ||
if (capabilities.turnServers) { | ||
widgetApi.requestCapability(MatrixCapabilities.MSC3846TurnServers); | ||
} | ||
|
||
this.widgetApi.on(`action:${WidgetApiToWidgetAction.SendEvent}`, this.onEvent); | ||
this.widgetApi.on(`action:${WidgetApiToWidgetAction.SendToDevice}`, this.onToDevice); | ||
widgetApi.on(`action:${WidgetApiToWidgetAction.SendEvent}`, this.onEvent); | ||
widgetApi.on(`action:${WidgetApiToWidgetAction.SendToDevice}`, this.onToDevice); | ||
|
||
// Open communication with the host | ||
this.widgetApi.start(); | ||
widgetApi.start(); | ||
} | ||
|
||
public async startClient(opts: IStartClientOpts = {}): Promise<void> { | ||
|
@@ -121,8 +125,8 @@ export class RoomWidgetClient extends MatrixClient { | |
// so it doesn't really matter what order we inject them in | ||
await Promise.all( | ||
this.capabilities.receiveState?.map(async ({ eventType, stateKey }) => { | ||
const rawEvents = await this.widgetApi.readStateEvents(eventType, undefined, stateKey); | ||
const events = rawEvents.map(rawEvent => new MatrixEvent(rawEvent)); | ||
const rawEvents = await this.widgetApi.readStateEvents(eventType, undefined, stateKey, [this.roomId]); | ||
const events = rawEvents.map(rawEvent => new MatrixEvent(rawEvent as Partial<IEvent>)); | ||
|
||
await this.syncApi.injectRoomEvents(this.room, [], events); | ||
events.forEach(event => { | ||
|
@@ -157,8 +161,7 @@ export class RoomWidgetClient extends MatrixClient { | |
content: any, | ||
stateKey = "", | ||
): Promise<ISendEventResponse> { | ||
if (roomId !== this.roomId) throw new Error(`Can't send events to ${roomId}`); | ||
return await this.widgetApi.sendStateEvent(eventType, stateKey, content); | ||
return await this.widgetApi.sendStateEvent(eventType, stateKey, content, roomId); | ||
} | ||
|
||
public async sendToDevice( | ||
|
@@ -215,11 +218,20 @@ export class RoomWidgetClient extends MatrixClient { | |
|
||
private onEvent = async (ev: CustomEvent<ISendEventToWidgetActionRequest>) => { | ||
ev.preventDefault(); | ||
const event = new MatrixEvent(ev.detail.data); | ||
await this.syncApi.injectRoomEvents(this.room, [], [event]); | ||
this.emit(ClientEvent.Event, event); | ||
this.setSyncState(SyncState.Syncing); | ||
logger.info(`Received event ${event.getId()} ${event.getType()} ${event.getStateKey()}`); | ||
|
||
// Verify the room ID matches, since it's possible for the client to | ||
// send us events from other rooms if this widget is always on screen | ||
if (ev.detail.data.room_id === this.roomId) { | ||
const event = new MatrixEvent(ev.detail.data as Partial<IEvent>); | ||
await this.syncApi.injectRoomEvents(this.room, [], [event]); | ||
this.emit(ClientEvent.Event, event); | ||
this.setSyncState(SyncState.Syncing); | ||
logger.info(`Received event ${event.getId()} ${event.getType()} ${event.getStateKey()}`); | ||
} else { | ||
const { event_id: eventId, room_id: roomId } = ev.detail.data; | ||
logger.info(`Received event ${eventId} for a different room ${roomId}; discarding`); | ||
Comment on lines
+231
to
+232
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: I think it might be nicer for this to be in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Returning early would mean that we skip the |
||
} | ||
|
||
await this.ack(ev); | ||
}; | ||
|
||
|
@@ -229,7 +241,7 @@ export class RoomWidgetClient extends MatrixClient { | |
const event = new MatrixEvent({ | ||
type: ev.detail.data.type, | ||
sender: ev.detail.data.sender, | ||
content: ev.detail.data.content, | ||
content: ev.detail.data.content as IContent, | ||
}); | ||
// Mark the event as encrypted if it was, using fake contents and keys since those are unknown to us | ||
if (ev.detail.data.encrypted) event.makeEncrypted(EventType.RoomMessageEncrypted, {}, "", ""); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this necessary now and it wasn't before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the timeline capability is a requirement for accessing a specific room, even if that room is normally what you'd think of as "the current room". The widget API rejects any requests directed at a specific room if the widget doesn't have this capability.