diff --git a/src/Lifecycle.js b/src/Lifecycle.js index a7f90f847d..b8494ce9f5 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -33,6 +33,7 @@ import ActiveWidgetStore from './stores/ActiveWidgetStore'; import PlatformPeg from "./PlatformPeg"; import { sendLoginRequest } from "./Login"; import * as StorageManager from './utils/StorageManager'; +import SettingsStore from "./settings/SettingsStore"; /** * Called at startup, to attempt to build a logged-in Matrix session. It tries @@ -499,7 +500,9 @@ async function startMatrixClient() { Notifier.start(); UserActivity.sharedInstance().start(); - Presence.start(); + if (!SettingsStore.getValue("lowBandwidth")) { + Presence.start(); + } DMRoomMap.makeShared().start(); ActiveWidgetStore.start(); diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index 391d089cc6..574f05bf85 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -119,7 +119,7 @@ class MatrixClientPeg { // try to initialise e2e on the new client try { // check that we have a version of the js-sdk which includes initCrypto - if (this.matrixClient.initCrypto) { + if (!SettingsStore.getValue("lowBandwidth") && this.matrixClient.initCrypto) { await this.matrixClient.initCrypto(); StorageManager.setCryptoInitialised(true); } diff --git a/src/Notifier.js b/src/Notifier.js index 6a4f9827f7..2322311769 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -85,7 +85,11 @@ const Notifier = { msg = ''; } - const avatarUrl = ev.sender ? Avatar.avatarUrlForMember(ev.sender, 40, 40, 'crop') : null; + let avatarUrl = null; + if (ev.sender && !SettingsStore.getValue("lowBandwidth")) { + avatarUrl = Avatar.avatarUrlForMember(ev.sender, 40, 40, 'crop'); + } + const notif = plaf.displayNotification(title, msg, avatarUrl, room); // if displayNotification returns non-null, the platform supports diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 44741ad521..c939d31f94 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -613,6 +613,8 @@ const TimelinePanel = React.createClass({ }, sendReadReceipt: function() { + if (SettingsStore.getValue("lowBandwidth")) return; + if (!this.refs.messagePanel) return; if (!this.props.manageReadReceipts) return; // This happens on user_activity_end which is delayed, and it's diff --git a/src/components/views/avatars/BaseAvatar.js b/src/components/views/avatars/BaseAvatar.js index 5b299c2570..80f5c43d0c 100644 --- a/src/components/views/avatars/BaseAvatar.js +++ b/src/components/views/avatars/BaseAvatar.js @@ -20,6 +20,7 @@ import PropTypes from 'prop-types'; import { MatrixClient } from 'matrix-js-sdk'; import AvatarLogic from '../../../Avatar'; import sdk from '../../../index'; +import SettingsStore from "../../../settings/SettingsStore"; import AccessibleButton from '../elements/AccessibleButton'; module.exports = React.createClass({ @@ -104,9 +105,13 @@ module.exports = React.createClass({ // work out the full set of urls to try to load. This is formed like so: // imageUrls: [ props.url, props.urls, default image ] - const urls = props.urls || []; - if (props.url) { - urls.unshift(props.url); // put in urls[0] + let urls = []; + if (!SettingsStore.getValue("lowBandwidth")) { + urls = props.urls || []; + + if (props.url) { + urls.unshift(props.url); // put in urls[0] + } } let defaultImageUrl = null; diff --git a/src/components/views/dialogs/UserSettingsDialog.js b/src/components/views/dialogs/UserSettingsDialog.js index 1c4509eee5..a24c18c8b2 100644 --- a/src/components/views/dialogs/UserSettingsDialog.js +++ b/src/components/views/dialogs/UserSettingsDialog.js @@ -28,6 +28,7 @@ import VoiceUserSettingsTab from "../settings/tabs/user/VoiceUserSettingsTab"; import HelpUserSettingsTab from "../settings/tabs/user/HelpUserSettingsTab"; import FlairUserSettingsTab from "../settings/tabs/user/FlairUserSettingsTab"; import sdk from "../../../index"; +import SdkConfig from "../../../SdkConfig"; export default class UserSettingsDialog extends React.Component { static propTypes = { @@ -67,7 +68,7 @@ export default class UserSettingsDialog extends React.Component { "mx_UserSettingsDialog_securityIcon", , )); - if (SettingsStore.getLabsFeatures().length > 0) { + if (SdkConfig.get()['showLabsSettings'] || SettingsStore.getLabsFeatures().length > 0) { tabs.push(new Tab( _td("Labs"), "mx_UserSettingsDialog_labsIcon", diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index bf2fc8bd37..e1a7f559f8 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -475,6 +475,7 @@ export default class MessageComposerInput extends React.Component { sendTyping(isTyping) { if (!SettingsStore.getValue('sendTypingNotifications')) return; + if (SettingsStore.getValue('lowBandwidth')) return; MatrixClientPeg.get().sendTyping( this.props.room.roomId, this.isTyping, TYPING_SERVER_TIMEOUT, diff --git a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js index d272d74d29..23b5e516cd 100644 --- a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js @@ -53,6 +53,7 @@ export default class LabsUserSettingsTab extends React.Component { {flags} + ); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 343e75bcf3..e34ed093e7 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -339,6 +339,7 @@ "Show developer tools": "Show developer tools", "Order rooms in the room list by most important first instead of most recent": "Order rooms in the room list by most important first instead of most recent", "Show hidden events in timeline": "Show hidden events in timeline", + "Low bandwidth mode": "Low bandwidth mode", "Collecting app version information": "Collecting app version information", "Collecting logs": "Collecting logs", "Uploading report": "Uploading report", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 116526b63a..2c911dda80 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -23,6 +23,7 @@ import { } from "./controllers/NotificationControllers"; import CustomStatusController from "./controllers/CustomStatusController"; import ThemeController from './controllers/ThemeController'; +import LowBandwidthController from "./controllers/LowBandwidthController"; // These are just a bunch of helper arrays to avoid copy/pasting a bunch of times const LEVELS_ROOM_SETTINGS = ['device', 'room-device', 'room-account', 'account', 'config']; @@ -373,4 +374,10 @@ export const SETTINGS = { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS, default: false, }, + "lowBandwidth": { + supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, + displayName: _td('Low bandwidth mode'), + default: false, + controller: new LowBandwidthController(), + }, }; diff --git a/src/settings/controllers/LowBandwidthController.js b/src/settings/controllers/LowBandwidthController.js new file mode 100644 index 0000000000..c7796a425a --- /dev/null +++ b/src/settings/controllers/LowBandwidthController.js @@ -0,0 +1,24 @@ +/* +Copyright 2019 The Matrix.org Foundation C.I.C. + +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 SettingController from "./SettingController"; +import PlatformPeg from "../../PlatformPeg"; + +export default class LowBandwidthController extends SettingController { + onChange(level, roomId, newValue) { + PlatformPeg.get().reload(); + } +}