Merge pull request #1516 from turt2live/travis/granular-settings

Granular settings
This commit is contained in:
Matthew Hodgson 2017-11-15 10:55:55 +00:00 committed by GitHub
commit 060a890275
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 1924 additions and 754 deletions

View file

@ -19,7 +19,6 @@ limitations under the License.
import * as Matrix from 'matrix-js-sdk';
import React from 'react';
import UserSettingsStore from '../../UserSettingsStore';
import KeyCode from '../../KeyCode';
import Notifier from '../../Notifier';
import PageTypes from '../../PageTypes';
@ -28,6 +27,7 @@ import sdk from '../../index';
import dis from '../../dispatcher';
import sessionStore from '../../stores/SessionStore';
import MatrixClientPeg from '../../MatrixClientPeg';
import SettingsStore from "../../settings/SettingsStore";
/**
* This is what our MatrixChat shows when we are logged in. The precise view is
@ -74,7 +74,7 @@ export default React.createClass({
getInitialState: function() {
return {
// use compact timeline view
useCompactLayout: UserSettingsStore.getSyncedSetting('useCompactLayout'),
useCompactLayout: SettingsStore.getValue('useCompactLayout'),
};
},

View file

@ -22,7 +22,6 @@ import React from 'react';
import Matrix from "matrix-js-sdk";
import Analytics from "../../Analytics";
import UserSettingsStore from '../../UserSettingsStore';
import MatrixClientPeg from "../../MatrixClientPeg";
import PlatformPeg from "../../PlatformPeg";
import SdkConfig from "../../SdkConfig";
@ -44,6 +43,7 @@ import createRoom from "../../createRoom";
import * as UDEHandler from '../../UnknownDeviceErrorHandler';
import KeyRequestHandler from '../../KeyRequestHandler';
import { _t, getCurrentLanguage } from '../../languageHandler';
import SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
/** constants for MatrixChat.state.view */
const VIEWS = {
@ -224,7 +224,7 @@ module.exports = React.createClass({
componentWillMount: function() {
SdkConfig.put(this.props.config);
if (!UserSettingsStore.getLocalSetting('analyticsOptOut', false)) Analytics.enable();
if (!SettingsStore.getValue("analyticsOptOut")) Analytics.enable();
// Used by _viewRoom before getting state from sync
this.firstSyncComplete = false;
@ -591,6 +591,9 @@ module.exports = React.createClass({
this._onWillStartClient();
});
break;
case 'client_started':
this._onClientStarted();
break;
case 'new_version':
this.onVersion(
payload.currentVersion, payload.newVersion,
@ -1124,6 +1127,34 @@ module.exports = React.createClass({
cli.on("crypto.roomKeyRequestCancellation", (req) => {
krh.handleKeyRequestCancellation(req);
});
cli.on("Room", (room) => {
if (MatrixClientPeg.get().isCryptoEnabled()) {
const blacklistEnabled = SettingsStore.getValueAt(
SettingLevel.ROOM_DEVICE,
"blacklistUnverifiedDevices",
room.roomId,
/*explicit=*/true,
);
room.setBlacklistUnverifiedDevices(blacklistEnabled);
}
});
},
/**
* Called shortly after the matrix client has started. Useful for
* setting up anything that requires the client to be started.
* @private
*/
_onClientStarted: function() {
const cli = MatrixClientPeg.get();
if (cli.isCryptoEnabled()) {
const blacklistEnabled = SettingsStore.getValueAt(
SettingLevel.DEVICE,
"blacklistUnverifiedDevices",
);
cli.setGlobalBlacklistUnverifiedDevices(blacklistEnabled);
}
},
showScreen: function(screen, params) {

View file

@ -17,7 +17,6 @@ limitations under the License.
import React from 'react';
import ReactDOM from 'react-dom';
import classNames from 'classnames';
import UserSettingsStore from '../../UserSettingsStore';
import shouldHideEvent from '../../shouldHideEvent';
import dis from "../../dispatcher";
import sdk from '../../index';
@ -110,8 +109,6 @@ module.exports = React.createClass({
// Velocity requires
this._readMarkerGhostNode = null;
this._syncedSettings = UserSettingsStore.getSyncedSettings();
this._isMounted = true;
},
@ -251,7 +248,7 @@ module.exports = React.createClass({
// Always show highlighted event
if (this.props.highlightedEventId === mxEv.getId()) return true;
return !shouldHideEvent(mxEv, this._syncedSettings);
return !shouldHideEvent(mxEv);
},
_getEventTiles: function() {

View file

@ -29,7 +29,6 @@ const classNames = require("classnames");
const Matrix = require("matrix-js-sdk");
import { _t } from '../../languageHandler';
const UserSettingsStore = require('../../UserSettingsStore');
const MatrixClientPeg = require("../../MatrixClientPeg");
const ContentMessages = require("../../ContentMessages");
const Modal = require("../../Modal");
@ -46,6 +45,7 @@ import KeyCode from '../../KeyCode';
import RoomViewStore from '../../stores/RoomViewStore';
import RoomScrollStateStore from '../../stores/RoomScrollStateStore';
import SettingsStore from "../../settings/SettingsStore";
const DEBUG = false;
let debuglog = function() {};
@ -149,8 +149,6 @@ module.exports = React.createClass({
MatrixClientPeg.get().on("RoomMember.membership", this.onRoomMemberMembership);
MatrixClientPeg.get().on("accountData", this.onAccountData);
this._syncedSettings = UserSettingsStore.getSyncedSettings();
// Start listening for RoomViewStore updates
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
this._onRoomViewStoreUpdate(true);
@ -542,7 +540,7 @@ module.exports = React.createClass({
// update unread count when scrolled up
if (!this.state.searchResults && this.state.atEndOfLiveTimeline) {
// no change
} else if (!shouldHideEvent(ev, this._syncedSettings)) {
} else if (!shouldHideEvent(ev)) {
this.setState((state, props) => {
return {numUnreadMessages: state.numUnreadMessages + 1};
});
@ -616,38 +614,8 @@ module.exports = React.createClass({
},
_updatePreviewUrlVisibility: function(room) {
// console.log("_updatePreviewUrlVisibility");
// check our per-room overrides
const roomPreviewUrls = room.getAccountData("org.matrix.room.preview_urls");
if (roomPreviewUrls && roomPreviewUrls.getContent().disable !== undefined) {
this.setState({
showUrlPreview: !roomPreviewUrls.getContent().disable,
});
return;
}
// check our global disable override
const userRoomPreviewUrls = MatrixClientPeg.get().getAccountData("org.matrix.preview_urls");
if (userRoomPreviewUrls && userRoomPreviewUrls.getContent().disable) {
this.setState({
showUrlPreview: false,
});
return;
}
// check the room state event
const roomStatePreviewUrls = room.currentState.getStateEvents('org.matrix.room.preview_urls', '');
if (roomStatePreviewUrls && roomStatePreviewUrls.getContent().disable) {
this.setState({
showUrlPreview: false,
});
return;
}
// otherwise, we assume they're on.
this.setState({
showUrlPreview: true,
showUrlPreview: SettingsStore.getValue("urlPreviewsEnabled", room.roomId),
});
},
@ -666,12 +634,7 @@ module.exports = React.createClass({
const room = this.state.room;
if (!room) return;
const color_scheme_event = room.getAccountData("org.matrix.room.color_scheme");
let color_scheme = {};
if (color_scheme_event) {
color_scheme = color_scheme_event.getContent();
// XXX: we should validate the event
}
const color_scheme = SettingsStore.getValue("roomColor", room.room_id);
console.log("Tinter.tint from updateTint");
Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
},
@ -1775,7 +1738,7 @@ module.exports = React.createClass({
const messagePanel = (
<TimelinePanel ref={this._gatherTimelinePanelRef}
timelineSet={this.state.room.getUnfilteredTimelineSet()}
showReadReceipts={!UserSettingsStore.getSyncedSetting('hideReadReceipts', false)}
showReadReceipts={!SettingsStore.getValue('hideReadReceipts')}
manageReadReceipts={!this.state.isPeeking}
manageReadMarkers={!this.state.isPeeking}
hidden={hideMessagePanel}

View file

@ -15,6 +15,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import SettingsStore from "../../settings/SettingsStore";
const React = require('react');
const ReactDOM = require("react-dom");
import Promise from 'bluebird';
@ -30,7 +32,6 @@ const ObjectUtils = require('../../ObjectUtils');
const Modal = require("../../Modal");
const UserActivity = require("../../UserActivity");
const KeyCode = require('../../KeyCode');
import UserSettingsStore from '../../UserSettingsStore';
const PAGINATE_SIZE = 20;
const INITIAL_SIZE = 20;
@ -129,8 +130,6 @@ var TimelinePanel = React.createClass({
}
}
const syncedSettings = UserSettingsStore.getSyncedSettings();
return {
events: [],
timelineLoading: true, // track whether our room timeline is loading
@ -175,10 +174,10 @@ var TimelinePanel = React.createClass({
clientSyncState: MatrixClientPeg.get().getSyncState(),
// should the event tiles have twelve hour times
isTwelveHour: syncedSettings.showTwelveHourTimestamps,
isTwelveHour: SettingsStore.getValue("showTwelveHourTimestamps"),
// always show timestamps on event tiles?
alwaysShowTimestamps: syncedSettings.alwaysShowTimestamps,
alwaysShowTimestamps: SettingsStore.getValue("alwaysShowTimestamps"),
};
},

View file

@ -15,6 +15,8 @@ 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 SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
const React = require('react');
const ReactDOM = require('react-dom');
const sdk = require('../../index');
@ -56,138 +58,64 @@ const gHVersionLabel = function(repo, token='') {
return <a target="_blank" rel="noopener" href={url}>{ token }</a>;
};
// Enumerate some simple 'flip a bit' UI settings (if any).
// 'id' gives the key name in the im.vector.web.settings account data event
// 'label' is how we describe it in the UI.
// Warning: Each "label" string below must be added to i18n/strings/en_EN.json,
// since they will be translated when rendered.
const SETTINGS_LABELS = [
{
id: 'autoplayGifsAndVideos',
label: _td('Autoplay GIFs and videos'),
},
{
id: 'hideReadReceipts',
label: _td('Hide read receipts'),
},
{
id: 'dontSendTypingNotifications',
label: _td("Don't send typing notifications"),
},
{
id: 'alwaysShowTimestamps',
label: _td('Always show message timestamps'),
},
{
id: 'showTwelveHourTimestamps',
label: _td('Show timestamps in 12 hour format (e.g. 2:30pm)'),
},
{
id: 'hideJoinLeaves',
label: _td('Hide join/leave messages (invites/kicks/bans unaffected)'),
},
{
id: 'hideAvatarDisplaynameChanges',
label: _td('Hide avatar and display name changes'),
},
{
id: 'useCompactLayout',
label: _td('Use compact timeline layout'),
},
{
id: 'hideRedactions',
label: _td('Hide removed messages'),
},
{
id: 'enableSyntaxHighlightLanguageDetection',
label: _td('Enable automatic language detection for syntax highlighting'),
},
{
id: 'MessageComposerInput.autoReplaceEmoji',
label: _td('Automatically replace plain text Emoji'),
},
{
id: 'MessageComposerInput.dontSuggestEmoji',
label: _td('Disable Emoji suggestions while typing'),
},
{
id: 'Pill.shouldHidePillAvatar',
label: _td('Hide avatars in user and room mentions'),
},
{
id: 'TextualBody.disableBigEmoji',
label: _td('Disable big emoji in chat'),
},
{
id: 'VideoView.flipVideoHorizontally',
label: _td('Mirror local video feed'),
},
/*
{
id: 'useFixedWidthFont',
label: 'Use fixed width font',
},
*/
// Enumerate some simple 'flip a bit' UI settings (if any). The strings provided here
// must be settings defined in SettingsStore.
const SIMPLE_SETTINGS = [
{ id: "urlPreviewsEnabled" },
{ id: "autoplayGifsAndVideos" },
{ id: "hideReadReceipts" },
{ id: "dontSendTypingNotifications" },
{ id: "alwaysShowTimestamps" },
{ id: "showTwelveHourTimestamps" },
{ id: "hideJoinLeaves" },
{ id: "hideAvatarChanges" },
{ id: "hideDisplaynameChanges" },
{ id: "useCompactLayout" },
{ id: "hideRedactions" },
{ id: "enableSyntaxHighlightLanguageDetection" },
{ id: "MessageComposerInput.autoReplaceEmoji" },
{ id: "MessageComposerInput.dontSuggestEmoji" },
{ id: "Pill.shouldHidePillAvatar" },
{ id: "TextualBody.disableBigEmoji" },
{ id: "VideoView.flipVideoHorizontally" },
];
const ANALYTICS_SETTINGS_LABELS = [
// These settings must be defined in SettingsStore
const ANALYTICS_SETTINGS = [
{
id: 'analyticsOptOut',
label: _td('Opt out of analytics'),
fn: function(checked) {
Analytics[checked ? 'disable' : 'enable']();
},
},
];
const WEBRTC_SETTINGS_LABELS = [
{
id: 'webRtcForceTURN',
label: _td('Disable Peer-to-Peer for 1:1 calls'),
},
// These settings must be defined in SettingsStore
const WEBRTC_SETTINGS = [
{ id: 'webRtcForceTURN' },
];
// Warning: Each "label" string below must be added to i18n/strings/en_EN.json,
// since they will be translated when rendered.
const CRYPTO_SETTINGS_LABELS = [
// These settings must be defined in SettingsStore
const CRYPTO_SETTINGS = [
{
id: 'blacklistUnverifiedDevices',
label: _td('Never send encrypted messages to unverified devices from this device'),
fn: function(checked) {
MatrixClientPeg.get().setGlobalBlacklistUnverifiedDevices(checked);
},
},
// XXX: this is here for documentation; the actual setting is managed via RoomSettings
// {
// id: 'blacklistUnverifiedDevicesPerRoom'
// label: 'Never send encrypted messages to unverified devices in this room',
// }
];
// Enumerate the available themes, with a nice human text label.
// 'id' gives the key name in the im.vector.web.settings account data event
// 'value' is the value for that key in the event
// 'label' is how we describe it in the UI.
// 'value' is the value for the theme setting
//
// XXX: Ideally we would have a theme manifest or something and they'd be nicely
// packaged up in a single directory, and/or located at the application layer.
// But for now for expedience we just hardcode them here.
const THEMES = [
{
id: 'theme',
label: _td('Light theme'),
value: 'light',
},
{
id: 'theme',
label: _td('Dark theme'),
value: 'dark',
},
{
id: 'theme',
label: _td('Status.im theme'),
value: 'status',
},
{ label: _td('Light theme'), value: 'light' },
{ label: _td('Dark theme'), value: 'dark' },
{ label: _td('Status.im theme'), value: 'status' },
];
const IgnoredUser = React.createClass({
@ -286,14 +214,6 @@ module.exports = React.createClass({
});
this._refreshFromServer();
const syncedSettings = UserSettingsStore.getSyncedSettings();
if (!syncedSettings.theme) {
syncedSettings.theme = SdkConfig.get().default_theme || 'light';
}
this._syncedSettings = syncedSettings;
this._localSettings = UserSettingsStore.getLocalSettings();
if (PlatformPeg.get().isElectron()) {
const {ipcRenderer} = require('electron');
@ -364,8 +284,8 @@ module.exports = React.createClass({
if (this._unmounted) return;
this.setState({
mediaDevices,
activeAudioInput: this._localSettings['webrtc_audioinput'],
activeVideoInput: this._localSettings['webrtc_videoinput'],
activeAudioInput: SettingsStore.getValueAt(SettingLevel.DEVICE, 'webrtc_audioinput'),
activeVideoInput: SettingsStore.getValueAt(SettingLevel.DEVICE, 'webrtc_videoinput'),
});
});
},
@ -497,10 +417,6 @@ module.exports = React.createClass({
dis.dispatch({action: 'password_changed'});
},
onEnableNotificationsChange: function(event) {
UserSettingsStore.setEnableNotifications(event.target.checked);
},
_onAddEmailEditFinished: function(value, shouldSubmit) {
if (!shouldSubmit) return;
this._addEmail();
@ -697,7 +613,8 @@ module.exports = React.createClass({
onLanguageChange: function(newLang) {
if(this.state.language !== newLang) {
UserSettingsStore.setLocalSetting('language', newLang);
// We intentionally promote this to the account level at this point
SettingsStore.setValue("language", null, SettingLevel.ACCOUNT, newLang);
this.setState({
language: newLang,
});
@ -720,14 +637,13 @@ module.exports = React.createClass({
// TODO: this ought to be a separate component so that we don't need
// to rebind the onChange each time we render
const onChange = (e) =>
UserSettingsStore.setLocalSetting('autocompleteDelay', + e.target.value);
SettingsStore.setValue("autocompleteDelay", null, SettingLevel.DEVICE, e.target.value);
return (
<div>
<h3>{ _t("User Interface") }</h3>
<div className="mx_UserSettings_section">
{ this._renderUrlPreviewSelector() }
{ SETTINGS_LABELS.map( this._renderSyncedSetting ) }
{ THEMES.map( this._renderThemeSelector ) }
{ SIMPLE_SETTINGS.map( this._renderAccountSetting ) }
{ THEMES.map( this._renderThemeOption ) }
<table>
<tbody>
<tr>
@ -735,7 +651,7 @@ module.exports = React.createClass({
<td>
<input
type="number"
defaultValue={UserSettingsStore.getLocalSetting('autocompleteDelay', 200)}
defaultValue={SettingsStore.getValueAt(SettingLevel.DEVICE, "autocompleteDelay")}
onChange={onChange}
/>
</td>
@ -748,69 +664,31 @@ module.exports = React.createClass({
);
},
_renderUrlPreviewSelector: function() {
return <div className="mx_UserSettings_toggle">
<input id="urlPreviewsDisabled"
type="checkbox"
defaultChecked={UserSettingsStore.getUrlPreviewsDisabled()}
onChange={this._onPreviewsDisabledChanged}
/>
<label htmlFor="urlPreviewsDisabled">
{ _t("Disable inline URL previews by default") }
</label>
</div>;
_renderAccountSetting: function(setting) {
const SettingsFlag = sdk.getComponent("elements.SettingsFlag");
return (
<div className="mx_UserSettings_toggle" key={setting.id}>
<SettingsFlag name={setting.id}
label={setting.label}
level={SettingLevel.ACCOUNT}
onChange={setting.fn} />
</div>
);
},
_onPreviewsDisabledChanged: function(e) {
UserSettingsStore.setUrlPreviewsDisabled(e.target.checked);
},
_renderSyncedSetting: function(setting) {
// TODO: this ought to be a separate component so that we don't need
// to rebind the onChange each time we render
const onChange = (e) => {
UserSettingsStore.setSyncedSetting(setting.id, e.target.checked);
if (setting.fn) setting.fn(e.target.checked);
};
return <div className="mx_UserSettings_toggle" key={setting.id}>
<input id={setting.id}
type="checkbox"
defaultChecked={this._syncedSettings[setting.id]}
onChange={onChange}
/>
<label htmlFor={setting.id}>
{ _t(setting.label) }
</label>
</div>;
},
_renderThemeSelector: function(setting) {
// TODO: this ought to be a separate component so that we don't need
// to rebind the onChange each time we render
const onChange = (e) => {
if (e.target.checked) {
this._syncedSettings[setting.id] = setting.value;
UserSettingsStore.setSyncedSetting(setting.id, setting.value);
}
dis.dispatch({
action: 'set_theme',
value: setting.value,
});
};
return <div className="mx_UserSettings_toggle" key={setting.id + "_" + setting.value}>
<input id={setting.id + "_" + setting.value}
type="radio"
name={setting.id}
value={setting.value}
checked={this._syncedSettings[setting.id] === setting.value}
onChange={onChange}
/>
<label htmlFor={setting.id + "_" + setting.value}>
{ _t(setting.label) }
</label>
</div>;
_renderThemeOption: function(setting) {
const SettingsFlag = sdk.getComponent("elements.SettingsFlag");
const onChange = (v) => dis.dispatch({action: 'set_theme', value: setting.value});
return (
<div className="mx_UserSettings_toggle" key={setting.id + '_' + setting.value}>
<SettingsFlag name="theme"
label={setting.label}
level={SettingLevel.ACCOUNT}
onChange={onChange}
group="theme"
value={setting.value} />
</div>
);
},
_renderCryptoInfo: function() {
@ -852,7 +730,7 @@ module.exports = React.createClass({
{ importExportButtons }
</div>
<div className="mx_UserSettings_section">
{ CRYPTO_SETTINGS_LABELS.map( this._renderLocalSetting ) }
{ CRYPTO_SETTINGS.map( this._renderDeviceSetting ) }
</div>
</div>
);
@ -878,24 +756,16 @@ module.exports = React.createClass({
} else return (<div />);
},
_renderLocalSetting: function(setting) {
// TODO: this ought to be a separate component so that we don't need
// to rebind the onChange each time we render
const onChange = (e) => {
UserSettingsStore.setLocalSetting(setting.id, e.target.checked);
if (setting.fn) setting.fn(e.target.checked);
};
return <div className="mx_UserSettings_toggle" key={setting.id}>
<input id={setting.id}
type="checkbox"
defaultChecked={this._localSettings[setting.id]}
onChange={onChange}
/>
<label htmlFor={setting.id}>
{ _t(setting.label) }
</label>
</div>;
_renderDeviceSetting: function(setting) {
const SettingsFlag = sdk.getComponent("elements.SettingsFlag");
return (
<div className="mx_UserSettings_toggle" key={setting.id}>
<SettingsFlag name={setting.id}
label={setting.label}
level={SettingLevel.DEVICE}
onChange={setting.fn} />
</div>
);
},
_renderDevicesPanel: function() {
@ -932,18 +802,18 @@ module.exports = React.createClass({
<h3>{ _t('Analytics') }</h3>
<div className="mx_UserSettings_section">
{ _t('Riot collects anonymous analytics to allow us to improve the application.') }
{ ANALYTICS_SETTINGS_LABELS.map( this._renderLocalSetting ) }
{ ANALYTICS_SETTINGS.map( this._renderDeviceSetting ) }
</div>
</div>;
},
_renderLabs: function() {
const features = [];
UserSettingsStore.getLabsFeatures().forEach((featureId) => {
SettingsStore.getLabsFeatures().forEach((featureId) => {
// TODO: this ought to be a separate component so that we don't need
// to rebind the onChange each time we render
const onChange = (e) => {
UserSettingsStore.setFeatureEnabled(featureId, e.target.checked);
SettingsStore.setFeatureEnabled(featureId, e.target.checked);
this.forceUpdate();
};
@ -953,10 +823,10 @@ module.exports = React.createClass({
type="checkbox"
id={featureId}
name={featureId}
defaultChecked={UserSettingsStore.isFeatureEnabled(featureId)}
defaultChecked={SettingsStore.isFeatureEnabled(featureId)}
onChange={onChange}
/>
<label htmlFor={featureId}>{ UserSettingsStore.translatedNameForFeature(featureId) }</label>
<label htmlFor={featureId}>{ SettingsStore.getDisplayName(featureId) }</label>
</div>);
});
@ -1049,6 +919,8 @@ module.exports = React.createClass({
const settings = this.state.electron_settings;
if (!settings) return;
// TODO: This should probably be a granular setting, but it only applies to electron
// and ends up being get/set outside of matrix anyways (local system setting).
return <div>
<h3>{ _t('Desktop specific') }</h3>
<div className="mx_UserSettings_section">
@ -1171,7 +1043,7 @@ module.exports = React.createClass({
return <div>
<h3>{ _t('VoIP') }</h3>
<div className="mx_UserSettings_section">
{ WEBRTC_SETTINGS_LABELS.map(this._renderLocalSetting) }
{ WEBRTC_SETTINGS.map(this._renderDeviceSetting) }
{ this._renderWebRtcDeviceSettings() }
</div>
</div>;

View file

@ -22,9 +22,9 @@ import { _t, _tJsx } from '../../../languageHandler';
import * as languageHandler from '../../../languageHandler';
import sdk from '../../../index';
import Login from '../../../Login';
import UserSettingsStore from '../../../UserSettingsStore';
import PlatformPeg from '../../../PlatformPeg';
import SdkConfig from '../../../SdkConfig';
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
// For validating phone numbers without country codes
const PHONE_NUMBER_REGEX = /^[0-9\(\)\-\s]*$/;
@ -328,7 +328,7 @@ module.exports = React.createClass({
_onLanguageChange: function(newLang) {
if(languageHandler.getCurrentLanguage() !== newLang) {
UserSettingsStore.setLocalSetting('language', newLang);
SettingsStore.setValue("language", null, SettingLevel.DEVICE, newLang);
PlatformPeg.get().reload();
}
},
@ -385,7 +385,7 @@ module.exports = React.createClass({
}
// FIXME: remove status.im theme tweaks
const theme = UserSettingsStore.getTheme();
const theme = SettingsStore.getValue("theme");
if (theme !== "status") {
header = <h2>{ _t('Sign in') }</h2>;
}

View file

@ -26,8 +26,8 @@ import MatrixClientPeg from '../../../MatrixClientPeg';
import RegistrationForm from '../../views/login/RegistrationForm';
import RtsClient from '../../../RtsClient';
import { _t } from '../../../languageHandler';
import UserSettingsStore from '../../../UserSettingsStore';
import SdkConfig from '../../../SdkConfig';
import SettingsStore from "../../../settings/SettingsStore";
const MIN_PASSWORD_LENGTH = 6;
@ -329,7 +329,7 @@ module.exports = React.createClass({
const Spinner = sdk.getComponent("elements.Spinner");
const ServerConfig = sdk.getComponent('views.login.ServerConfig');
const theme = UserSettingsStore.getTheme();
const theme = SettingsStore.getValue("theme");
let registerBody;
if (this.state.doingUIAuth) {