Merge branch 'develop' into travis/integs/widgets
This commit is contained in:
commit
24ac1d1547
11 changed files with 81 additions and 128 deletions
|
@ -148,7 +148,7 @@
|
||||||
"karma-summary-reporter": "^1.5.1",
|
"karma-summary-reporter": "^1.5.1",
|
||||||
"karma-webpack": "^4.0.0-beta.0",
|
"karma-webpack": "^4.0.0-beta.0",
|
||||||
"matrix-mock-request": "^1.2.3",
|
"matrix-mock-request": "^1.2.3",
|
||||||
"matrix-react-test-utils": "^0.1.1",
|
"matrix-react-test-utils": "^0.2.2",
|
||||||
"mocha": "^5.0.5",
|
"mocha": "^5.0.5",
|
||||||
"react-addons-test-utils": "^15.4.0",
|
"react-addons-test-utils": "^15.4.0",
|
||||||
"require-json": "0.0.1",
|
"require-json": "0.0.1",
|
||||||
|
|
|
@ -23,8 +23,8 @@ limitations under the License.
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_GeneralUserSettingsTab_accountSection > .mx_EmailAddresses,
|
.mx_GeneralUserSettingsTab_accountSection .mx_EmailAddresses,
|
||||||
.mx_GeneralUserSettingsTab_accountSection > .mx_PhoneNumbers,
|
.mx_GeneralUserSettingsTab_accountSection .mx_PhoneNumbers,
|
||||||
.mx_GeneralUserSettingsTab_languageInput {
|
.mx_GeneralUserSettingsTab_languageInput {
|
||||||
margin-right: 100px; // Align with the other fields on the page
|
margin-right: 100px; // Align with the other fields on the page
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,13 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
|
import {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
|
||||||
import SdkConfig from "../../../SdkConfig";
|
import SdkConfig from "../../../SdkConfig";
|
||||||
import AutoDiscoveryUtils from "../../../utils/AutoDiscoveryUtils";
|
import AutoDiscoveryUtils from "../../../utils/AutoDiscoveryUtils";
|
||||||
import * as ServerType from '../../views/auth/ServerTypeSelector';
|
import * as ServerType from '../../views/auth/ServerTypeSelector';
|
||||||
|
import ServerConfig from "./ServerConfig";
|
||||||
|
|
||||||
const MODULAR_URL = 'https://modular.im/?utm_source=riot-web&utm_medium=web&utm_campaign=riot-web-authentication';
|
const MODULAR_URL = 'https://modular.im/?utm_source=riot-web&utm_medium=web&utm_campaign=riot-web-authentication';
|
||||||
|
|
||||||
|
@ -33,49 +33,8 @@ const MODULAR_URL = 'https://modular.im/?utm_source=riot-web&utm_medium=web&utm_
|
||||||
* This is a variant of ServerConfig with only the HS field and different body
|
* This is a variant of ServerConfig with only the HS field and different body
|
||||||
* text that is specific to the Modular case.
|
* text that is specific to the Modular case.
|
||||||
*/
|
*/
|
||||||
export default class ModularServerConfig extends React.PureComponent {
|
export default class ModularServerConfig extends ServerConfig {
|
||||||
static propTypes = {
|
static propTypes = ServerConfig.propTypes;
|
||||||
onServerConfigChange: PropTypes.func,
|
|
||||||
|
|
||||||
// The current configuration that the user is expecting to change.
|
|
||||||
serverConfig: PropTypes.instanceOf(ValidatedServerConfig).isRequired,
|
|
||||||
|
|
||||||
delayTimeMs: PropTypes.number, // time to wait before invoking onChanged
|
|
||||||
|
|
||||||
// Called after the component calls onServerConfigChange
|
|
||||||
onAfterSubmit: PropTypes.func,
|
|
||||||
|
|
||||||
// Optional text for the submit button. If falsey, no button will be shown.
|
|
||||||
submitText: PropTypes.string,
|
|
||||||
|
|
||||||
// Optional class for the submit button. Only applies if the submit button
|
|
||||||
// is to be rendered.
|
|
||||||
submitClass: PropTypes.string,
|
|
||||||
};
|
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
onServerConfigChange: function() {},
|
|
||||||
customHsUrl: "",
|
|
||||||
delayTimeMs: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
busy: false,
|
|
||||||
errorText: "",
|
|
||||||
hsUrl: props.serverConfig.hsUrl,
|
|
||||||
isUrl: props.serverConfig.isUrl,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillReceiveProps(newProps) {
|
|
||||||
if (newProps.serverConfig.hsUrl === this.state.hsUrl &&
|
|
||||||
newProps.serverConfig.isUrl === this.state.isUrl) return;
|
|
||||||
|
|
||||||
this.validateAndApplyServer(newProps.serverConfig.hsUrl, newProps.serverConfig.isUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
async validateAndApplyServer(hsUrl, isUrl) {
|
async validateAndApplyServer(hsUrl, isUrl) {
|
||||||
// Always try and use the defaults first
|
// Always try and use the defaults first
|
||||||
|
@ -120,35 +79,6 @@ export default class ModularServerConfig extends React.PureComponent {
|
||||||
return this.validateAndApplyServer(this.state.hsUrl, ServerType.TYPES.PREMIUM.identityServerUrl);
|
return this.validateAndApplyServer(this.state.hsUrl, ServerType.TYPES.PREMIUM.identityServerUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
onHomeserverBlur = (ev) => {
|
|
||||||
this._hsTimeoutId = this._waitThenInvoke(this._hsTimeoutId, () => {
|
|
||||||
this.validateServer();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onHomeserverChange = (ev) => {
|
|
||||||
const hsUrl = ev.target.value;
|
|
||||||
this.setState({ hsUrl });
|
|
||||||
};
|
|
||||||
|
|
||||||
onSubmit = async (ev) => {
|
|
||||||
ev.preventDefault();
|
|
||||||
ev.stopPropagation();
|
|
||||||
const result = await this.validateServer();
|
|
||||||
if (!result) return; // Do not continue.
|
|
||||||
|
|
||||||
if (this.props.onAfterSubmit) {
|
|
||||||
this.props.onAfterSubmit();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
_waitThenInvoke(existingTimeoutId, fn) {
|
|
||||||
if (existingTimeoutId) {
|
|
||||||
clearTimeout(existingTimeoutId);
|
|
||||||
}
|
|
||||||
return setTimeout(fn.bind(this), this.props.delayTimeMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const Field = sdk.getComponent('elements.Field');
|
const Field = sdk.getComponent('elements.Field');
|
||||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
Copyright 2017 Vector Creations Ltd
|
Copyright 2017 Vector Creations Ltd
|
||||||
Copyright 2018, 2019 New Vector Ltd
|
Copyright 2018, 2019 New Vector Ltd
|
||||||
|
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||||
|
|
||||||
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.
|
||||||
|
@ -69,10 +70,10 @@ module.exports = React.createClass({
|
||||||
fieldValid: {},
|
fieldValid: {},
|
||||||
// The ISO2 country code selected in the phone number entry
|
// The ISO2 country code selected in the phone number entry
|
||||||
phoneCountry: this.props.defaultPhoneCountry,
|
phoneCountry: this.props.defaultPhoneCountry,
|
||||||
username: "",
|
username: this.props.defaultUsername || "",
|
||||||
email: "",
|
email: this.props.defaultEmail || "",
|
||||||
phoneNumber: "",
|
phoneNumber: this.props.defaultPhoneNumber || "",
|
||||||
password: "",
|
password: this.props.defaultPassword || "",
|
||||||
passwordConfirm: "",
|
passwordConfirm: "",
|
||||||
passwordComplexity: null,
|
passwordComplexity: null,
|
||||||
passwordSafe: false,
|
passwordSafe: false,
|
||||||
|
@ -90,7 +91,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
if (this.state.email == '') {
|
if (this.state.email === '') {
|
||||||
const haveIs = Boolean(this.props.serverConfig.isUrl);
|
const haveIs = Boolean(this.props.serverConfig.isUrl);
|
||||||
|
|
||||||
let desc;
|
let desc;
|
||||||
|
@ -455,7 +456,6 @@ module.exports = React.createClass({
|
||||||
ref={field => this[FIELD_EMAIL] = field}
|
ref={field => this[FIELD_EMAIL] = field}
|
||||||
type="text"
|
type="text"
|
||||||
label={emailPlaceholder}
|
label={emailPlaceholder}
|
||||||
defaultValue={this.props.defaultEmail}
|
|
||||||
value={this.state.email}
|
value={this.state.email}
|
||||||
onChange={this.onEmailChange}
|
onChange={this.onEmailChange}
|
||||||
onValidate={this.onEmailValidate}
|
onValidate={this.onEmailValidate}
|
||||||
|
@ -469,7 +469,6 @@ module.exports = React.createClass({
|
||||||
ref={field => this[FIELD_PASSWORD] = field}
|
ref={field => this[FIELD_PASSWORD] = field}
|
||||||
type="password"
|
type="password"
|
||||||
label={_t("Password")}
|
label={_t("Password")}
|
||||||
defaultValue={this.props.defaultPassword}
|
|
||||||
value={this.state.password}
|
value={this.state.password}
|
||||||
onChange={this.onPasswordChange}
|
onChange={this.onPasswordChange}
|
||||||
onValidate={this.onPasswordValidate}
|
onValidate={this.onPasswordValidate}
|
||||||
|
@ -483,7 +482,6 @@ module.exports = React.createClass({
|
||||||
ref={field => this[FIELD_PASSWORD_CONFIRM] = field}
|
ref={field => this[FIELD_PASSWORD_CONFIRM] = field}
|
||||||
type="password"
|
type="password"
|
||||||
label={_t("Confirm")}
|
label={_t("Confirm")}
|
||||||
defaultValue={this.props.defaultPassword}
|
|
||||||
value={this.state.passwordConfirm}
|
value={this.state.passwordConfirm}
|
||||||
onChange={this.onPasswordConfirmChange}
|
onChange={this.onPasswordConfirmChange}
|
||||||
onValidate={this.onPasswordConfirmValidate}
|
onValidate={this.onPasswordConfirmValidate}
|
||||||
|
@ -512,7 +510,6 @@ module.exports = React.createClass({
|
||||||
ref={field => this[FIELD_PHONE_NUMBER] = field}
|
ref={field => this[FIELD_PHONE_NUMBER] = field}
|
||||||
type="text"
|
type="text"
|
||||||
label={phoneLabel}
|
label={phoneLabel}
|
||||||
defaultValue={this.props.defaultPhoneNumber}
|
|
||||||
value={this.state.phoneNumber}
|
value={this.state.phoneNumber}
|
||||||
prefix={phoneCountry}
|
prefix={phoneCountry}
|
||||||
onChange={this.onPhoneNumberChange}
|
onChange={this.onPhoneNumberChange}
|
||||||
|
@ -528,7 +525,6 @@ module.exports = React.createClass({
|
||||||
type="text"
|
type="text"
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
label={_t("Username")}
|
label={_t("Username")}
|
||||||
defaultValue={this.props.defaultUsername}
|
|
||||||
value={this.state.username}
|
value={this.state.username}
|
||||||
onChange={this.onUsernameChange}
|
onChange={this.onUsernameChange}
|
||||||
onValidate={this.onUsernameValidate}
|
onValidate={this.onUsernameValidate}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
Copyright 2018 New Vector Ltd
|
Copyright 2018 New Vector Ltd
|
||||||
|
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||||
|
|
||||||
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.
|
||||||
|
@ -19,7 +20,6 @@ import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { MatrixClient } from 'matrix-js-sdk';
|
import { MatrixClient } from 'matrix-js-sdk';
|
||||||
import AvatarLogic from '../../../Avatar';
|
import AvatarLogic from '../../../Avatar';
|
||||||
import sdk from '../../../index';
|
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
|
|
||||||
|
@ -121,6 +121,10 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
urls.push(defaultImageUrl); // lowest priority
|
urls.push(defaultImageUrl); // lowest priority
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deduplicate URLs
|
||||||
|
urls = Array.from(new Set(urls));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
imageUrls: urls,
|
imageUrls: urls,
|
||||||
defaultImageUrl: defaultImageUrl,
|
defaultImageUrl: defaultImageUrl,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2017 Vector Creations Ltd
|
Copyright 2017 Vector Creations Ltd
|
||||||
|
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||||
|
|
||||||
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.
|
||||||
|
@ -17,7 +18,6 @@ limitations under the License.
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||||
import { ContentRepo } from 'matrix-js-sdk';
|
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import Modal from '../../../Modal';
|
import Modal from '../../../Modal';
|
||||||
|
@ -31,12 +31,21 @@ module.exports = React.createClass({
|
||||||
mxEvent: PropTypes.object.isRequired,
|
mxEvent: PropTypes.object.isRequired,
|
||||||
},
|
},
|
||||||
|
|
||||||
onAvatarClick: function(name) {
|
onAvatarClick: function() {
|
||||||
const httpUrl = MatrixClientPeg.get().mxcUrlToHttp(this.props.mxEvent.getContent().url);
|
const cli = MatrixClientPeg.get();
|
||||||
|
const ev = this.props.mxEvent;
|
||||||
|
const httpUrl = cli.mxcUrlToHttp(ev.getContent().url);
|
||||||
|
|
||||||
|
const room = cli.getRoom(this.props.mxEvent.getRoomId());
|
||||||
|
const text = _t('%(senderDisplayName)s changed the avatar for %(roomName)s', {
|
||||||
|
senderDisplayName: ev.sender && ev.sender.name ? ev.sender.name : ev.getSender(),
|
||||||
|
roomName: room ? room.name : '',
|
||||||
|
});
|
||||||
|
|
||||||
const ImageView = sdk.getComponent("elements.ImageView");
|
const ImageView = sdk.getComponent("elements.ImageView");
|
||||||
const params = {
|
const params = {
|
||||||
src: httpUrl,
|
src: httpUrl,
|
||||||
name: name,
|
name: text,
|
||||||
};
|
};
|
||||||
Modal.createDialog(ImageView, params, "mx_Dialog_lightbox");
|
Modal.createDialog(ImageView, params, "mx_Dialog_lightbox");
|
||||||
},
|
},
|
||||||
|
@ -44,29 +53,22 @@ module.exports = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
const ev = this.props.mxEvent;
|
const ev = this.props.mxEvent;
|
||||||
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
||||||
const BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
|
const RoomAvatar = sdk.getComponent("avatars.RoomAvatar");
|
||||||
|
|
||||||
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
|
||||||
const name = _t('%(senderDisplayName)s changed the avatar for %(roomName)s', {
|
|
||||||
senderDisplayName: senderDisplayName,
|
|
||||||
roomName: room ? room.name : '',
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!ev.getContent().url || ev.getContent().url.trim().length === 0) {
|
if (!ev.getContent().url || ev.getContent().url.trim().length === 0) {
|
||||||
return (
|
return (
|
||||||
<div className="mx_TextualEvent">
|
<div className="mx_TextualEvent">
|
||||||
{ _t('%(senderDisplayName)s removed the room avatar.', {senderDisplayName: senderDisplayName}) }
|
{ _t('%(senderDisplayName)s removed the room avatar.', {senderDisplayName}) }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = ContentRepo.getHttpUriForMxc(
|
const room = MatrixClientPeg.get().getRoom(ev.getRoomId());
|
||||||
MatrixClientPeg.get().getHomeserverUrl(),
|
// Provide all arguments to RoomAvatar via oobData because the avatar is historic
|
||||||
ev.getContent().url,
|
const oobData = {
|
||||||
Math.ceil(14 * window.devicePixelRatio),
|
avatarUrl: ev.getContent().url,
|
||||||
Math.ceil(14 * window.devicePixelRatio),
|
name: room ? room.name : "",
|
||||||
'crop',
|
};
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_RoomAvatarEvent">
|
<div className="mx_RoomAvatarEvent">
|
||||||
|
@ -75,8 +77,8 @@ module.exports = React.createClass({
|
||||||
{
|
{
|
||||||
'img': () =>
|
'img': () =>
|
||||||
<AccessibleButton key="avatar" className="mx_RoomAvatarEvent_avatar"
|
<AccessibleButton key="avatar" className="mx_RoomAvatarEvent_avatar"
|
||||||
onClick={this.onAvatarClick.bind(this, name)}>
|
onClick={this.onAvatarClick}>
|
||||||
<BaseAvatar width={14} height={14} url={url} name={name} />
|
<RoomAvatar width={14} height={14} oobData={oobData} />
|
||||||
</AccessibleButton>,
|
</AccessibleButton>,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2019 New Vector Ltd
|
Copyright 2019 New Vector Ltd
|
||||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||||
|
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||||
|
|
||||||
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.
|
||||||
|
@ -26,6 +27,7 @@ import LanguageDropdown from "../../../elements/LanguageDropdown";
|
||||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||||
import DeactivateAccountDialog from "../../../dialogs/DeactivateAccountDialog";
|
import DeactivateAccountDialog from "../../../dialogs/DeactivateAccountDialog";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
|
import {THEMES} from "../../../../../themes";
|
||||||
const PlatformPeg = require("../../../../../PlatformPeg");
|
const PlatformPeg = require("../../../../../PlatformPeg");
|
||||||
const MatrixClientPeg = require("../../../../../MatrixClientPeg");
|
const MatrixClientPeg = require("../../../../../MatrixClientPeg");
|
||||||
const sdk = require('../../../../..');
|
const sdk = require('../../../../..');
|
||||||
|
@ -160,8 +162,9 @@ export default class GeneralUserSettingsTab extends React.Component {
|
||||||
<span className="mx_SettingsTab_subheading">{_t("Theme")}</span>
|
<span className="mx_SettingsTab_subheading">{_t("Theme")}</span>
|
||||||
<Field id="theme" label={_t("Theme")} element="select"
|
<Field id="theme" label={_t("Theme")} element="select"
|
||||||
value={this.state.theme} onChange={this._onThemeChange}>
|
value={this.state.theme} onChange={this._onThemeChange}>
|
||||||
<option value="light">{_t("Light theme")}</option>
|
{Object.entries(THEMES).map(([theme, text]) => {
|
||||||
<option value="dark">{_t("Dark theme")}</option>
|
return <option key={theme} value={theme}>{_t(text)}</option>;
|
||||||
|
})}
|
||||||
</Field>
|
</Field>
|
||||||
<SettingsFlag name="useCompactLayout" level={SettingLevel.ACCOUNT} />
|
<SettingsFlag name="useCompactLayout" level={SettingLevel.ACCOUNT} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -251,6 +251,8 @@
|
||||||
"%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s",
|
"%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s",
|
||||||
"%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s",
|
"%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s",
|
||||||
"%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s",
|
"%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s",
|
||||||
|
"Light theme": "Light theme",
|
||||||
|
"Dark theme": "Dark theme",
|
||||||
"%(displayName)s is typing …": "%(displayName)s is typing …",
|
"%(displayName)s is typing …": "%(displayName)s is typing …",
|
||||||
"%(names)s and %(count)s others are typing …|other": "%(names)s and %(count)s others are typing …",
|
"%(names)s and %(count)s others are typing …|other": "%(names)s and %(count)s others are typing …",
|
||||||
"%(names)s and %(count)s others are typing …|one": "%(names)s and one other is typing …",
|
"%(names)s and %(count)s others are typing …|one": "%(names)s and one other is typing …",
|
||||||
|
@ -548,8 +550,6 @@
|
||||||
"Set a new account password...": "Set a new account password...",
|
"Set a new account password...": "Set a new account password...",
|
||||||
"Language and region": "Language and region",
|
"Language and region": "Language and region",
|
||||||
"Theme": "Theme",
|
"Theme": "Theme",
|
||||||
"Light theme": "Light theme",
|
|
||||||
"Dark theme": "Dark theme",
|
|
||||||
"Account management": "Account management",
|
"Account management": "Account management",
|
||||||
"Deactivating your account is a permanent action - be careful!": "Deactivating your account is a permanent action - be careful!",
|
"Deactivating your account is a permanent action - be careful!": "Deactivating your account is a permanent action - be careful!",
|
||||||
"Deactivate Account": "Deactivate Account",
|
"Deactivate Account": "Deactivate Account",
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2019 New Vector Ltd
|
Copyright 2019 New Vector Ltd
|
||||||
|
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||||
|
|
||||||
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.
|
||||||
|
@ -15,17 +16,13 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import SettingController from "./SettingController";
|
import SettingController from "./SettingController";
|
||||||
|
import {DEFAULT_THEME, THEMES} from "../../themes";
|
||||||
const SUPPORTED_THEMES = [
|
|
||||||
"light",
|
|
||||||
"dark",
|
|
||||||
];
|
|
||||||
|
|
||||||
export default class ThemeController extends SettingController {
|
export default class ThemeController extends SettingController {
|
||||||
getValueOverride(level, roomId, calculatedValue, calculatedAtLevel) {
|
getValueOverride(level, roomId, calculatedValue, calculatedAtLevel) {
|
||||||
// Override in case some no longer supported theme is stored here
|
// Override in case some no longer supported theme is stored here
|
||||||
if (!SUPPORTED_THEMES.includes(calculatedValue)) {
|
if (!THEMES[calculatedValue]) {
|
||||||
return "light";
|
return DEFAULT_THEME;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null; // no override
|
return null; // no override
|
||||||
|
|
24
src/themes.js
Normal file
24
src/themes.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||||
|
|
||||||
|
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 {_td} from "./languageHandler";
|
||||||
|
|
||||||
|
export const DEFAULT_THEME = "light";
|
||||||
|
|
||||||
|
export const THEMES = {
|
||||||
|
"light": _td("Light theme"),
|
||||||
|
"dark": _td("Dark theme"),
|
||||||
|
};
|
15
yarn.lock
15
yarn.lock
|
@ -5061,13 +5061,10 @@ matrix-mock-request@^1.2.3:
|
||||||
bluebird "^3.5.0"
|
bluebird "^3.5.0"
|
||||||
expect "^1.20.2"
|
expect "^1.20.2"
|
||||||
|
|
||||||
matrix-react-test-utils@^0.1.1:
|
matrix-react-test-utils@^0.2.2:
|
||||||
version "0.1.1"
|
version "0.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/matrix-react-test-utils/-/matrix-react-test-utils-0.1.1.tgz#b548844d0ebe338ea1b9c8f16474c30d17c3bdf4"
|
resolved "https://registry.yarnpkg.com/matrix-react-test-utils/-/matrix-react-test-utils-0.2.2.tgz#c87144d3b910c7edc544a6699d13c7c2bf02f853"
|
||||||
integrity sha1-tUiETQ6+M46hucjxZHTDDRfDvfQ=
|
integrity sha512-49+7gfV6smvBIVbeloql+37IeWMTD+fiywalwCqk8Dnz53zAFjKSltB3rmWHso1uecLtQEcPtCijfhzcLXAxTQ==
|
||||||
dependencies:
|
|
||||||
react "^15.6.1"
|
|
||||||
react-dom "^15.6.1"
|
|
||||||
|
|
||||||
md5.js@^1.3.4:
|
md5.js@^1.3.4:
|
||||||
version "1.3.5"
|
version "1.3.5"
|
||||||
|
@ -6373,7 +6370,7 @@ react-beautiful-dnd@^4.0.1:
|
||||||
redux-thunk "^2.2.0"
|
redux-thunk "^2.2.0"
|
||||||
reselect "^3.0.1"
|
reselect "^3.0.1"
|
||||||
|
|
||||||
react-dom@^15.6.0, react-dom@^15.6.1:
|
react-dom@^15.6.0:
|
||||||
version "15.6.2"
|
version "15.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.6.2.tgz#41cfadf693b757faf2708443a1d1fd5a02bef730"
|
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.6.2.tgz#41cfadf693b757faf2708443a1d1fd5a02bef730"
|
||||||
integrity sha1-Qc+t9pO3V/rycIRDodH9WgK+9zA=
|
integrity sha1-Qc+t9pO3V/rycIRDodH9WgK+9zA=
|
||||||
|
@ -6436,7 +6433,7 @@ react-redux@^5.0.6:
|
||||||
react-is "^16.6.0"
|
react-is "^16.6.0"
|
||||||
react-lifecycles-compat "^3.0.0"
|
react-lifecycles-compat "^3.0.0"
|
||||||
|
|
||||||
react@^15.6.0, react@^15.6.1:
|
react@^15.6.0:
|
||||||
version "15.6.2"
|
version "15.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/react/-/react-15.6.2.tgz#dba0434ab439cfe82f108f0f511663908179aa72"
|
resolved "https://registry.yarnpkg.com/react/-/react-15.6.2.tgz#dba0434ab439cfe82f108f0f511663908179aa72"
|
||||||
integrity sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=
|
integrity sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=
|
||||||
|
|
Loading…
Reference in a new issue