Simplify & refactor some widget stuff
* ScalarMessaging onMessage was getting the current room ID by listening for view_and remembering the room id or alias, and so having to look up the alias if it was alias. We have RoomViewStore for this. * Move waitForUserWidget into WidgetUtils * s/require/import/
This commit is contained in:
parent
e858cf3bcb
commit
1cb794753e
2 changed files with 106 additions and 133 deletions
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2016 OpenMarket Ltd
|
Copyright 2016 OpenMarket Ltd
|
||||||
Copyright 2017 Vector Creations Ltd
|
Copyright 2017 Vector Creations Ltd
|
||||||
|
Copyright 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.
|
||||||
|
@ -231,11 +232,12 @@ Example:
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const SdkConfig = require('./SdkConfig');
|
import SdkConfig from './SdkConfig';
|
||||||
const MatrixClientPeg = require("./MatrixClientPeg");
|
import MatrixClientPeg from './MatrixClientPeg';
|
||||||
const MatrixEvent = require("matrix-js-sdk").MatrixEvent;
|
import { MatrixEvent } from 'matrix-js-sdk';
|
||||||
const dis = require("./dispatcher");
|
import dis from './dispatcher';
|
||||||
const Widgets = require('./utils/widgets');
|
import Widgets from './utils/widgets';
|
||||||
|
import RoomViewStore from './stores/RoomViewStore';
|
||||||
import { _t } from './languageHandler';
|
import { _t } from './languageHandler';
|
||||||
|
|
||||||
function sendResponse(event, res) {
|
function sendResponse(event, res) {
|
||||||
|
@ -286,51 +288,6 @@ function inviteUser(event, roomId, userId) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a promise that resolves when a widget with the given
|
|
||||||
* ID has been added as a user widget (ie. the accountData event
|
|
||||||
* arrives) or rejects after a timeout
|
|
||||||
*
|
|
||||||
* @param {string} widgetId The ID of the widget to wait for
|
|
||||||
* @param {boolean} add True to wait for the widget to be added,
|
|
||||||
* false to wait for it to be deleted.
|
|
||||||
* @returns {Promise} that resolves when the widget is available
|
|
||||||
*/
|
|
||||||
function waitForUserWidget(widgetId, add) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const currentAccountDataEvent = MatrixClientPeg.get().getAccountData('m.widgets');
|
|
||||||
|
|
||||||
// Tests an account data event, returning true if it's in the state
|
|
||||||
// we're waiting for it to be in
|
|
||||||
function eventInIntendedState(ev) {
|
|
||||||
if (!ev || !currentAccountDataEvent.getContent()) return false;
|
|
||||||
if (add) {
|
|
||||||
return ev.getContent()[widgetId] !== undefined;
|
|
||||||
} else {
|
|
||||||
return ev.getContent()[widgetId] === undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eventInIntendedState(currentAccountDataEvent)) {
|
|
||||||
resolve();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onAccountData(ev) {
|
|
||||||
if (eventInIntendedState(currentAccountDataEvent)) {
|
|
||||||
MatrixClientPeg.get().removeListener('accountData', onAccountData);
|
|
||||||
clearTimeout(timerId);
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const timerId = setTimeout(() => {
|
|
||||||
MatrixClientPeg.get().removeListener('accountData', onAccountData);
|
|
||||||
reject(new Error("Timed out waiting for widget ID " + widgetId + " to appear"));
|
|
||||||
}, 10000);
|
|
||||||
MatrixClientPeg.get().on('accountData', onAccountData);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function setWidget(event, roomId) {
|
function setWidget(event, roomId) {
|
||||||
const widgetId = event.data.widget_id;
|
const widgetId = event.data.widget_id;
|
||||||
const widgetType = event.data.type;
|
const widgetType = event.data.type;
|
||||||
|
@ -637,19 +594,6 @@ function returnStateEvent(event, roomId, eventType, stateKey) {
|
||||||
sendResponse(event, stateEvent.getContent());
|
sendResponse(event, stateEvent.getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
let currentRoomId = null;
|
|
||||||
let currentRoomAlias = null;
|
|
||||||
|
|
||||||
// Listen for when a room is viewed
|
|
||||||
dis.register(onAction);
|
|
||||||
function onAction(payload) {
|
|
||||||
if (payload.action !== "view_room") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
currentRoomId = payload.room_id;
|
|
||||||
currentRoomAlias = payload.room_alias;
|
|
||||||
}
|
|
||||||
|
|
||||||
const onMessage = function(event) {
|
const onMessage = function(event) {
|
||||||
if (!event.origin) { // stupid chrome
|
if (!event.origin) { // stupid chrome
|
||||||
event.origin = event.originalEvent.origin;
|
event.origin = event.originalEvent.origin;
|
||||||
|
@ -700,80 +644,63 @@ const onMessage = function(event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let promise = Promise.resolve(currentRoomId);
|
|
||||||
if (!currentRoomId) {
|
if (roomId !== RoomViewStore.getRoomId()) {
|
||||||
if (!currentRoomAlias) {
|
sendError(event, _t('Room %(roomId)s not visible', {roomId: roomId}));
|
||||||
sendError(event, _t('Must be viewing a room'));
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
// no room ID but there is an alias, look it up.
|
|
||||||
console.log("Looking up alias " + currentRoomAlias);
|
|
||||||
promise = MatrixClientPeg.get().getRoomIdForAlias(currentRoomAlias).then((res) => {
|
|
||||||
return res.room_id;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
promise.then((viewingRoomId) => {
|
// Get and set room-based widgets
|
||||||
if (roomId !== viewingRoomId) {
|
if (event.data.action === "get_widgets") {
|
||||||
sendError(event, _t('Room %(roomId)s not visible', {roomId: roomId}));
|
getWidgets(event, roomId);
|
||||||
return;
|
return;
|
||||||
}
|
} else if (event.data.action === "set_widget") {
|
||||||
|
setWidget(event, roomId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get and set room-based widgets
|
// These APIs don't require userId
|
||||||
if (event.data.action === "get_widgets") {
|
if (event.data.action === "join_rules_state") {
|
||||||
getWidgets(event, roomId);
|
getJoinRules(event, roomId);
|
||||||
return;
|
return;
|
||||||
} else if (event.data.action === "set_widget") {
|
} else if (event.data.action === "set_plumbing_state") {
|
||||||
setWidget(event, roomId);
|
setPlumbingState(event, roomId, event.data.status);
|
||||||
return;
|
return;
|
||||||
}
|
} else if (event.data.action === "get_membership_count") {
|
||||||
|
getMembershipCount(event, roomId);
|
||||||
|
return;
|
||||||
|
} else if (event.data.action === "get_room_enc_state") {
|
||||||
|
getRoomEncState(event, roomId);
|
||||||
|
return;
|
||||||
|
} else if (event.data.action === "can_send_event") {
|
||||||
|
canSendEvent(event, roomId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// These APIs don't require userId
|
if (!userId) {
|
||||||
if (event.data.action === "join_rules_state") {
|
sendError(event, _t('Missing user_id in request'));
|
||||||
getJoinRules(event, roomId);
|
return;
|
||||||
return;
|
}
|
||||||
} else if (event.data.action === "set_plumbing_state") {
|
switch (event.data.action) {
|
||||||
setPlumbingState(event, roomId, event.data.status);
|
case "membership_state":
|
||||||
return;
|
getMembershipState(event, roomId, userId);
|
||||||
} else if (event.data.action === "get_membership_count") {
|
break;
|
||||||
getMembershipCount(event, roomId);
|
case "invite":
|
||||||
return;
|
inviteUser(event, roomId, userId);
|
||||||
} else if (event.data.action === "get_room_enc_state") {
|
break;
|
||||||
getRoomEncState(event, roomId);
|
case "bot_options":
|
||||||
return;
|
botOptions(event, roomId, userId);
|
||||||
} else if (event.data.action === "can_send_event") {
|
break;
|
||||||
canSendEvent(event, roomId);
|
case "set_bot_options":
|
||||||
return;
|
setBotOptions(event, roomId, userId);
|
||||||
}
|
break;
|
||||||
|
case "set_bot_power":
|
||||||
if (!userId) {
|
setBotPower(event, roomId, userId, event.data.level);
|
||||||
sendError(event, _t('Missing user_id in request'));
|
break;
|
||||||
return;
|
default:
|
||||||
}
|
console.warn("Unhandled postMessage event with action '" + event.data.action +"'");
|
||||||
switch (event.data.action) {
|
break;
|
||||||
case "membership_state":
|
}
|
||||||
getMembershipState(event, roomId, userId);
|
|
||||||
break;
|
|
||||||
case "invite":
|
|
||||||
inviteUser(event, roomId, userId);
|
|
||||||
break;
|
|
||||||
case "bot_options":
|
|
||||||
botOptions(event, roomId, userId);
|
|
||||||
break;
|
|
||||||
case "set_bot_options":
|
|
||||||
setBotOptions(event, roomId, userId);
|
|
||||||
break;
|
|
||||||
case "set_bot_power":
|
|
||||||
setBotPower(event, roomId, userId, event.data.level);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.warn("Unhandled postMessage event with action '" + event.data.action +"'");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}, (err) => {
|
|
||||||
console.error(err);
|
|
||||||
sendError(event, _t('Failed to lookup current room') + '.');
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let listenerCount = 0;
|
let listenerCount = 0;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2017 Vector Creations Ltd
|
Copyright 2017 Vector Creations Ltd
|
||||||
|
Copyright 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.
|
||||||
|
@ -90,4 +91,49 @@ export default class WidgetUtils {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a promise that resolves when a widget with the given
|
||||||
|
* ID has been added as a user widget (ie. the accountData event
|
||||||
|
* arrives) or rejects after a timeout
|
||||||
|
*
|
||||||
|
* @param {string} widgetId The ID of the widget to wait for
|
||||||
|
* @param {boolean} add True to wait for the widget to be added,
|
||||||
|
* false to wait for it to be deleted.
|
||||||
|
* @returns {Promise} that resolves when the widget is available
|
||||||
|
*/
|
||||||
|
static waitForUserWidget(widgetId, add) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const currentAccountDataEvent = MatrixClientPeg.get().getAccountData('m.widgets');
|
||||||
|
|
||||||
|
// Tests an account data event, returning true if it's in the state
|
||||||
|
// we're waiting for it to be in
|
||||||
|
function eventInIntendedState(ev) {
|
||||||
|
if (!ev || !currentAccountDataEvent.getContent()) return false;
|
||||||
|
if (add) {
|
||||||
|
return ev.getContent()[widgetId] !== undefined;
|
||||||
|
} else {
|
||||||
|
return ev.getContent()[widgetId] === undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eventInIntendedState(currentAccountDataEvent)) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onAccountData(ev) {
|
||||||
|
if (eventInIntendedState(currentAccountDataEvent)) {
|
||||||
|
MatrixClientPeg.get().removeListener('accountData', onAccountData);
|
||||||
|
clearTimeout(timerId);
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const timerId = setTimeout(() => {
|
||||||
|
MatrixClientPeg.get().removeListener('accountData', onAccountData);
|
||||||
|
reject(new Error("Timed out waiting for widget ID " + widgetId + " to appear"));
|
||||||
|
}, 10000);
|
||||||
|
MatrixClientPeg.get().on('accountData', onAccountData);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue