diff --git a/res/css/_components.scss b/res/css/_components.scss
index 2d819b38b6..dcc5799329 100644
--- a/res/css/_components.scss
+++ b/res/css/_components.scss
@@ -136,6 +136,7 @@
@import "./views/settings/_PhoneNumbers.scss";
@import "./views/settings/_ProfileSettings.scss";
@import "./views/settings/tabs/_GeneralSettingsTab.scss";
+@import "./views/settings/tabs/_PreferencesSettingsTab.scss";
@import "./views/settings/tabs/_SettingsTab.scss";
@import "./views/voip/_CallView.scss";
@import "./views/voip/_IncomingCallbox.scss";
diff --git a/res/css/views/elements/_Field.scss b/res/css/views/elements/_Field.scss
index 75cc2bec34..b2c6822bf2 100644
--- a/res/css/views/elements/_Field.scss
+++ b/res/css/views/elements/_Field.scss
@@ -24,6 +24,7 @@ limitations under the License.
.mx_Field input,
.mx_Field select {
font-weight: normal;
+ font-family: $font-family;
border-radius: 4px;
transition: border-color 0.25s;
border: 1px solid $input-border-color;
diff --git a/res/css/views/settings/tabs/_PreferencesSettingsTab.scss b/res/css/views/settings/tabs/_PreferencesSettingsTab.scss
new file mode 100644
index 0000000000..d6d7a8018e
--- /dev/null
+++ b/res/css/views/settings/tabs/_PreferencesSettingsTab.scss
@@ -0,0 +1,27 @@
+/*
+Copyright 2019 New Vector Ltd
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.mx_PreferencesSettingsTab .mx_Field {
+ margin-right: 100px; // Align with the rest of the controls
+}
+
+.mx_PreferencesSettingsTab .mx_Field input {
+ display: block;
+
+ // Subtract 10px padding on left and right
+ // This is to keep the input aligned with the rest of the tab's controls.
+ width: calc(100% - 20px);
+}
diff --git a/src/components/views/dialogs/UserSettingsDialog.js b/src/components/views/dialogs/UserSettingsDialog.js
index adcfa751c2..0c11b29456 100644
--- a/src/components/views/dialogs/UserSettingsDialog.js
+++ b/src/components/views/dialogs/UserSettingsDialog.js
@@ -24,6 +24,7 @@ import dis from '../../../dispatcher';
import SettingsStore from "../../../settings/SettingsStore";
import LabsSettingsTab from "../settings/tabs/LabsSettingsTab";
import NotificationSettingsTab from "../settings/tabs/NotificationSettingsTab";
+import PreferencesSettingsTab from "../settings/tabs/PreferencesSettingsTab";
// TODO: Ditch this whole component
export class TempTab extends React.Component {
@@ -62,7 +63,7 @@ export default class UserSettingsDialog extends React.Component {
tabs.push(new Tab(
_td("Preferences"),
"mx_UserSettingsDialog_preferencesIcon",
-
Preferences Test
,
+ ,
));
tabs.push(new Tab(
_td("Voice & Video"),
diff --git a/src/components/views/settings/tabs/PreferencesSettingsTab.js b/src/components/views/settings/tabs/PreferencesSettingsTab.js
new file mode 100644
index 0000000000..d0f3f2b36f
--- /dev/null
+++ b/src/components/views/settings/tabs/PreferencesSettingsTab.js
@@ -0,0 +1,125 @@
+/*
+Copyright 2019 New Vector Ltd
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import React from 'react';
+import {_t} from "../../../../languageHandler";
+import {SettingLevel} from "../../../../settings/SettingsStore";
+import LabelledToggleSwitch from "../../elements/LabelledToggleSwitch";
+import SettingsStore from "../../../../settings/SettingsStore";
+import Field from "../../elements/Field";
+const sdk = require("../../../../index");
+const PlatformPeg = require("../../../../PlatformPeg");
+
+export default class PreferencesSettingsTab extends React.Component {
+ static COMPOSER_SETTINGS = [
+ 'MessageComposerInput.autoReplaceEmoji',
+ 'MessageComposerInput.dontSuggestEmoji', // TODO: Positive wording
+ 'dontSendTypingNotifications', // TODO: Positive wording
+ ];
+
+ static ROOM_LIST_SETTINGS = [
+ 'pinUnreadRooms',
+ 'pinMentionedRooms',
+ ];
+
+ static TIMELINE_SETTINGS = [
+ 'autoplayGifsAndVideos',
+ 'urlPreviewsEnabled',
+ 'TextualBody.disableBigEmoji', // TODO: Positive wording
+ 'hideReadReceipts', // TODO: Positive wording
+ 'showTwelveHourTimestamps',
+ 'alwaysShowTimestamps',
+ 'hideRedactions', // TODO: Positive wording ("Show a placeholder for removed messages")
+ 'enableSyntaxHighlightLanguageDetection',
+ 'hideJoinLeaves', // TODO: Positive wording
+ 'hideAvatarChanges', // TODO: Positive wording
+ 'hideDisplaynameChanges', // TODO: Positive wording
+ ];
+
+ static ADVANCED_SETTINGS = [
+ 'alwaysShowEncryptionIcons',
+ 'Pill.shouldHidePillAvatar', // TODO: Positive wording
+ 'TagPanel.disableTagPanel', // TODO: Positive wording
+ 'promptBeforeInviteUnknownUsers',
+ // Start automatically after startup (electron-only)
+ // Autocomplete delay (niche text box)
+ ];
+
+ constructor() {
+ super();
+
+ this.state = {
+ autoLaunch: false,
+ autoLaunchSupported: false,
+ };
+ }
+
+ async componentWillMount(): void {
+ const autoLaunchSupported = await PlatformPeg.get().supportsAutoLaunch();
+ let autoLaunch = false;
+
+ if (autoLaunchSupported) {
+ autoLaunch = await PlatformPeg.get().getAutoLaunchEnabled();
+ }
+
+ this.setState({autoLaunch, autoLaunchSupported});
+ }
+
+ _onAutoLaunchChange = (checked) => {
+ PlatformPeg.get().setAutoLaunchEnabled(checked).then(() => this.setState({autoLaunch: checked}));
+ };
+
+ _onAutocompleteDelayChange = (e) => {
+ SettingsStore.setValue("autocompleteDelay", null, SettingLevel.DEVICE, e.target.value);
+ };
+
+ _renderGroup(settingIds) {
+ const SettingsFlag = sdk.getComponent("views.elements.SettingsFlag");
+ return settingIds.map(i => );
+ }
+
+ render() {
+ let autoLaunchOption = null;
+ if (this.state.autoLaunchSupported) {
+ autoLaunchOption = ;
+ }
+
+ return (
+
+
{_t("Preferences")}
+
+ {_t("Composer")}
+ {this._renderGroup(PreferencesSettingsTab.COMPOSER_SETTINGS)}
+
+ {_t("Room list")}
+ {this._renderGroup(PreferencesSettingsTab.ROOM_LIST_SETTINGS)}
+
+ {_t("Timeline")}
+ {this._renderGroup(PreferencesSettingsTab.TIMELINE_SETTINGS)}
+
+ {_t("Advanced")}
+ {this._renderGroup(PreferencesSettingsTab.ADVANCED_SETTINGS)}
+ {autoLaunchOption}
+
+
+
+ );
+ }
+}
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 20f7db0ebe..1ef41824d5 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -443,6 +443,13 @@
"Lazy loading is not supported by your current homeserver.": "Lazy loading is not supported by your current homeserver.",
"Labs": "Labs",
"Notifications": "Notifications",
+ "Start automatically after system login": "Start automatically after system login",
+ "Preferences": "Preferences",
+ "Composer": "Composer",
+ "Room list": "Room list",
+ "Timeline": "Timeline",
+ "Advanced": "Advanced",
+ "Autocomplete delay (ms)": "Autocomplete delay (ms)",
"Cannot add any more widgets": "Cannot add any more widgets",
"The maximum permitted number of widgets have already been added to this room.": "The maximum permitted number of widgets have already been added to this room.",
"Add a widget": "Add a widget",
@@ -677,7 +684,6 @@
"Members only (since they were invited)": "Members only (since they were invited)",
"Members only (since they joined)": "Members only (since they joined)",
"Permissions": "Permissions",
- "Advanced": "Advanced",
"Internal room ID: ": "Internal room ID: ",
"Room version number: ": "Room version number: ",
"Add a topic": "Add a topic",
@@ -1038,7 +1044,6 @@
"Room contains unknown devices": "Room contains unknown devices",
"\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" contains devices that you haven't seen before.",
"Unknown devices": "Unknown devices",
- "Preferences": "Preferences",
"Voice & Video": "Voice & Video",
"Security & Privacy": "Security & Privacy",
"Help & About": "Help & About",
@@ -1295,7 +1300,6 @@
"Reject all %(invitedRooms)s invites": "Reject all %(invitedRooms)s invites",
"Bulk Options": "Bulk Options",
"Desktop specific": "Desktop specific",
- "Start automatically after system login": "Start automatically after system login",
"No media permissions": "No media permissions",
"You may need to manually permit Riot to access your microphone/webcam": "You may need to manually permit Riot to access your microphone/webcam",
"Missing Media Permissions, click here to request.": "Missing Media Permissions, click here to request.",