Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit b2fce48

Browse files
author
Weblate
committed
Merge remote-tracking branch 'origin/develop' into develop
2 parents 7e721ad + c19a5bd commit b2fce48

File tree

5 files changed

+73
-9
lines changed

5 files changed

+73
-9
lines changed

src/Lifecycle.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import DMRoomMap from './utils/DMRoomMap';
3030
import RtsClient from './RtsClient';
3131
import Modal from './Modal';
3232
import sdk from './index';
33+
import ActiveWidgetStore from './stores/ActiveWidgetStore';
3334

3435
/**
3536
* Called at startup, to attempt to build a logged-in Matrix session. It tries
@@ -436,6 +437,7 @@ async function startMatrixClient() {
436437
UserActivity.start();
437438
Presence.start();
438439
DMRoomMap.makeShared().start();
440+
ActiveWidgetStore.start();
439441

440442
await MatrixClientPeg.start();
441443

@@ -488,6 +490,7 @@ export function stopMatrixClient() {
488490
Notifier.stop();
489491
UserActivity.stop();
490492
Presence.stop();
493+
ActiveWidgetStore.stop();
491494
if (DMRoomMap.shared()) DMRoomMap.shared().stop();
492495
const cli = MatrixClientPeg.get();
493496
if (cli) {

src/components/views/elements/AppTile.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,7 @@ export default class AppTile extends React.Component {
160160

161161
// if it's not remaining on screen, get rid of the PersistedElement container
162162
if (!ActiveWidgetStore.getWidgetPersistence(this.props.id)) {
163-
// FIXME: ActiveWidgetStore should probably worry about this?
164-
const PersistedElement = sdk.getComponent("elements.PersistedElement");
165-
PersistedElement.destroyElement(this._persistKey);
166-
ActiveWidgetStore.delWidgetMessaging(this.props.id);
167-
ActiveWidgetStore.delWidgetCapabilities(this.props.id);
168-
ActiveWidgetStore.delRoomId(this.props.id);
163+
ActiveWidgetStore.destroyPersistentWidget();
169164
}
170165
}
171166

@@ -439,6 +434,9 @@ export default class AppTile extends React.Component {
439434
console.warn('Revoking permission to load widget - ', this.state.widgetUrl);
440435
localStorage.removeItem(this.state.widgetPermissionId);
441436
this.setState({hasPermissionToLoad: false});
437+
438+
// Force the widget to be non-persistent
439+
ActiveWidgetStore.destroyPersistentWidget();
442440
}
443441

444442
formatAppTileName() {

src/components/views/elements/PersistentApp.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,20 @@ module.exports = React.createClass({
2727
getInitialState: function() {
2828
return {
2929
roomId: RoomViewStore.getRoomId(),
30+
persistentWidgetId: ActiveWidgetStore.getPersistentWidgetId(),
3031
};
3132
},
3233

3334
componentWillMount: function() {
3435
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
36+
ActiveWidgetStore.on('update', this._onActiveWidgetStoreUpdate);
3537
},
3638

3739
componentWillUnmount: function() {
3840
if (this._roomStoreToken) {
3941
this._roomStoreToken.remove();
4042
}
43+
ActiveWidgetStore.removeListener('update', this._onActiveWidgetStoreUpdate);
4144
},
4245

4346
_onRoomViewStoreUpdate: function(payload) {
@@ -47,9 +50,15 @@ module.exports = React.createClass({
4750
});
4851
},
4952

53+
_onActiveWidgetStoreUpdate: function() {
54+
this.setState({
55+
persistentWidgetId: ActiveWidgetStore.getPersistentWidgetId(),
56+
});
57+
},
58+
5059
render: function() {
51-
if (ActiveWidgetStore.getPersistentWidgetId()) {
52-
const persistentWidgetInRoomId = ActiveWidgetStore.getRoomId(ActiveWidgetStore.getPersistentWidgetId());
60+
if (this.state.persistentWidgetId) {
61+
const persistentWidgetInRoomId = ActiveWidgetStore.getRoomId(this.state.persistentWidgetId);
5362
if (this.state.roomId !== persistentWidgetInRoomId) {
5463
const persistentWidgetInRoom = MatrixClientPeg.get().getRoom(persistentWidgetInRoomId);
5564
// get the widget data

src/stores/ActiveWidgetStore.js

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,20 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17+
import EventEmitter from 'events';
18+
19+
import MatrixClientPeg from '../MatrixClientPeg';
20+
import sdk from '../index';
21+
1722
/**
1823
* Stores information about the widgets active in the app right now:
1924
* * What widget is set to remain always-on-screen, if any
2025
* Only one widget may be 'always on screen' at any one time.
2126
* * Negotiated capabilities for active apps
2227
*/
23-
class ActiveWidgetStore {
28+
class ActiveWidgetStore extends EventEmitter {
2429
constructor() {
30+
super();
2531
this._persistentWidgetId = null;
2632

2733
// A list of negotiated capabilities for each widget, by ID
@@ -35,6 +41,46 @@ class ActiveWidgetStore {
3541

3642
// What room ID each widget is associated with (if it's a room widget)
3743
this._roomIdByWidgetId = {};
44+
45+
this.onRoomStateEvents = this.onRoomStateEvents.bind(this);
46+
47+
this.dispatcherRef = null;
48+
}
49+
50+
start() {
51+
MatrixClientPeg.get().on('RoomState.events', this.onRoomStateEvents);
52+
}
53+
54+
stop() {
55+
if (MatrixClientPeg.get()) {
56+
MatrixClientPeg.get().removeListener('RoomState.events', this.onRoomStateEvents);
57+
}
58+
this._capsByWidgetId = {};
59+
this._widgetMessagingByWidgetId = {};
60+
this._roomIdByWidgetId = {};
61+
}
62+
63+
onRoomStateEvents(ev, state) {
64+
// XXX: This listens for state events in order to remove the active widget.
65+
// Everything else relies on views listening for events and calling setters
66+
// on this class which is terrible. This store should just listen for events
67+
// and keep itself up to date.
68+
if (ev.getType() !== 'im.vector.modular.widgets') return;
69+
70+
if (ev.getStateKey() === this._persistentWidgetId) {
71+
this.destroyPersistentWidget();
72+
}
73+
}
74+
75+
destroyPersistentWidget() {
76+
const toDeleteId = this._persistentWidgetId;
77+
78+
const PersistedElement = sdk.getComponent("elements.PersistedElement");
79+
PersistedElement.destroyElement('widget_' + toDeleteId);
80+
this.setWidgetPersistence(toDeleteId, false);
81+
this.delWidgetMessaging(toDeleteId);
82+
this.delWidgetCapabilities(toDeleteId);
83+
this.delRoomId(toDeleteId);
3884
}
3985

4086
setWidgetPersistence(widgetId, val) {
@@ -43,6 +89,7 @@ class ActiveWidgetStore {
4389
} else if (this._persistentWidgetId !== widgetId && val) {
4490
this._persistentWidgetId = widgetId;
4591
}
92+
this.emit('update');
4693
}
4794

4895
getWidgetPersistence(widgetId) {
@@ -55,6 +102,7 @@ class ActiveWidgetStore {
55102

56103
setWidgetCapabilities(widgetId, caps) {
57104
this._capsByWidgetId[widgetId] = caps;
105+
this.emit('update');
58106
}
59107

60108
widgetHasCapability(widgetId, cap) {
@@ -63,10 +111,12 @@ class ActiveWidgetStore {
63111

64112
delWidgetCapabilities(widgetId) {
65113
delete this._capsByWidgetId[widgetId];
114+
this.emit('update');
66115
}
67116

68117
setWidgetMessaging(widgetId, wm) {
69118
this._widgetMessagingByWidgetId[widgetId] = wm;
119+
this.emit('update');
70120
}
71121

72122
getWidgetMessaging(widgetId) {
@@ -81,6 +131,7 @@ class ActiveWidgetStore {
81131
console.error('Failed to stop listening for widgetMessaging events', e.message);
82132
}
83133
delete this._widgetMessagingByWidgetId[widgetId];
134+
this.emit('update');
84135
}
85136
}
86137

@@ -90,10 +141,12 @@ class ActiveWidgetStore {
90141

91142
setRoomId(widgetId, roomId) {
92143
this._roomIdByWidgetId[widgetId] = roomId;
144+
this.emit('update');
93145
}
94146

95147
delRoomId(widgetId) {
96148
delete this._roomIdByWidgetId[widgetId];
149+
this.emit('update');
97150
}
98151
}
99152

src/stores/LifecycleStore.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
Copyright 2017 Vector Creations Ltd
3+
Copyright 2018 New Vector Ltd
34
45
Licensed under the Apache License, Version 2.0 (the "License");
56
you may not use this file except in compliance with the License.

0 commit comments

Comments
 (0)