diff --git a/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx b/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx
index ebeab191b1..556dc057f9 100644
--- a/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx
+++ b/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx
@@ -1,5 +1,5 @@
/*
-Copyright 2020 The Matrix.org Foundation C.I.C.
+Copyright 2020 - 2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import { _t } from "../../../languageHandler";
import { IDialogProps } from "./IDialogProps";
import {
Capability,
+ isTimelineCapability,
Widget,
WidgetEventCapability,
WidgetKind,
@@ -30,6 +31,7 @@ import DialogButtons from "../elements/DialogButtons";
import LabelledToggleSwitch from "../elements/LabelledToggleSwitch";
import { CapabilityText } from "../../../widgets/CapabilityText";
import { replaceableComponent } from "../../../utils/replaceableComponent";
+import { lexicographicCompare } from "matrix-js-sdk/src/utils";
export function getRememberedCapabilitiesForWidget(widget: Widget): Capability[] {
return JSON.parse(localStorage.getItem(`widget_${widget.id}_approved_caps`) || "[]");
@@ -102,7 +104,20 @@ export default class WidgetCapabilitiesPromptDialog extends React.PureComponent<
}
public render() {
- const checkboxRows = Object.entries(this.state.booleanStates).map(([cap, isChecked], i) => {
+ // We specifically order the timeline capabilities down to the bottom. The capability text
+ // generation cares strongly about this.
+ const orderedCapabilities = Object.entries(this.state.booleanStates).sort(([capA], [capB]) => {
+ const isTimelineA = isTimelineCapability(capA);
+ const isTimelineB = isTimelineCapability(capB);
+
+ if (!isTimelineA && !isTimelineB) return lexicographicCompare(capA, capB);
+ if (isTimelineA && !isTimelineB) return 1;
+ if (!isTimelineA && isTimelineB) return -1;
+ if (isTimelineA && isTimelineB) return lexicographicCompare(capA, capB);
+
+ return 0;
+ });
+ const checkboxRows = orderedCapabilities.map(([cap, isChecked], i) => {
const text = CapabilityText.for(cap, this.props.widgetKind);
const byline = text.byline
? { text.byline }
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 21859fb1aa..3b67db374c 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -604,6 +604,8 @@
"See when anyone posts a sticker to your active room": "See when anyone posts a sticker to your active room",
"with an empty state key": "with an empty state key",
"with state key %(stateKey)s": "with state key %(stateKey)s",
+ "The above, but in any room you are joined or invited to as well": "The above, but in any room you are joined or invited to as well",
+ "The above, but in as well": "The above, but in as well",
"Send %(eventType)s events as you in this room": "Send %(eventType)s events as you in this room",
"See %(eventType)s events posted to this room": "See %(eventType)s events posted to this room",
"Send %(eventType)s events as you in your active room": "Send %(eventType)s events as you in your active room",
diff --git a/src/stores/widgets/StopGapWidget.ts b/src/stores/widgets/StopGapWidget.ts
index daa1e0e787..49653626c1 100644
--- a/src/stores/widgets/StopGapWidget.ts
+++ b/src/stores/widgets/StopGapWidget.ts
@@ -1,5 +1,5 @@
/*
- * Copyright 2020, 2021 The Matrix.org Foundation C.I.C.
+ * Copyright 2020 - 2021 The Matrix.org Foundation C.I.C.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -408,13 +408,11 @@ export class StopGapWidget extends EventEmitter {
private onEvent = (ev: MatrixEvent) => {
MatrixClientPeg.get().decryptEventIfNeeded(ev);
if (ev.isBeingDecrypted() || ev.isDecryptionFailure()) return;
- if (ev.getRoomId() !== this.eventListenerRoomId) return;
this.feedEvent(ev);
};
private onEventDecrypted = (ev: MatrixEvent) => {
if (ev.isDecryptionFailure()) return;
- if (ev.getRoomId() !== this.eventListenerRoomId) return;
this.feedEvent(ev);
};
@@ -422,7 +420,7 @@ export class StopGapWidget extends EventEmitter {
if (!this.messaging) return;
const raw = ev.getEffectiveEvent();
- this.messaging.feedEvent(raw).catch(e => {
+ this.messaging.feedEvent(raw, this.eventListenerRoomId).catch(e => {
console.error("Error sending event to widget: ", e);
});
}
diff --git a/src/stores/widgets/StopGapWidgetDriver.ts b/src/stores/widgets/StopGapWidgetDriver.ts
index 13cd260ef0..78d7c9ede0 100644
--- a/src/stores/widgets/StopGapWidgetDriver.ts
+++ b/src/stores/widgets/StopGapWidgetDriver.ts
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Matrix.org Foundation C.I.C.
+ * Copyright 2020 - 2021 The Matrix.org Foundation C.I.C.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import {
MatrixCapabilities,
OpenIDRequestState,
SimpleObservable,
+ Symbols,
Widget,
WidgetDriver,
WidgetEventCapability,
@@ -44,7 +45,8 @@ import { CHAT_EFFECTS } from "../../effects";
import { containsEmoji } from "../../effects/utils";
import dis from "../../dispatcher/dispatcher";
import { tryTransformPermalinkToLocalHref } from "../../utils/permalinks/Permalinks";
-import { MatrixEvent } from "matrix-js-sdk/src/models/event";
+import { IEvent, MatrixEvent } from "matrix-js-sdk/src/models/event";
+import { Room } from "matrix-js-sdk";
// TODO: Purge this from the universe
@@ -119,9 +121,9 @@ export class StopGapWidgetDriver extends WidgetDriver {
return new Set(iterableUnion(allowedSoFar, requested));
}
- public async sendEvent(eventType: string, content: any, stateKey: string = null): Promise {
+ public async sendEvent(eventType: string, content: any, stateKey: string = null, targetRoomId: string = null): Promise {
const client = MatrixClientPeg.get();
- const roomId = ActiveRoomObserver.activeRoomId;
+ const roomId = targetRoomId || ActiveRoomObserver.activeRoomId;
if (!client || !roomId) throw new Error("Not in a room or not attached to a client");
@@ -145,48 +147,68 @@ export class StopGapWidgetDriver extends WidgetDriver {
return { roomId, eventId: r.event_id };
}
- public async readRoomEvents(eventType: string, msgtype: string | undefined, limit: number): Promise