mirror of https://github.com/vector-im/riot-web
Make ActiveWidgetStore clear persistent widgets
ActiveWidgetStore is now reponsible for removing the current persistent widget from the store if it's been removed from whatever room it was in. As per comment, this leaves us with the store updating itself in this case but in all other cases, views call setters on the store to update its state. We should make it so the store keeps itself up to date and views aren't responsible for keeping the store up to date. The store now emits events so it can notify PersistentApp when it changes. Fixes https://github.com/vector-im/riot-web/issues/7076pull/21833/head
parent
6804647dda
commit
ec4c7ffb71
|
@ -30,6 +30,7 @@ import DMRoomMap from './utils/DMRoomMap';
|
|||
import RtsClient from './RtsClient';
|
||||
import Modal from './Modal';
|
||||
import sdk from './index';
|
||||
import ActiveWidgetStore from './stores/ActiveWidgetStore';
|
||||
|
||||
/**
|
||||
* Called at startup, to attempt to build a logged-in Matrix session. It tries
|
||||
|
@ -436,6 +437,7 @@ async function startMatrixClient() {
|
|||
UserActivity.start();
|
||||
Presence.start();
|
||||
DMRoomMap.makeShared().start();
|
||||
ActiveWidgetStore.start();
|
||||
|
||||
await MatrixClientPeg.start();
|
||||
|
||||
|
@ -488,6 +490,7 @@ export function stopMatrixClient() {
|
|||
Notifier.stop();
|
||||
UserActivity.stop();
|
||||
Presence.stop();
|
||||
ActiveWidgetStore.start();
|
||||
if (DMRoomMap.shared()) DMRoomMap.shared().stop();
|
||||
const cli = MatrixClientPeg.get();
|
||||
if (cli) {
|
||||
|
|
|
@ -27,17 +27,20 @@ module.exports = React.createClass({
|
|||
getInitialState: function() {
|
||||
return {
|
||||
roomId: RoomViewStore.getRoomId(),
|
||||
persistentWidgetId: ActiveWidgetStore.getPersistentWidgetId(),
|
||||
};
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
|
||||
ActiveWidgetStore.on('update', this._onActiveWidgetStoreUpdate);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
if (this._roomStoreToken) {
|
||||
this._roomStoreToken.remove();
|
||||
}
|
||||
ActiveWidgetStore.removeListener('update', this._onActiveWidgetStoreUpdate);
|
||||
},
|
||||
|
||||
_onRoomViewStoreUpdate: function(payload) {
|
||||
|
@ -47,9 +50,15 @@ module.exports = React.createClass({
|
|||
});
|
||||
},
|
||||
|
||||
_onActiveWidgetStoreUpdate: function() {
|
||||
this.setState({
|
||||
persistentWidgetId: ActiveWidgetStore.getPersistentWidgetId(),
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (ActiveWidgetStore.getPersistentWidgetId()) {
|
||||
const persistentWidgetInRoomId = ActiveWidgetStore.getRoomId(ActiveWidgetStore.getPersistentWidgetId());
|
||||
if (this.state.persistentWidgetId) {
|
||||
const persistentWidgetInRoomId = ActiveWidgetStore.getRoomId(this.state.persistentWidgetId);
|
||||
if (this.state.roomId !== persistentWidgetInRoomId) {
|
||||
const persistentWidgetInRoom = MatrixClientPeg.get().getRoom(persistentWidgetInRoomId);
|
||||
// get the widget data
|
||||
|
|
|
@ -14,14 +14,20 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import EventEmitter from 'events';
|
||||
|
||||
import MatrixClientPeg from '../MatrixClientPeg';
|
||||
import sdk from '../index';
|
||||
|
||||
/**
|
||||
* Stores information about the widgets active in the app right now:
|
||||
* * What widget is set to remain always-on-screen, if any
|
||||
* Only one widget may be 'always on screen' at any one time.
|
||||
* * Negotiated capabilities for active apps
|
||||
*/
|
||||
class ActiveWidgetStore {
|
||||
class ActiveWidgetStore extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
this._persistentWidgetId = null;
|
||||
|
||||
// A list of negotiated capabilities for each widget, by ID
|
||||
|
@ -35,6 +41,38 @@ class ActiveWidgetStore {
|
|||
|
||||
// What room ID each widget is associated with (if it's a room widget)
|
||||
this._roomIdByWidgetId = {};
|
||||
|
||||
this.onRoomStateEvents = this.onRoomStateEvents.bind(this);
|
||||
|
||||
this.dispatcherRef = null;
|
||||
}
|
||||
|
||||
start() {
|
||||
MatrixClientPeg.get().on('RoomState.events', this.onRoomStateEvents);
|
||||
}
|
||||
|
||||
stop() {
|
||||
MatrixClientPeg.get().removeListener('RoomState.events', this.onRoomStateEvents);
|
||||
this._capsByWidgetId = {};
|
||||
this._widgetMessagingByWidgetId = {};
|
||||
this._roomIdByWidgetId = {};
|
||||
}
|
||||
|
||||
onRoomStateEvents(ev, state) {
|
||||
// XXX: This listens for state events in order to remove the active widget.
|
||||
// Everything else relies on views listening for events and calling setters
|
||||
// on this class which is terrible. This store should just listen for events
|
||||
// and keep itself up to date.
|
||||
if (ev.getType() !== 'im.vector.modular.widgets') return;
|
||||
|
||||
if (ev.getStateKey() === this._persistentWidgetId) {
|
||||
const PersistedElement = sdk.getComponent("elements.PersistedElement");
|
||||
PersistedElement.destroyElement('widget_' + ev.getStateKey());
|
||||
this.setWidgetPersistence(ev.getStateKey(), false);
|
||||
this.delWidgetMessaging(ev.getStateKey());
|
||||
this.delWidgetCapabilities(ev.getStateKey());
|
||||
this.delRoomId(ev.getStateKey());
|
||||
}
|
||||
}
|
||||
|
||||
setWidgetPersistence(widgetId, val) {
|
||||
|
@ -43,6 +81,7 @@ class ActiveWidgetStore {
|
|||
} else if (this._persistentWidgetId !== widgetId && val) {
|
||||
this._persistentWidgetId = widgetId;
|
||||
}
|
||||
this.emit('update');
|
||||
}
|
||||
|
||||
getWidgetPersistence(widgetId) {
|
||||
|
@ -55,6 +94,7 @@ class ActiveWidgetStore {
|
|||
|
||||
setWidgetCapabilities(widgetId, caps) {
|
||||
this._capsByWidgetId[widgetId] = caps;
|
||||
this.emit('update');
|
||||
}
|
||||
|
||||
widgetHasCapability(widgetId, cap) {
|
||||
|
@ -63,10 +103,12 @@ class ActiveWidgetStore {
|
|||
|
||||
delWidgetCapabilities(widgetId) {
|
||||
delete this._capsByWidgetId[widgetId];
|
||||
this.emit('update');
|
||||
}
|
||||
|
||||
setWidgetMessaging(widgetId, wm) {
|
||||
this._widgetMessagingByWidgetId[widgetId] = wm;
|
||||
this.emit('update');
|
||||
}
|
||||
|
||||
getWidgetMessaging(widgetId) {
|
||||
|
@ -81,6 +123,7 @@ class ActiveWidgetStore {
|
|||
console.error('Failed to stop listening for widgetMessaging events', e.message);
|
||||
}
|
||||
delete this._widgetMessagingByWidgetId[widgetId];
|
||||
this.emit('update');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,10 +133,12 @@ class ActiveWidgetStore {
|
|||
|
||||
setRoomId(widgetId, roomId) {
|
||||
this._roomIdByWidgetId[widgetId] = roomId;
|
||||
this.emit('update');
|
||||
}
|
||||
|
||||
delRoomId(widgetId) {
|
||||
delete this._roomIdByWidgetId[widgetId];
|
||||
this.emit('update');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue