matrix-react-sdk
Version:
SDK for matrix.org using React
99 lines (93 loc) • 13.7 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _events = _interopRequireDefault(require("events"));
/*
Copyright 2024 New Vector Ltd.
Copyright 2018-2021 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
/**
* Acts as a place to get & set widget state, storing local echo state and
* proxying through state from the js-sdk.
*/
class WidgetEchoStore extends _events.default {
constructor() {
super();
(0, _defineProperty2.default)(this, "roomWidgetEcho", void 0);
this.roomWidgetEcho = {
// Map as below. Object is the content of the widget state event,
// so for widgets that have been deleted locally, the object is empty.
// roomId: {
// widgetId: IWidget
// }
};
}
/**
* Gets the widgets for a room, subtracting those that are pending deletion.
* Widgets that are pending addition are not included, since widgets are
* represented as MatrixEvents, so to do this we'd have to create fake MatrixEvents,
* and we don't really need the actual widget events anyway since we just want to
* show a spinner / prevent widgets being added twice.
*
* @param {string} roomId The ID of the room to get widgets for
* @param {MatrixEvent[]} currentRoomWidgets Current widgets for the room
* @returns {MatrixEvent[]} List of widgets in the room, minus any pending removal
*/
getEchoedRoomWidgets(roomId, currentRoomWidgets) {
const echoedWidgets = [];
const roomEchoState = Object.assign({}, this.roomWidgetEcho[roomId]);
for (const w of currentRoomWidgets) {
const widgetId = w.getStateKey();
// If there's no echo, or the echo still has a widget present, show the *old* widget
// we don't include widgets that have changed for the same reason we don't include new ones,
// ie. we'd need to fake matrix events to do so and there's currently no need.
if (!roomEchoState[widgetId] || Object.keys(roomEchoState[widgetId]).length !== 0) {
echoedWidgets.push(w);
}
delete roomEchoState[widgetId];
}
return echoedWidgets;
}
roomHasPendingWidgetsOfType(roomId, currentRoomWidgets, type) {
const roomEchoState = Object.assign({}, this.roomWidgetEcho[roomId]);
// any widget IDs that are already in the room are not pending, so
// echoes for them don't count as pending.
for (const w of currentRoomWidgets) {
const widgetId = w.getStateKey();
delete roomEchoState[widgetId];
}
// if there's anything left then there are pending widgets.
if (type === undefined) {
return Object.keys(roomEchoState).length > 0;
} else {
return Object.values(roomEchoState).some(widget => {
return type.matches(widget.type);
});
}
}
roomHasPendingWidgets(roomId, currentRoomWidgets) {
return this.roomHasPendingWidgetsOfType(roomId, currentRoomWidgets);
}
setRoomWidgetEcho(roomId, widgetId, state) {
if (this.roomWidgetEcho[roomId] === undefined) this.roomWidgetEcho[roomId] = {};
this.roomWidgetEcho[roomId][widgetId] = state;
this.emit("update", roomId, widgetId);
}
removeRoomWidgetEcho(roomId, widgetId) {
delete this.roomWidgetEcho[roomId][widgetId];
if (Object.keys(this.roomWidgetEcho[roomId]).length === 0) delete this.roomWidgetEcho[roomId];
this.emit("update", roomId, widgetId);
}
}
let singletonWidgetEchoStore = null;
if (!singletonWidgetEchoStore) {
singletonWidgetEchoStore = new WidgetEchoStore();
}
var _default = exports.default = singletonWidgetEchoStore;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZXZlbnRzIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJXaWRnZXRFY2hvU3RvcmUiLCJFdmVudEVtaXR0ZXIiLCJjb25zdHJ1Y3RvciIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJkZWZhdWx0Iiwicm9vbVdpZGdldEVjaG8iLCJnZXRFY2hvZWRSb29tV2lkZ2V0cyIsInJvb21JZCIsImN1cnJlbnRSb29tV2lkZ2V0cyIsImVjaG9lZFdpZGdldHMiLCJyb29tRWNob1N0YXRlIiwiT2JqZWN0IiwiYXNzaWduIiwidyIsIndpZGdldElkIiwiZ2V0U3RhdGVLZXkiLCJrZXlzIiwibGVuZ3RoIiwicHVzaCIsInJvb21IYXNQZW5kaW5nV2lkZ2V0c09mVHlwZSIsInR5cGUiLCJ1bmRlZmluZWQiLCJ2YWx1ZXMiLCJzb21lIiwid2lkZ2V0IiwibWF0Y2hlcyIsInJvb21IYXNQZW5kaW5nV2lkZ2V0cyIsInNldFJvb21XaWRnZXRFY2hvIiwic3RhdGUiLCJlbWl0IiwicmVtb3ZlUm9vbVdpZGdldEVjaG8iLCJzaW5nbGV0b25XaWRnZXRFY2hvU3RvcmUiLCJfZGVmYXVsdCIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RvcmVzL1dpZGdldEVjaG9TdG9yZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuQ29weXJpZ2h0IDIwMjQgTmV3IFZlY3RvciBMdGQuXG5Db3B5cmlnaHQgMjAxOC0yMDIxIFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgZnJvbSBcImV2ZW50c1wiO1xuaW1wb3J0IHsgSVdpZGdldCB9IGZyb20gXCJtYXRyaXgtd2lkZ2V0LWFwaVwiO1xuaW1wb3J0IHsgTWF0cml4RXZlbnQgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5cbmltcG9ydCB7IFdpZGdldFR5cGUgfSBmcm9tIFwiLi4vd2lkZ2V0cy9XaWRnZXRUeXBlXCI7XG5cbi8qKlxuICogQWN0cyBhcyBhIHBsYWNlIHRvIGdldCAmIHNldCB3aWRnZXQgc3RhdGUsIHN0b3JpbmcgbG9jYWwgZWNobyBzdGF0ZSBhbmRcbiAqIHByb3h5aW5nIHRocm91Z2ggc3RhdGUgZnJvbSB0aGUganMtc2RrLlxuICovXG5jbGFzcyBXaWRnZXRFY2hvU3RvcmUgZXh0ZW5kcyBFdmVudEVtaXR0ZXIge1xuICAgIHByaXZhdGUgcm9vbVdpZGdldEVjaG86IHtcbiAgICAgICAgW3Jvb21JZDogc3RyaW5nXToge1xuICAgICAgICAgICAgW3dpZGdldElkOiBzdHJpbmddOiBJV2lkZ2V0O1xuICAgICAgICB9O1xuICAgIH07XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgdGhpcy5yb29tV2lkZ2V0RWNobyA9IHtcbiAgICAgICAgICAgIC8vIE1hcCBhcyBiZWxvdy4gT2JqZWN0IGlzIHRoZSBjb250ZW50IG9mIHRoZSB3aWRnZXQgc3RhdGUgZXZlbnQsXG4gICAgICAgICAgICAvLyBzbyBmb3Igd2lkZ2V0cyB0aGF0IGhhdmUgYmVlbiBkZWxldGVkIGxvY2FsbHksIHRoZSBvYmplY3QgaXMgZW1wdHkuXG4gICAgICAgICAgICAvLyByb29tSWQ6IHtcbiAgICAgICAgICAgIC8vICAgICB3aWRnZXRJZDogSVdpZGdldFxuICAgICAgICAgICAgLy8gfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHdpZGdldHMgZm9yIGEgcm9vbSwgc3VidHJhY3RpbmcgdGhvc2UgdGhhdCBhcmUgcGVuZGluZyBkZWxldGlvbi5cbiAgICAgKiBXaWRnZXRzIHRoYXQgYXJlIHBlbmRpbmcgYWRkaXRpb24gYXJlIG5vdCBpbmNsdWRlZCwgc2luY2Ugd2lkZ2V0cyBhcmVcbiAgICAgKiByZXByZXNlbnRlZCBhcyBNYXRyaXhFdmVudHMsIHNvIHRvIGRvIHRoaXMgd2UnZCBoYXZlIHRvIGNyZWF0ZSBmYWtlIE1hdHJpeEV2ZW50cyxcbiAgICAgKiBhbmQgd2UgZG9uJ3QgcmVhbGx5IG5lZWQgdGhlIGFjdHVhbCB3aWRnZXQgZXZlbnRzIGFueXdheSBzaW5jZSB3ZSBqdXN0IHdhbnQgdG9cbiAgICAgKiBzaG93IGEgc3Bpbm5lciAvIHByZXZlbnQgd2lkZ2V0cyBiZWluZyBhZGRlZCB0d2ljZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSByb29tSWQgVGhlIElEIG9mIHRoZSByb29tIHRvIGdldCB3aWRnZXRzIGZvclxuICAgICAqIEBwYXJhbSB7TWF0cml4RXZlbnRbXX0gY3VycmVudFJvb21XaWRnZXRzIEN1cnJlbnQgd2lkZ2V0cyBmb3IgdGhlIHJvb21cbiAgICAgKiBAcmV0dXJucyB7TWF0cml4RXZlbnRbXX0gTGlzdCBvZiB3aWRnZXRzIGluIHRoZSByb29tLCBtaW51cyBhbnkgcGVuZGluZyByZW1vdmFsXG4gICAgICovXG4gICAgcHVibGljIGdldEVjaG9lZFJvb21XaWRnZXRzKHJvb21JZDogc3RyaW5nLCBjdXJyZW50Um9vbVdpZGdldHM6IE1hdHJpeEV2ZW50W10pOiBNYXRyaXhFdmVudFtdIHtcbiAgICAgICAgY29uc3QgZWNob2VkV2lkZ2V0czogTWF0cml4RXZlbnRbXSA9IFtdO1xuXG4gICAgICAgIGNvbnN0IHJvb21FY2hvU3RhdGUgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLnJvb21XaWRnZXRFY2hvW3Jvb21JZF0pO1xuXG4gICAgICAgIGZvciAoY29uc3QgdyBvZiBjdXJyZW50Um9vbVdpZGdldHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHdpZGdldElkID0gdy5nZXRTdGF0ZUtleSgpITtcbiAgICAgICAgICAgIC8vIElmIHRoZXJlJ3Mgbm8gZWNobywgb3IgdGhlIGVjaG8gc3RpbGwgaGFzIGEgd2lkZ2V0IHByZXNlbnQsIHNob3cgdGhlICpvbGQqIHdpZGdldFxuICAgICAgICAgICAgLy8gd2UgZG9uJ3QgaW5jbHVkZSB3aWRnZXRzIHRoYXQgaGF2ZSBjaGFuZ2VkIGZvciB0aGUgc2FtZSByZWFzb24gd2UgZG9uJ3QgaW5jbHVkZSBuZXcgb25lcyxcbiAgICAgICAgICAgIC8vIGllLiB3ZSdkIG5lZWQgdG8gZmFrZSBtYXRyaXggZXZlbnRzIHRvIGRvIHNvIGFuZCB0aGVyZSdzIGN1cnJlbnRseSBubyBuZWVkLlxuICAgICAgICAgICAgaWYgKCFyb29tRWNob1N0YXRlW3dpZGdldElkXSB8fCBPYmplY3Qua2V5cyhyb29tRWNob1N0YXRlW3dpZGdldElkXSkubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgZWNob2VkV2lkZ2V0cy5wdXNoKHcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsZXRlIHJvb21FY2hvU3RhdGVbd2lkZ2V0SWRdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVjaG9lZFdpZGdldHM7XG4gICAgfVxuXG4gICAgcHVibGljIHJvb21IYXNQZW5kaW5nV2lkZ2V0c09mVHlwZShyb29tSWQ6IHN0cmluZywgY3VycmVudFJvb21XaWRnZXRzOiBNYXRyaXhFdmVudFtdLCB0eXBlPzogV2lkZ2V0VHlwZSk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCByb29tRWNob1N0YXRlID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5yb29tV2lkZ2V0RWNob1tyb29tSWRdKTtcblxuICAgICAgICAvLyBhbnkgd2lkZ2V0IElEcyB0aGF0IGFyZSBhbHJlYWR5IGluIHRoZSByb29tIGFyZSBub3QgcGVuZGluZywgc29cbiAgICAgICAgLy8gZWNob2VzIGZvciB0aGVtIGRvbid0IGNvdW50IGFzIHBlbmRpbmcuXG4gICAgICAgIGZvciAoY29uc3QgdyBvZiBjdXJyZW50Um9vbVdpZGdldHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHdpZGdldElkID0gdy5nZXRTdGF0ZUtleSgpITtcbiAgICAgICAgICAgIGRlbGV0ZSByb29tRWNob1N0YXRlW3dpZGdldElkXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIHRoZXJlJ3MgYW55dGhpbmcgbGVmdCB0aGVuIHRoZXJlIGFyZSBwZW5kaW5nIHdpZGdldHMuXG4gICAgICAgIGlmICh0eXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhyb29tRWNob1N0YXRlKS5sZW5ndGggPiAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC52YWx1ZXMocm9vbUVjaG9TdGF0ZSkuc29tZSgod2lkZ2V0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHR5cGUubWF0Y2hlcyh3aWRnZXQudHlwZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyByb29tSGFzUGVuZGluZ1dpZGdldHMocm9vbUlkOiBzdHJpbmcsIGN1cnJlbnRSb29tV2lkZ2V0czogTWF0cml4RXZlbnRbXSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yb29tSGFzUGVuZGluZ1dpZGdldHNPZlR5cGUocm9vbUlkLCBjdXJyZW50Um9vbVdpZGdldHMpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRSb29tV2lkZ2V0RWNobyhyb29tSWQ6IHN0cmluZywgd2lkZ2V0SWQ6IHN0cmluZywgc3RhdGU6IElXaWRnZXQpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMucm9vbVdpZGdldEVjaG9bcm9vbUlkXSA9PT0gdW5kZWZpbmVkKSB0aGlzLnJvb21XaWRnZXRFY2hvW3Jvb21JZF0gPSB7fTtcblxuICAgICAgICB0aGlzLnJvb21XaWRnZXRFY2hvW3Jvb21JZF1bd2lkZ2V0SWRdID0gc3RhdGU7XG4gICAgICAgIHRoaXMuZW1pdChcInVwZGF0ZVwiLCByb29tSWQsIHdpZGdldElkKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVtb3ZlUm9vbVdpZGdldEVjaG8ocm9vbUlkOiBzdHJpbmcsIHdpZGdldElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgZGVsZXRlIHRoaXMucm9vbVdpZGdldEVjaG9bcm9vbUlkXVt3aWRnZXRJZF07XG4gICAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLnJvb21XaWRnZXRFY2hvW3Jvb21JZF0pLmxlbmd0aCA9PT0gMCkgZGVsZXRlIHRoaXMucm9vbVdpZGdldEVjaG9bcm9vbUlkXTtcbiAgICAgICAgdGhpcy5lbWl0KFwidXBkYXRlXCIsIHJvb21JZCwgd2lkZ2V0SWQpO1xuICAgIH1cbn1cblxubGV0IHNpbmdsZXRvbldpZGdldEVjaG9TdG9yZTogV2lkZ2V0RWNob1N0b3JlIHwgbnVsbCA9IG51bGw7XG5pZiAoIXNpbmdsZXRvbldpZGdldEVjaG9TdG9yZSkge1xuICAgIHNpbmdsZXRvbldpZGdldEVjaG9TdG9yZSA9IG5ldyBXaWRnZXRFY2hvU3RvcmUoKTtcbn1cbmV4cG9ydCBkZWZhdWx0IHNpbmdsZXRvbldpZGdldEVjaG9TdG9yZSE7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBUUEsSUFBQUEsT0FBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNQyxlQUFlLFNBQVNDLGVBQVksQ0FBQztFQU9oQ0MsV0FBV0EsQ0FBQSxFQUFHO0lBQ2pCLEtBQUssQ0FBQyxDQUFDO0lBQUMsSUFBQUMsZ0JBQUEsQ0FBQUMsT0FBQTtJQUVSLElBQUksQ0FBQ0MsY0FBYyxHQUFHO01BQ2xCO01BQ0E7TUFDQTtNQUNBO01BQ0E7SUFBQSxDQUNIO0VBQ0w7O0VBRUE7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNXQyxvQkFBb0JBLENBQUNDLE1BQWMsRUFBRUMsa0JBQWlDLEVBQWlCO0lBQzFGLE1BQU1DLGFB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