Merge branches 'develop' and 't3chguy/remove_bluebird' of github.com:matrix-org/matrix-react-sdk into t3chguy/remove_bluebird
This commit is contained in:
commit
d3f872bf7a
24 changed files with 262 additions and 107 deletions
|
@ -133,6 +133,7 @@
|
|||
"eslint": "^5.12.0",
|
||||
"eslint-config-google": "^0.7.1",
|
||||
"eslint-plugin-babel": "^5.2.1",
|
||||
"eslint-plugin-jest": "^23.0.4",
|
||||
"eslint-plugin-flowtype": "^2.30.0",
|
||||
"eslint-plugin-react": "^7.7.0",
|
||||
"eslint-plugin-react-hooks": "^2.0.1",
|
||||
|
|
|
@ -23,10 +23,6 @@ limitations under the License.
|
|||
padding-left: 84px;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_wrapper.mx_MessageComposer_hasE2EIcon {
|
||||
padding-left: 109px;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_replaced_wrapper {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
@ -78,10 +74,10 @@ limitations under the License.
|
|||
.mx_MessageComposer_e2eIcon.mx_E2EIcon {
|
||||
position: absolute;
|
||||
left: 60px;
|
||||
|
||||
&::after {
|
||||
background-color: $composer-e2e-icon-color;
|
||||
}
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 0; // Counteract the E2EIcon class
|
||||
margin-left: 3px; // Counteract the E2EIcon class
|
||||
}
|
||||
|
||||
.mx_MessageComposer_noperm_error {
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -57,7 +57,7 @@ import { ValidatedServerConfig } from "../../utils/AutoDiscoveryUtils";
|
|||
import AutoDiscoveryUtils from "../../utils/AutoDiscoveryUtils";
|
||||
import DMRoomMap from '../../utils/DMRoomMap';
|
||||
import { countRoomsWithNotif } from '../../RoomNotifs';
|
||||
import { setTheme } from "../../theme";
|
||||
import { ThemeWatcher } from "../../theme";
|
||||
import { storeRoomAliasInCache } from '../../RoomAliasCache';
|
||||
import { defer } from "../../utils/promise";
|
||||
|
||||
|
@ -268,7 +268,8 @@ export default createReactClass({
|
|||
|
||||
componentDidMount: function() {
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
this._themeWatchRef = SettingsStore.watchSetting("theme", null, this._onThemeChanged);
|
||||
this._themeWatcher = new ThemeWatcher();
|
||||
this._themeWatcher.start();
|
||||
|
||||
this.focusComposer = false;
|
||||
|
||||
|
@ -355,7 +356,7 @@ export default createReactClass({
|
|||
componentWillUnmount: function() {
|
||||
Lifecycle.stopMatrixClient();
|
||||
dis.unregister(this.dispatcherRef);
|
||||
SettingsStore.unwatchSetting(this._themeWatchRef);
|
||||
this._themeWatcher.stop();
|
||||
window.removeEventListener("focus", this.onFocus);
|
||||
window.removeEventListener('resize', this.handleResize);
|
||||
this.state.resizeNotifier.removeListener("middlePanelResized", this._dispatchTimelineResize);
|
||||
|
@ -378,13 +379,6 @@ export default createReactClass({
|
|||
}
|
||||
},
|
||||
|
||||
_onThemeChanged: function(settingName, roomId, atLevel, newValue) {
|
||||
dis.dispatch({
|
||||
action: 'set_theme',
|
||||
value: newValue,
|
||||
});
|
||||
},
|
||||
|
||||
startPageChangeTimer() {
|
||||
// Tor doesn't support performance
|
||||
if (!performance || !performance.mark) return null;
|
||||
|
@ -666,9 +660,6 @@ export default createReactClass({
|
|||
});
|
||||
break;
|
||||
}
|
||||
case 'set_theme':
|
||||
setTheme(payload.value);
|
||||
break;
|
||||
case 'on_logging_in':
|
||||
// We are now logging in, so set the state to reflect that
|
||||
// NB. This does not touch 'ready' since if our dispatches
|
||||
|
|
|
@ -34,7 +34,7 @@ import dis from '../../../dispatcher';
|
|||
import ActiveWidgetStore from '../../../stores/ActiveWidgetStore';
|
||||
import classNames from 'classnames';
|
||||
import {IntegrationManagers} from "../../../integrations/IntegrationManagers";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
|
||||
const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:'];
|
||||
const ENABLE_REACT_PERF = false;
|
||||
|
@ -69,8 +69,11 @@ export default class AppTile extends React.Component {
|
|||
* @return {Object} Updated component state to be set with setState
|
||||
*/
|
||||
_getNewState(newProps) {
|
||||
const widgetPermissionId = [newProps.room.roomId, encodeURIComponent(newProps.url)].join('_');
|
||||
const hasPermissionToLoad = localStorage.getItem(widgetPermissionId);
|
||||
// This is a function to make the impact of calling SettingsStore slightly less
|
||||
const hasPermissionToLoad = () => {
|
||||
const currentlyAllowedWidgets = SettingsStore.getValue("allowedWidgets", newProps.room.roomId);
|
||||
return !!currentlyAllowedWidgets[newProps.eventId];
|
||||
};
|
||||
|
||||
const PersistedElement = sdk.getComponent("elements.PersistedElement");
|
||||
return {
|
||||
|
@ -78,10 +81,9 @@ export default class AppTile extends React.Component {
|
|||
// True while the iframe content is loading
|
||||
loading: this.props.waitForIframeLoad && !PersistedElement.isMounted(this._persistKey),
|
||||
widgetUrl: this._addWurlParams(newProps.url),
|
||||
widgetPermissionId: widgetPermissionId,
|
||||
// Assume that widget has permission to load if we are the user who
|
||||
// added it to the room, or if explicitly granted by the user
|
||||
hasPermissionToLoad: hasPermissionToLoad === 'true' || newProps.userId === newProps.creatorUserId,
|
||||
hasPermissionToLoad: newProps.userId === newProps.creatorUserId || hasPermissionToLoad(),
|
||||
error: null,
|
||||
deleting: false,
|
||||
widgetPageTitle: newProps.widgetPageTitle,
|
||||
|
@ -446,24 +448,38 @@ export default class AppTile extends React.Component {
|
|||
});
|
||||
}
|
||||
|
||||
/* TODO -- Store permission in account data so that it is persisted across multiple devices */
|
||||
_grantWidgetPermission() {
|
||||
console.warn('Granting permission to load widget - ', this.state.widgetUrl);
|
||||
localStorage.setItem(this.state.widgetPermissionId, true);
|
||||
this.setState({hasPermissionToLoad: true});
|
||||
// Now that we have permission, fetch the IM token
|
||||
this.setScalarToken();
|
||||
const roomId = this.props.room.roomId;
|
||||
console.info("Granting permission for widget to load: " + this.props.eventId);
|
||||
const current = SettingsStore.getValue("allowedWidgets", roomId);
|
||||
current[this.props.eventId] = true;
|
||||
SettingsStore.setValue("allowedWidgets", roomId, SettingLevel.ROOM_ACCOUNT, current).then(() => {
|
||||
this.setState({hasPermissionToLoad: true});
|
||||
|
||||
// Fetch a token for the integration manager, now that we're allowed to
|
||||
this.setScalarToken();
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
// We don't really need to do anything about this - the user will just hit the button again.
|
||||
});
|
||||
}
|
||||
|
||||
_revokeWidgetPermission() {
|
||||
console.warn('Revoking permission to load widget - ', this.state.widgetUrl);
|
||||
localStorage.removeItem(this.state.widgetPermissionId);
|
||||
this.setState({hasPermissionToLoad: false});
|
||||
const roomId = this.props.room.roomId;
|
||||
console.info("Revoking permission for widget to load: " + this.props.eventId);
|
||||
const current = SettingsStore.getValue("allowedWidgets", roomId);
|
||||
current[this.props.eventId] = false;
|
||||
SettingsStore.setValue("allowedWidgets", roomId, SettingLevel.ROOM_ACCOUNT, current).then(() => {
|
||||
this.setState({hasPermissionToLoad: false});
|
||||
|
||||
// Force the widget to be non-persistent
|
||||
ActiveWidgetStore.destroyPersistentWidget(this.props.id);
|
||||
const PersistedElement = sdk.getComponent("elements.PersistedElement");
|
||||
PersistedElement.destroyElement(this._persistKey);
|
||||
// Force the widget to be non-persistent (able to be deleted/forgotten)
|
||||
ActiveWidgetStore.destroyPersistentWidget(this.props.id);
|
||||
const PersistedElement = sdk.getComponent("elements.PersistedElement");
|
||||
PersistedElement.destroyElement(this._persistKey);
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
// We don't really need to do anything about this - the user will just hit the button again.
|
||||
});
|
||||
}
|
||||
|
||||
formatAppTileName() {
|
||||
|
@ -720,6 +736,7 @@ AppTile.displayName ='AppTile';
|
|||
|
||||
AppTile.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
eventId: PropTypes.string, // required for room widgets
|
||||
url: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
room: PropTypes.object.isRequired,
|
||||
|
|
|
@ -67,13 +67,15 @@ module.exports = createReactClass({
|
|||
return ev.getStateKey() === ActiveWidgetStore.getPersistentWidgetId();
|
||||
});
|
||||
const app = WidgetUtils.makeAppConfig(
|
||||
appEvent.getStateKey(), appEvent.getContent(), appEvent.getSender(), persistentWidgetInRoomId,
|
||||
appEvent.getStateKey(), appEvent.getContent(), appEvent.getSender(),
|
||||
persistentWidgetInRoomId, appEvent.getId(),
|
||||
);
|
||||
const capWhitelist = WidgetUtils.getCapWhitelistForAppTypeInRoomId(app.type, persistentWidgetInRoomId);
|
||||
const AppTile = sdk.getComponent('elements.AppTile');
|
||||
return <AppTile
|
||||
key={app.id}
|
||||
id={app.id}
|
||||
eventId={app.eventId}
|
||||
url={app.url}
|
||||
name={app.name}
|
||||
type={app.type}
|
||||
|
|
|
@ -43,7 +43,8 @@ export default class ReactionsRowButtonTooltip extends React.PureComponent {
|
|||
if (room) {
|
||||
const senders = [];
|
||||
for (const reactionEvent of reactionEvents) {
|
||||
const { name } = room.getMember(reactionEvent.getSender());
|
||||
const member = room.getMember(reactionEvent.getSender());
|
||||
const name = member ? member.name : reactionEvent.getSender();
|
||||
senders.push(name);
|
||||
}
|
||||
const shortName = unicodeToShortcode(content);
|
||||
|
|
|
@ -107,7 +107,9 @@ module.exports = createReactClass({
|
|||
this.props.room.roomId, WidgetUtils.getRoomWidgets(this.props.room),
|
||||
);
|
||||
return widgets.map((ev) => {
|
||||
return WidgetUtils.makeAppConfig(ev.getStateKey(), ev.getContent(), ev.getSender());
|
||||
return WidgetUtils.makeAppConfig(
|
||||
ev.getStateKey(), ev.getContent(), ev.getSender(), ev.getRoomId(), ev.getId(),
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -159,6 +161,7 @@ module.exports = createReactClass({
|
|||
return (<AppTile
|
||||
key={app.id}
|
||||
id={app.id}
|
||||
eventId={app.eventId}
|
||||
url={app.url}
|
||||
name={app.name}
|
||||
type={app.type}
|
||||
|
|
|
@ -25,7 +25,6 @@ import RoomViewStore from '../../../stores/RoomViewStore';
|
|||
import Stickerpicker from './Stickerpicker';
|
||||
import { makeRoomPermalink } from '../../../utils/permalinks/Permalinks';
|
||||
import ContentMessages from '../../../ContentMessages';
|
||||
import classNames from 'classnames';
|
||||
import E2EIcon from './E2EIcon';
|
||||
|
||||
function ComposerAvatar(props) {
|
||||
|
@ -353,13 +352,9 @@ export default class MessageComposer extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
const wrapperClasses = classNames({
|
||||
mx_MessageComposer_wrapper: true,
|
||||
mx_MessageComposer_hasE2EIcon: !!this.props.e2eStatus,
|
||||
});
|
||||
return (
|
||||
<div className="mx_MessageComposer">
|
||||
<div className={wrapperClasses}>
|
||||
<div className="mx_MessageComposer_wrapper">
|
||||
<div className="mx_MessageComposer_row">
|
||||
{ controls }
|
||||
</div>
|
||||
|
|
|
@ -460,13 +460,9 @@ export default class SlateMessageComposer extends React.Component {
|
|||
|
||||
const showFormatBar = this.state.showFormatting && this.state.inputState.isRichTextEnabled;
|
||||
|
||||
const wrapperClasses = classNames({
|
||||
mx_MessageComposer_wrapper: true,
|
||||
mx_MessageComposer_hasE2EIcon: !!this.props.e2eStatus,
|
||||
});
|
||||
return (
|
||||
<div className="mx_MessageComposer">
|
||||
<div className={wrapperClasses}>
|
||||
<div className="mx_MessageComposer_wrapper">
|
||||
<div className="mx_MessageComposer_row">
|
||||
{ controls }
|
||||
</div>
|
||||
|
|
|
@ -27,7 +27,7 @@ import LanguageDropdown from "../../../elements/LanguageDropdown";
|
|||
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||
import DeactivateAccountDialog from "../../../dialogs/DeactivateAccountDialog";
|
||||
import PropTypes from "prop-types";
|
||||
import {enumerateThemes} from "../../../../../theme";
|
||||
import {enumerateThemes, ThemeWatcher} from "../../../../../theme";
|
||||
import PlatformPeg from "../../../../../PlatformPeg";
|
||||
import MatrixClientPeg from "../../../../../MatrixClientPeg";
|
||||
import sdk from "../../../../..";
|
||||
|
@ -50,6 +50,7 @@ export default class GeneralUserSettingsTab extends React.Component {
|
|||
this.state = {
|
||||
language: languageHandler.getCurrentLanguage(),
|
||||
theme: SettingsStore.getValueAt(SettingLevel.ACCOUNT, "theme"),
|
||||
useSystemTheme: SettingsStore.getValueAt(SettingLevel.DEVICE, "use_system_theme"),
|
||||
haveIdServer: Boolean(MatrixClientPeg.get().getIdentityServerUrl()),
|
||||
serverSupportsSeparateAddAndBind: null,
|
||||
idServerHasUnsignedTerms: false,
|
||||
|
@ -177,16 +178,25 @@ export default class GeneralUserSettingsTab extends React.Component {
|
|||
// so remember what the value was before we tried to set it so we can revert
|
||||
const oldTheme = SettingsStore.getValue('theme');
|
||||
SettingsStore.setValue("theme", null, SettingLevel.ACCOUNT, newTheme).catch(() => {
|
||||
dis.dispatch({action: 'set_theme', value: oldTheme});
|
||||
dis.dispatch({action: 'recheck_theme'});
|
||||
this.setState({theme: oldTheme});
|
||||
});
|
||||
this.setState({theme: newTheme});
|
||||
// The settings watcher doesn't fire until the echo comes back from the
|
||||
// server, so to make the theme change immediately we need to manually
|
||||
// do the dispatch now
|
||||
dis.dispatch({action: 'set_theme', value: newTheme});
|
||||
// XXX: The local echoed value appears to be unreliable, in particular
|
||||
// when settings custom themes(!) so adding forceTheme to override
|
||||
// the value from settings.
|
||||
dis.dispatch({action: 'recheck_theme', forceTheme: newTheme});
|
||||
};
|
||||
|
||||
_onUseSystemThemeChanged = (checked) => {
|
||||
this.setState({useSystemTheme: checked});
|
||||
dis.dispatch({action: 'recheck_theme'});
|
||||
}
|
||||
|
||||
|
||||
_onPasswordChangeError = (err) => {
|
||||
// TODO: Figure out a design that doesn't involve replacing the current dialog
|
||||
let errMsg = err.error || "";
|
||||
|
@ -297,11 +307,24 @@ export default class GeneralUserSettingsTab extends React.Component {
|
|||
|
||||
_renderThemeSection() {
|
||||
const SettingsFlag = sdk.getComponent("views.elements.SettingsFlag");
|
||||
|
||||
const themeWatcher = new ThemeWatcher();
|
||||
let systemThemeSection;
|
||||
if (themeWatcher.isSystemThemeSupported()) {
|
||||
systemThemeSection = <div>
|
||||
<SettingsFlag name="use_system_theme" level={SettingLevel.DEVICE}
|
||||
onChange={this._onUseSystemThemeChanged}
|
||||
/>
|
||||
</div>;
|
||||
}
|
||||
return (
|
||||
<div className="mx_SettingsTab_section mx_GeneralUserSettingsTab_themeSection">
|
||||
<span className="mx_SettingsTab_subheading">{_t("Theme")}</span>
|
||||
{systemThemeSection}
|
||||
<Field id="theme" label={_t("Theme")} element="select"
|
||||
value={this.state.theme} onChange={this._onThemeChange}>
|
||||
value={this.state.theme} onChange={this._onThemeChange}
|
||||
disabled={this.state.useSystemTheme}
|
||||
>
|
||||
{Object.entries(enumerateThemes()).map(([theme, text]) => {
|
||||
return <option key={theme} value={theme}>{text}</option>;
|
||||
})}
|
||||
|
|
|
@ -364,6 +364,7 @@
|
|||
"Automatically replace plain text Emoji": "Automatically replace plain text Emoji",
|
||||
"Mirror local video feed": "Mirror local video feed",
|
||||
"Enable Community Filter Panel": "Enable Community Filter Panel",
|
||||
"Match system dark mode setting": "Match system dark mode setting",
|
||||
"Allow Peer-to-Peer for 1:1 calls": "Allow Peer-to-Peer for 1:1 calls",
|
||||
"Send analytics data": "Send analytics data",
|
||||
"Never send encrypted messages to unverified devices from this device": "Never send encrypted messages to unverified devices from this device",
|
||||
|
|
|
@ -281,6 +281,11 @@ export const SETTINGS = {
|
|||
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||
default: [],
|
||||
},
|
||||
"use_system_theme": {
|
||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||
default: true,
|
||||
displayName: _td("Match system dark mode setting"),
|
||||
},
|
||||
"webRtcAllowPeerToPeer": {
|
||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
|
||||
displayName: _td('Allow Peer-to-Peer for 1:1 calls'),
|
||||
|
|
149
src/theme.js
149
src/theme.js
|
@ -19,8 +19,75 @@ import {_t} from "./languageHandler";
|
|||
|
||||
export const DEFAULT_THEME = "light";
|
||||
import Tinter from "./Tinter";
|
||||
import dis from "./dispatcher";
|
||||
import SettingsStore from "./settings/SettingsStore";
|
||||
|
||||
export class ThemeWatcher {
|
||||
static _instance = null;
|
||||
|
||||
constructor() {
|
||||
this._themeWatchRef = null;
|
||||
this._systemThemeWatchRef = null;
|
||||
this._dispatcherRef = null;
|
||||
|
||||
// we have both here as each may either match or not match, so by having both
|
||||
// we can get the tristate of dark/light/unsupported
|
||||
this._preferDark = global.matchMedia("(prefers-color-scheme: dark)");
|
||||
this._preferLight = global.matchMedia("(prefers-color-scheme: light)");
|
||||
|
||||
this._currentTheme = this.getEffectiveTheme();
|
||||
}
|
||||
|
||||
start() {
|
||||
this._themeWatchRef = SettingsStore.watchSetting("theme", null, this._onChange);
|
||||
this._systemThemeWatchRef = SettingsStore.watchSetting("use_system_theme", null, this._onChange);
|
||||
this._preferDark.addEventListener('change', this._onChange);
|
||||
this._preferLight.addEventListener('change', this._onChange);
|
||||
this._dispatcherRef = dis.register(this._onAction);
|
||||
}
|
||||
|
||||
stop() {
|
||||
this._preferDark.removeEventListener('change', this._onChange);
|
||||
this._preferLight.removeEventListener('change', this._onChange);
|
||||
SettingsStore.unwatchSetting(this._systemThemeWatchRef);
|
||||
SettingsStore.unwatchSetting(this._themeWatchRef);
|
||||
dis.unregister(this._dispatcherRef);
|
||||
}
|
||||
|
||||
_onChange = () => {
|
||||
this.recheck();
|
||||
}
|
||||
|
||||
_onAction = (payload) => {
|
||||
if (payload.action === 'recheck_theme') {
|
||||
// XXX forceTheme
|
||||
this.recheck(payload.forceTheme);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: forceTheme param aded here as local echo appears to be unreliable
|
||||
// https://github.com/vector-im/riot-web/issues/11443
|
||||
recheck(forceTheme) {
|
||||
const oldTheme = this._currentTheme;
|
||||
this._currentTheme = forceTheme === undefined ? this.getEffectiveTheme() : forceTheme;
|
||||
if (oldTheme !== this._currentTheme) {
|
||||
setTheme(this._currentTheme);
|
||||
}
|
||||
}
|
||||
|
||||
getEffectiveTheme() {
|
||||
if (SettingsStore.getValue('use_system_theme')) {
|
||||
if (this._preferDark.matches) return 'dark';
|
||||
if (this._preferLight.matches) return 'light';
|
||||
}
|
||||
return SettingsStore.getValue('theme');
|
||||
}
|
||||
|
||||
isSystemThemeSupported() {
|
||||
return this._preferDark.matches || this._preferLight.matches;
|
||||
}
|
||||
}
|
||||
|
||||
export function enumerateThemes() {
|
||||
const BUILTIN_THEMES = {
|
||||
"light": _t("Light theme"),
|
||||
|
@ -60,30 +127,17 @@ function getCustomTheme(themeName) {
|
|||
return customTheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying theme name for the given theme. This is usually the theme or
|
||||
* CSS resource that the theme relies upon to load.
|
||||
* @param {string} theme The theme name to get the base of.
|
||||
* @returns {string} The base theme (typically "light" or "dark").
|
||||
*/
|
||||
export function getBaseTheme(theme) {
|
||||
if (!theme) return "light";
|
||||
if (theme.startsWith("custom-")) {
|
||||
const customTheme = getCustomTheme(theme.substr(7));
|
||||
return customTheme.is_dark ? "dark-custom" : "light-custom";
|
||||
}
|
||||
|
||||
return theme; // it's probably a base theme
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever someone changes the theme
|
||||
* Async function that returns once the theme has been set
|
||||
* (ie. the CSS has been loaded)
|
||||
*
|
||||
* @param {string} theme new theme
|
||||
*/
|
||||
export function setTheme(theme) {
|
||||
export async function setTheme(theme) {
|
||||
if (!theme) {
|
||||
theme = SettingsStore.getValue("theme");
|
||||
const themeWatcher = new ThemeWatcher();
|
||||
theme = themeWatcher.getEffectiveTheme();
|
||||
}
|
||||
let stylesheetName = theme;
|
||||
if (theme.startsWith("custom-")) {
|
||||
|
@ -122,38 +176,41 @@ export function setTheme(theme) {
|
|||
|
||||
styleElements[stylesheetName].disabled = false;
|
||||
|
||||
const switchTheme = function() {
|
||||
// we re-enable our theme here just in case we raced with another
|
||||
// theme set request as per https://github.com/vector-im/riot-web/issues/5601.
|
||||
// We could alternatively lock or similar to stop the race, but
|
||||
// this is probably good enough for now.
|
||||
styleElements[stylesheetName].disabled = false;
|
||||
Object.values(styleElements).forEach((a) => {
|
||||
if (a == styleElements[stylesheetName]) return;
|
||||
a.disabled = true;
|
||||
});
|
||||
Tinter.setTheme(theme);
|
||||
};
|
||||
return new Promise((resolve) => {
|
||||
const switchTheme = function() {
|
||||
// we re-enable our theme here just in case we raced with another
|
||||
// theme set request as per https://github.com/vector-im/riot-web/issues/5601.
|
||||
// We could alternatively lock or similar to stop the race, but
|
||||
// this is probably good enough for now.
|
||||
styleElements[stylesheetName].disabled = false;
|
||||
Object.values(styleElements).forEach((a) => {
|
||||
if (a == styleElements[stylesheetName]) return;
|
||||
a.disabled = true;
|
||||
});
|
||||
Tinter.setTheme(theme);
|
||||
resolve();
|
||||
};
|
||||
|
||||
// turns out that Firefox preloads the CSS for link elements with
|
||||
// the disabled attribute, but Chrome doesn't.
|
||||
// turns out that Firefox preloads the CSS for link elements with
|
||||
// the disabled attribute, but Chrome doesn't.
|
||||
|
||||
let cssLoaded = false;
|
||||
let cssLoaded = false;
|
||||
|
||||
styleElements[stylesheetName].onload = () => {
|
||||
switchTheme();
|
||||
};
|
||||
styleElements[stylesheetName].onload = () => {
|
||||
switchTheme();
|
||||
};
|
||||
|
||||
for (let i = 0; i < document.styleSheets.length; i++) {
|
||||
const ss = document.styleSheets[i];
|
||||
if (ss && ss.href === styleElements[stylesheetName].href) {
|
||||
cssLoaded = true;
|
||||
break;
|
||||
for (let i = 0; i < document.styleSheets.length; i++) {
|
||||
const ss = document.styleSheets[i];
|
||||
if (ss && ss.href === styleElements[stylesheetName].href) {
|
||||
cssLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cssLoaded) {
|
||||
styleElements[stylesheetName].onload = undefined;
|
||||
switchTheme();
|
||||
}
|
||||
if (cssLoaded) {
|
||||
styleElements[stylesheetName].onload = undefined;
|
||||
switchTheme();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -400,7 +400,7 @@ export default class WidgetUtils {
|
|||
return client.setAccountData('m.widgets', userWidgets);
|
||||
}
|
||||
|
||||
static makeAppConfig(appId, app, senderUserId, roomId) {
|
||||
static makeAppConfig(appId, app, senderUserId, roomId, eventId) {
|
||||
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
const user = MatrixClientPeg.get().getUser(myUserId);
|
||||
const params = {
|
||||
|
@ -419,6 +419,7 @@ export default class WidgetUtils {
|
|||
app.creatorUserId = senderUserId;
|
||||
|
||||
app.id = appId;
|
||||
app.eventId = eventId;
|
||||
app.name = app.name || app.type;
|
||||
|
||||
if (app.data) {
|
||||
|
|
72
yarn.lock
72
yarn.lock
|
@ -244,6 +244,11 @@
|
|||
"@types/istanbul-lib-coverage" "*"
|
||||
"@types/istanbul-lib-report" "*"
|
||||
|
||||
"@types/json-schema@^7.0.3":
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636"
|
||||
integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==
|
||||
|
||||
"@types/minimatch@*":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||
|
@ -293,6 +298,28 @@
|
|||
dependencies:
|
||||
"@types/yargs-parser" "*"
|
||||
|
||||
"@typescript-eslint/experimental-utils@^2.5.0":
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.8.0.tgz#208b4164d175587e9b03ce6fea97d55f19c30ca9"
|
||||
integrity sha512-jZ05E4SxCbbXseQGXOKf3ESKcsGxT8Ucpkp1jiVp55MGhOvZB2twmWKf894PAuVQTCgbPbJz9ZbRDqtUWzP8xA==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.3"
|
||||
"@typescript-eslint/typescript-estree" "2.8.0"
|
||||
eslint-scope "^5.0.0"
|
||||
|
||||
"@typescript-eslint/typescript-estree@2.8.0":
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.8.0.tgz#fcc3fe6532840085d29b75432c8a59895876aeca"
|
||||
integrity sha512-ksvjBDTdbAQ04cR5JyFSDX113k66FxH1tAXmi+dj6hufsl/G0eMc/f1GgLjEVPkYClDbRKv+rnBFuE5EusomUw==
|
||||
dependencies:
|
||||
debug "^4.1.1"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
glob "^7.1.6"
|
||||
is-glob "^4.0.1"
|
||||
lodash.unescape "4.0.1"
|
||||
semver "^6.3.0"
|
||||
tsutils "^3.17.1"
|
||||
|
||||
"@webassemblyjs/ast@1.8.5":
|
||||
version "1.8.5"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359"
|
||||
|
@ -2881,6 +2908,13 @@ eslint-plugin-flowtype@^2.30.0:
|
|||
dependencies:
|
||||
lodash "^4.17.10"
|
||||
|
||||
eslint-plugin-jest@^23.0.4:
|
||||
version "23.0.4"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-23.0.4.tgz#1ab81ffe3b16c5168efa72cbd4db14d335092aa0"
|
||||
integrity sha512-OaP8hhT8chJNodUPvLJ6vl8gnalcsU/Ww1t9oR3HnGdEWjm/DdCCUXLOral+IPGAeWu/EwgVQCK/QtxALpH1Yw==
|
||||
dependencies:
|
||||
"@typescript-eslint/experimental-utils" "^2.5.0"
|
||||
|
||||
eslint-plugin-react-hooks@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.0.1.tgz#e898ec26a0a335af6f7b0ad1f0bedda7143ed756"
|
||||
|
@ -2914,6 +2948,14 @@ eslint-scope@^4.0.3:
|
|||
esrecurse "^4.1.0"
|
||||
estraverse "^4.1.1"
|
||||
|
||||
eslint-scope@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9"
|
||||
integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==
|
||||
dependencies:
|
||||
esrecurse "^4.1.0"
|
||||
estraverse "^4.1.1"
|
||||
|
||||
eslint-utils@^1.3.1:
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab"
|
||||
|
@ -2921,7 +2963,7 @@ eslint-utils@^1.3.1:
|
|||
dependencies:
|
||||
eslint-visitor-keys "^1.0.0"
|
||||
|
||||
eslint-visitor-keys@^1.0.0:
|
||||
eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
|
||||
integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
|
||||
|
@ -3704,6 +3746,18 @@ glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
|
|||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^7.1.6:
|
||||
version "7.1.6"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
global-modules@2.0.0, global-modules@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
|
||||
|
@ -5028,6 +5082,11 @@ lodash.mergewith@^4.6.1:
|
|||
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55"
|
||||
integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==
|
||||
|
||||
lodash.unescape@4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c"
|
||||
integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=
|
||||
|
||||
lodash@^4.1.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.2.1:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
|
@ -7139,7 +7198,7 @@ selection-is-backward@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||
|
||||
semver@6.3.0:
|
||||
semver@6.3.0, semver@^6.3.0:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
||||
|
@ -8076,11 +8135,18 @@ trough@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.4.tgz#3b52b1f13924f460c3fbfd0df69b587dbcbc762e"
|
||||
integrity sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==
|
||||
|
||||
tslib@^1.9.0:
|
||||
tslib@^1.8.1, tslib@^1.9.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
|
||||
integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
|
||||
|
||||
tsutils@^3.17.1:
|
||||
version "3.17.1"
|
||||
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"
|
||||
integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==
|
||||
dependencies:
|
||||
tslib "^1.8.1"
|
||||
|
||||
tty-browserify@0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
|
||||
|
|
Loading…
Reference in a new issue