mirror of
				https://github.com/vector-im/element-web.git
				synced 2025-11-04 02:02:14 +01:00 
			
		
		
		
	Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
		
						commit
						f700c8e60d
					
				@ -62,6 +62,7 @@ import dis from './dispatcher';
 | 
				
			|||||||
import { showUnknownDeviceDialogForCalls } from './cryptodevices';
 | 
					import { showUnknownDeviceDialogForCalls } from './cryptodevices';
 | 
				
			||||||
import SettingsStore from "./settings/SettingsStore";
 | 
					import SettingsStore from "./settings/SettingsStore";
 | 
				
			||||||
import WidgetUtils from './utils/WidgetUtils';
 | 
					import WidgetUtils from './utils/WidgetUtils';
 | 
				
			||||||
 | 
					import WidgetEchoStore from './stores/WidgetEchoStore';
 | 
				
			||||||
import ScalarAuthClient from './ScalarAuthClient';
 | 
					import ScalarAuthClient from './ScalarAuthClient';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
global.mxCalls = {
 | 
					global.mxCalls = {
 | 
				
			||||||
@ -431,12 +432,19 @@ async function _startCallApp(roomId, type) {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const room = MatrixClientPeg.get().getRoom(roomId);
 | 
					    const room = MatrixClientPeg.get().getRoom(roomId);
 | 
				
			||||||
    if (!room) {
 | 
					    const currentRoomWidgets = WidgetUtils.getRoomWidgets(room);
 | 
				
			||||||
        console.error("Attempted to start conference call widget in unknown room: " + roomId);
 | 
					
 | 
				
			||||||
 | 
					    if (WidgetEchoStore.roomHasPendingWidgetsOfType(roomId, currentRoomWidgets, 'jitsi')) {
 | 
				
			||||||
 | 
					        const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Modal.createTrackedDialog('Call already in progress', '', ErrorDialog, {
 | 
				
			||||||
 | 
					            title: _t('Call in Progress'),
 | 
				
			||||||
 | 
					            description: _t('A call is currently being placed!'),
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const currentJitsiWidgets = WidgetUtils.getRoomWidgets(room).filter((ev) => {
 | 
					    const currentJitsiWidgets = currentRoomWidgets.filter((ev) => {
 | 
				
			||||||
        return ev.getContent().type === 'jitsi';
 | 
					        return ev.getContent().type === 'jitsi';
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    if (currentJitsiWidgets.length > 0) {
 | 
					    if (currentJitsiWidgets.length > 0) {
 | 
				
			||||||
 | 
				
			|||||||
@ -45,6 +45,7 @@ import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import RoomViewStore from '../../stores/RoomViewStore';
 | 
					import RoomViewStore from '../../stores/RoomViewStore';
 | 
				
			||||||
import RoomScrollStateStore from '../../stores/RoomScrollStateStore';
 | 
					import RoomScrollStateStore from '../../stores/RoomScrollStateStore';
 | 
				
			||||||
 | 
					import WidgetEchoStore from '../../stores/WidgetEchoStore';
 | 
				
			||||||
import SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
 | 
					import SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
 | 
				
			||||||
import WidgetUtils from '../../utils/WidgetUtils';
 | 
					import WidgetUtils from '../../utils/WidgetUtils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -153,6 +154,8 @@ module.exports = React.createClass({
 | 
				
			|||||||
        // Start listening for RoomViewStore updates
 | 
					        // Start listening for RoomViewStore updates
 | 
				
			||||||
        this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
 | 
					        this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
 | 
				
			||||||
        this._onRoomViewStoreUpdate(true);
 | 
					        this._onRoomViewStoreUpdate(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        WidgetEchoStore.on('update', this._onWidgetEchoStoreUpdate);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _onRoomViewStoreUpdate: function(initial) {
 | 
					    _onRoomViewStoreUpdate: function(initial) {
 | 
				
			||||||
@ -243,6 +246,12 @@ module.exports = React.createClass({
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _onWidgetEchoStoreUpdate: function() {
 | 
				
			||||||
 | 
					        this.setState({
 | 
				
			||||||
 | 
					            showApps: this._shouldShowApps(this.state.room),
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _setupRoom: function(room, roomId, joining, shouldPeek) {
 | 
					    _setupRoom: function(room, roomId, joining, shouldPeek) {
 | 
				
			||||||
        // if this is an unknown room then we're in one of three states:
 | 
					        // if this is an unknown room then we're in one of three states:
 | 
				
			||||||
        // - This is a room we can peek into (search engine) (we can /peek)
 | 
					        // - This is a room we can peek into (search engine) (we can /peek)
 | 
				
			||||||
@ -319,7 +328,9 @@ module.exports = React.createClass({
 | 
				
			|||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return WidgetUtils.getRoomWidgets(room).length > 0;
 | 
					        const widgets = WidgetEchoStore.getEchoedRoomWidgets(room.roomId, WidgetUtils.getRoomWidgets(room));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return widgets.length > 0 || WidgetEchoStore.roomHasPendingWidgets(room.roomId, WidgetUtils.getRoomWidgets(room));
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    componentDidMount: function() {
 | 
					    componentDidMount: function() {
 | 
				
			||||||
@ -414,6 +425,8 @@ module.exports = React.createClass({
 | 
				
			|||||||
            this._roomStoreToken.remove();
 | 
					            this._roomStoreToken.remove();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        WidgetEchoStore.removeListener('update', this._onWidgetEchoStoreUpdate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // cancel any pending calls to the rate_limited_funcs
 | 
					        // cancel any pending calls to the rate_limited_funcs
 | 
				
			||||||
        this._updateRoomMembers.cancelPendingCall();
 | 
					        this._updateRoomMembers.cancelPendingCall();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -325,6 +325,12 @@ export default class AppTile extends React.Component {
 | 
				
			|||||||
                            this.props.id,
 | 
					                            this.props.id,
 | 
				
			||||||
                        ).catch((e) => {
 | 
					                        ).catch((e) => {
 | 
				
			||||||
                            console.error('Failed to delete widget', e);
 | 
					                            console.error('Failed to delete widget', e);
 | 
				
			||||||
 | 
					                            const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            Modal.createTrackedDialog('Failed to remove widget', '', ErrorDialog, {
 | 
				
			||||||
 | 
					                                title: _t('Failed to remove widget'),
 | 
				
			||||||
 | 
					                                description: _t('An error ocurred whilst trying to remove the widget from the room'),
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
                        }).finally(() => {
 | 
					                        }).finally(() => {
 | 
				
			||||||
                            this.setState({deleting: false});
 | 
					                            this.setState({deleting: false});
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
 | 
				
			|||||||
@ -29,6 +29,7 @@ import ScalarAuthClient from '../../../ScalarAuthClient';
 | 
				
			|||||||
import ScalarMessaging from '../../../ScalarMessaging';
 | 
					import ScalarMessaging from '../../../ScalarMessaging';
 | 
				
			||||||
import { _t } from '../../../languageHandler';
 | 
					import { _t } from '../../../languageHandler';
 | 
				
			||||||
import WidgetUtils from '../../../utils/WidgetUtils';
 | 
					import WidgetUtils from '../../../utils/WidgetUtils';
 | 
				
			||||||
 | 
					import WidgetEchoStore from "../../../stores/WidgetEchoStore";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The maximum number of widgets that can be added in a room
 | 
					// The maximum number of widgets that can be added in a room
 | 
				
			||||||
const MAX_WIDGETS = 2;
 | 
					const MAX_WIDGETS = 2;
 | 
				
			||||||
@ -57,6 +58,7 @@ module.exports = React.createClass({
 | 
				
			|||||||
    componentWillMount: function() {
 | 
					    componentWillMount: function() {
 | 
				
			||||||
        ScalarMessaging.startListening();
 | 
					        ScalarMessaging.startListening();
 | 
				
			||||||
        MatrixClientPeg.get().on('RoomState.events', this.onRoomStateEvents);
 | 
					        MatrixClientPeg.get().on('RoomState.events', this.onRoomStateEvents);
 | 
				
			||||||
 | 
					        WidgetEchoStore.on('update', this._updateApps);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    componentDidMount: function() {
 | 
					    componentDidMount: function() {
 | 
				
			||||||
@ -82,6 +84,7 @@ module.exports = React.createClass({
 | 
				
			|||||||
        if (MatrixClientPeg.get()) {
 | 
					        if (MatrixClientPeg.get()) {
 | 
				
			||||||
            MatrixClientPeg.get().removeListener('RoomState.events', this.onRoomStateEvents);
 | 
					            MatrixClientPeg.get().removeListener('RoomState.events', this.onRoomStateEvents);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        WidgetEchoStore.removeListener('update', this._updateApps);
 | 
				
			||||||
        dis.unregister(this.dispatcherRef);
 | 
					        dis.unregister(this.dispatcherRef);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -114,8 +117,11 @@ module.exports = React.createClass({
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _getApps: function() {
 | 
					    _getApps: function() {
 | 
				
			||||||
        return WidgetUtils.getRoomWidgets(this.props.room).map((ev) => {
 | 
					        const widgets = WidgetEchoStore.getEchoedRoomWidgets(
 | 
				
			||||||
            return WidgetUtils.makeAppConfig(ev.getStateKey(), ev.getContent(), ev.sender, this.props.room.roomId);
 | 
					            this.props.room.roomId, WidgetUtils.getRoomWidgets(this.props.room),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        return widgets.map((ev) => {
 | 
				
			||||||
 | 
					            return WidgetUtils.makeAppConfig(ev.getStateKey(), ev.getContent(), ev.sender);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -200,10 +206,22 @@ module.exports = React.createClass({
 | 
				
			|||||||
            </div>;
 | 
					            </div>;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let spinner;
 | 
				
			||||||
 | 
					        if (
 | 
				
			||||||
 | 
					            apps.length === 0 && WidgetEchoStore.roomHasPendingWidgets(
 | 
				
			||||||
 | 
					                this.props.room.roomId,
 | 
				
			||||||
 | 
					                WidgetUtils.getRoomWidgets(this.props.room),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
 | 
					            const Loader = sdk.getComponent("elements.Spinner");
 | 
				
			||||||
 | 
					            spinner = <Loader />;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <div className={'mx_AppsDrawer' + (this.props.hide ? ' mx_AppsDrawer_hidden' : '')}>
 | 
					            <div className={'mx_AppsDrawer' + (this.props.hide ? ' mx_AppsDrawer_hidden' : '')}>
 | 
				
			||||||
                <div id='apps' className='mx_AppsContainer'>
 | 
					                <div id='apps' className='mx_AppsContainer'>
 | 
				
			||||||
                    { apps }
 | 
					                    { apps }
 | 
				
			||||||
 | 
					                    { spinner }
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                { this._canUserModify() && addWidget }
 | 
					                { this._canUserModify() && addWidget }
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -42,6 +42,7 @@
 | 
				
			|||||||
    "Could not connect to the integration server": "Could not connect to the integration server",
 | 
					    "Could not connect to the integration server": "Could not connect to the integration server",
 | 
				
			||||||
    "A conference call could not be started because the intgrations server is not available": "A conference call could not be started because the intgrations server is not available",
 | 
					    "A conference call could not be started because the intgrations server is not available": "A conference call could not be started because the intgrations server is not available",
 | 
				
			||||||
    "Call in Progress": "Call in Progress",
 | 
					    "Call in Progress": "Call in Progress",
 | 
				
			||||||
 | 
					    "A call is currently being placed!": "A call is currently being placed!",
 | 
				
			||||||
    "A call is already in progress!": "A call is already in progress!",
 | 
					    "A call is already in progress!": "A call is already in progress!",
 | 
				
			||||||
    "Permission Required": "Permission Required",
 | 
					    "Permission Required": "Permission Required",
 | 
				
			||||||
    "You do not have permission to start a conference call in this room": "You do not have permission to start a conference call in this room",
 | 
					    "You do not have permission to start a conference call in this room": "You do not have permission to start a conference call in this room",
 | 
				
			||||||
@ -695,6 +696,8 @@
 | 
				
			|||||||
    "Delete Widget": "Delete Widget",
 | 
					    "Delete Widget": "Delete Widget",
 | 
				
			||||||
    "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?",
 | 
					    "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?",
 | 
				
			||||||
    "Delete widget": "Delete widget",
 | 
					    "Delete widget": "Delete widget",
 | 
				
			||||||
 | 
					    "Failed to remove widget": "Failed to remove widget",
 | 
				
			||||||
 | 
					    "An error ocurred whilst trying to remove the widget from the room": "An error ocurred whilst trying to remove the widget from the room",
 | 
				
			||||||
    "Revoke widget access": "Revoke widget access",
 | 
					    "Revoke widget access": "Revoke widget access",
 | 
				
			||||||
    "Minimize apps": "Minimize apps",
 | 
					    "Minimize apps": "Minimize apps",
 | 
				
			||||||
    "Reload widget": "Reload widget",
 | 
					    "Reload widget": "Reload widget",
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
Copyright 2017 Vector Creations Ltd
 | 
					Copyright 2017 Vector Creations Ltd
 | 
				
			||||||
Copyright 2017 New Vector Ltd
 | 
					Copyright 2017, 2018 New Vector Ltd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										108
									
								
								src/stores/WidgetEchoStore.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								src/stores/WidgetEchoStore.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,108 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					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 = {
 | 
				
			||||||
 | 
					            // 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.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param {Room} 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 therte'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 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('update');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    removeRoomWidgetEcho(roomId, widgetId) {
 | 
				
			||||||
 | 
					        delete this._roomWidgetEcho[roomId][widgetId];
 | 
				
			||||||
 | 
					        if (Object.keys(this._roomWidgetEcho[roomId]).length === 0) delete this._roomWidgetEcho[roomId];
 | 
				
			||||||
 | 
					        this.emit('update');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let singletonWidgetEchoStore = null;
 | 
				
			||||||
 | 
					if (!singletonWidgetEchoStore) {
 | 
				
			||||||
 | 
					    singletonWidgetEchoStore = new WidgetEchoStore();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					module.exports = singletonWidgetEchoStore;
 | 
				
			||||||
@ -19,6 +19,11 @@ import MatrixClientPeg from '../MatrixClientPeg';
 | 
				
			|||||||
import SdkConfig from "../SdkConfig";
 | 
					import SdkConfig from "../SdkConfig";
 | 
				
			||||||
import dis from '../dispatcher';
 | 
					import dis from '../dispatcher';
 | 
				
			||||||
import * as url from "url";
 | 
					import * as url from "url";
 | 
				
			||||||
 | 
					import WidgetEchoStore from '../stores/WidgetEchoStore';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// How long we wait for the state event echo to come back from the server
 | 
				
			||||||
 | 
					// before waitFor[Room/User]Widget rejects its promise
 | 
				
			||||||
 | 
					const WIDGET_WAIT_TIME = 20000;
 | 
				
			||||||
import SettingsStore from "../settings/SettingsStore";
 | 
					import SettingsStore from "../settings/SettingsStore";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -155,7 +160,7 @@ export default class WidgetUtils {
 | 
				
			|||||||
            const timerId = setTimeout(() => {
 | 
					            const timerId = setTimeout(() => {
 | 
				
			||||||
                MatrixClientPeg.get().removeListener('accountData', onAccountData);
 | 
					                MatrixClientPeg.get().removeListener('accountData', onAccountData);
 | 
				
			||||||
                reject(new Error("Timed out waiting for widget ID " + widgetId + " to appear"));
 | 
					                reject(new Error("Timed out waiting for widget ID " + widgetId + " to appear"));
 | 
				
			||||||
            }, 10000);
 | 
					            }, WIDGET_WAIT_TIME);
 | 
				
			||||||
            MatrixClientPeg.get().on('accountData', onAccountData);
 | 
					            MatrixClientPeg.get().on('accountData', onAccountData);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -208,7 +213,7 @@ export default class WidgetUtils {
 | 
				
			|||||||
            const timerId = setTimeout(() => {
 | 
					            const timerId = setTimeout(() => {
 | 
				
			||||||
                MatrixClientPeg.get().removeListener('RoomState.events', onRoomStateEvents);
 | 
					                MatrixClientPeg.get().removeListener('RoomState.events', onRoomStateEvents);
 | 
				
			||||||
                reject(new Error("Timed out waiting for widget ID " + widgetId + " to appear"));
 | 
					                reject(new Error("Timed out waiting for widget ID " + widgetId + " to appear"));
 | 
				
			||||||
            }, 10000);
 | 
					            }, WIDGET_WAIT_TIME);
 | 
				
			||||||
            MatrixClientPeg.get().on('RoomState.events', onRoomStateEvents);
 | 
					            MatrixClientPeg.get().on('RoomState.events', onRoomStateEvents);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -271,11 +276,15 @@ export default class WidgetUtils {
 | 
				
			|||||||
            content = {};
 | 
					            content = {};
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        WidgetEchoStore.setRoomWidgetEcho(roomId, widgetId, content);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const client = MatrixClientPeg.get();
 | 
					        const client = MatrixClientPeg.get();
 | 
				
			||||||
        // TODO - Room widgets need to be moved to 'm.widget' state events
 | 
					        // TODO - Room widgets need to be moved to 'm.widget' state events
 | 
				
			||||||
        // https://docs.google.com/document/d/1uPF7XWY_dXTKVKV7jZQ2KmsI19wn9-kFRgQ1tFQP7wQ/edit?usp=sharing
 | 
					        // https://docs.google.com/document/d/1uPF7XWY_dXTKVKV7jZQ2KmsI19wn9-kFRgQ1tFQP7wQ/edit?usp=sharing
 | 
				
			||||||
        return client.sendStateEvent(roomId, "im.vector.modular.widgets", content, widgetId).then(() => {
 | 
					        return client.sendStateEvent(roomId, "im.vector.modular.widgets", content, widgetId).then(() => {
 | 
				
			||||||
            return WidgetUtils.waitForRoomWidget(widgetId, roomId, addingWidget);
 | 
					            return WidgetUtils.waitForRoomWidget(widgetId, roomId, addingWidget);
 | 
				
			||||||
 | 
					        }).finally(() => {
 | 
				
			||||||
 | 
					            WidgetEchoStore.removeRoomWidgetEcho(roomId, widgetId);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user