Don't re-init the stickerpicker unless something actually changes

Fixes https://github.com/vector-im/riot-web/issues/9354

https://github.com/matrix-org/matrix-react-sdk/pull/2801 introduced a change which tried to make sure that when the widget URL was changed that the picker would be re-mounted, however it accidentally introduced a regression. While it effectively did the task it wanted to, it failed to keep the previously-mounted sticker picker alive. This is because the Stickerpicker component is remounted when opened, and the _updateWidget function is called. This results in this.state not having the "current" widget, meaning a URL change is always detected when the component is remounted (room changes, open sticker picker). 

Instead of remounting always, we'll instead track which sticker picker widget is being used out of band. This therefore means that whenever the Stickerpicker component is mounted it doesn't create a whole new widget, and the existing (background) picker can be used. This also fixes the loading screen that people would see when opening the sticker picker after switching rooms, something which the persistent widget stuff is supposed to solve.
pull/21833/head
Travis Ralston 2019-04-01 19:47:28 -06:00
parent d92336fc16
commit a4f76670c4
2 changed files with 23 additions and 1 deletions

View File

@ -130,8 +130,13 @@ export default class Stickerpicker extends React.Component {
_updateWidget() {
const stickerpickerWidget = WidgetUtils.getStickerpickerWidgets()[0];
if (!stickerpickerWidget) {
ActiveWidgetStore.delStickerPickerWidget();
this.setState({stickerpickerWidget: null, widgetId: null});
return;
}
const currentWidget = this.state.stickerpickerWidget;
const currentWidget = ActiveWidgetStore.getStickerPickerWidget();
let currentUrl = null;
if (currentWidget && currentWidget.content && currentWidget.content.url) {
currentUrl = currentWidget.content.url;
@ -147,6 +152,7 @@ export default class Stickerpicker extends React.Component {
PersistedElement.destroyElement(PERSISTED_ELEMENT_KEY);
}
ActiveWidgetStore.setStickerPickerWidget(stickerpickerWidget);
this.setState({
stickerpickerWidget,
widgetId: stickerpickerWidget ? stickerpickerWidget.id : null,

View File

@ -23,6 +23,7 @@ import MatrixClientPeg from '../MatrixClientPeg';
* * 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
* * Which stickerpicker the app is using, if any
*/
class ActiveWidgetStore extends EventEmitter {
constructor() {
@ -41,6 +42,9 @@ class ActiveWidgetStore extends EventEmitter {
// What room ID each widget is associated with (if it's a room widget)
this._roomIdByWidgetId = {};
// The sticker picker widget definition the app is currently using, if any
this._stickerPickerWidget = null;
this.onRoomStateEvents = this.onRoomStateEvents.bind(this);
this.dispatcherRef = null;
@ -145,6 +149,18 @@ class ActiveWidgetStore extends EventEmitter {
delete this._roomIdByWidgetId[widgetId];
this.emit('update');
}
getStickerPickerWidget() {
return this._stickerPickerWidget;
}
setStickerPickerWidget(widget) {
this._stickerPickerWidget = widget;
}
delStickerPickerWidget() {
this._stickerPickerWidget = null;
}
}
if (global.singletonActiveWidgetStore === undefined) {