element-web/src/stores/WidgetEchoStore.js

106 lines
3.7 KiB
JavaScript
Raw Normal View History

/*
Copyright 2018 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import EventEmitter from 'events';
/**
* Acts as a place to get & set widget state, storing local echo state and
* proxying through state from the js-sdk.
*/
class WidgetEchoStore extends EventEmitter {
constructor() {
super();
this._roomWidgetEcho = {
2018-07-05 21:40:45 +03:00
// 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: [object]
// }
};
}
/**
* Gets the widgets for a room, substracting those that are pending deletion.
* Widgets that are pending addition are not included, since widgets are
* represted 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.
2018-07-03 13:22:19 +03:00
*
* @param {Room} roomId The ID of the room to get widgets for
2018-07-03 13:22:19 +03:00
* @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();
2018-07-05 21:46:37 +03:00
// 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 rason we don't include new ones
if (!roomEchoState[widgetId] || Object.keys(roomEchoState[widgetId]).length !== 0) {
} else {
echoedWidgets.push(w);
}
delete roomEchoState[widgetId];
}
return echoedWidgets;
}
roomHasPendingWidgetsOfType(roomId, currentRoomWidgets, type) {
const roomEchoState = Object.assign({}, this._roomWidgetEcho[roomId]);
for (const w of currentRoomWidgets) {
const widgetId = w.getStateKey();
delete roomEchoState[widgetId];
}
if (type === undefined) {
return Object.keys(roomEchoState).length > 0;
} else {
return Object.values(roomEchoState).some((widget) => {
2018-07-03 13:22:19 +03:00
return widget.type === 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('updateRoomWidgetEcho');
}
removeRoomWidgetEcho(roomId, widgetId) {
delete this._roomWidgetEcho[roomId][widgetId];
2018-07-05 21:38:42 +03:00
if (Object.keys(this._roomWidgetEcho[roomId]).length === 0) delete this._roomWidgetEcho[roomId];
this.emit('updateRoomWidgetEcho');
}
}
let singletonWidgetEchoStore = null;
if (!singletonWidgetEchoStore) {
singletonWidgetEchoStore = new WidgetEchoStore();
}
module.exports = singletonWidgetEchoStore;