From 53947bee35324c58b464e6db96803e09c58813cf Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Wed, 28 Nov 2018 14:42:30 -0600 Subject: [PATCH 001/165] Fix empty lightbox when there is no avatarUrl Signed-off-by: Aaron Raimist --- src/components/views/avatars/RoomAvatar.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index 7b9cb10d51..506bd87adc 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -137,6 +137,11 @@ module.exports = React.createClass({ const avatarUrl = this.props.room.getAvatarUrl( MatrixClientPeg.get().getHomeserverUrl(), null, null, null, false); + + if (!avatarUrl) { + return; + } + const ImageView = sdk.getComponent("elements.ImageView"); const params = { src: avatarUrl, From 52ebba9d3eae2c7ca4a800b24846088c6853d422 Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Tue, 29 Jan 2019 16:05:38 -0600 Subject: [PATCH 002/165] Disable clicking on room icon in a better way Signed-off-by: Aaron Raimist --- src/components/views/avatars/RoomAvatar.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index 506bd87adc..38f088238f 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -137,11 +137,6 @@ module.exports = React.createClass({ const avatarUrl = this.props.room.getAvatarUrl( MatrixClientPeg.get().getHomeserverUrl(), null, null, null, false); - - if (!avatarUrl) { - return; - } - const ImageView = sdk.getComponent("elements.ImageView"); const params = { src: avatarUrl, @@ -163,7 +158,8 @@ module.exports = React.createClass({ + onClick={this.props.viewAvatarOnClick ? this.onRoomAvatarClick : null} + disabled={!this.state.urls[0]} /> ); }, }); From bc6d13e768c3a6d69c91ac31d8b4b45444aed942 Mon Sep 17 00:00:00 2001 From: Bastian Date: Wed, 30 Jan 2019 11:22:05 +0100 Subject: [PATCH 003/165] Extend slash command '/topic' to display the room topic If no is provided, the command will display a modal dialog containing the sanitized and linkified room topic. This is just adding some juice to make reading long room topics more convenient. --- src/SlashCommands.js | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index 24328d6372..5b5a53b83f 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -27,7 +27,12 @@ import SettingsStore, {SettingLevel} from './settings/SettingsStore'; import {MATRIXTO_URL_PATTERN} from "./linkify-matrix"; import * as querystring from "querystring"; import MultiInviter from './utils/MultiInviter'; +import * as linkify from 'linkifyjs'; +import linkifyString from 'linkifyjs/string'; +import linkifyMatrix from './linkify-matrix'; +import sanitizeHtml from 'sanitize-html'; +linkifyMatrix(linkify); class Command { constructor({name, args='', description, runFn, hideCompletionAfterSpace=false}) { @@ -125,13 +130,27 @@ export const CommandMap = { topic: new Command({ name: 'topic', - args: '', - description: _td('Sets the room topic'), + args: '[]', + description: _td('Gets or sets the room topic'), runFn: function(roomId, args) { + const cli = MatrixClientPeg.get(); if (args) { - return success(MatrixClientPeg.get().setRoomTopic(roomId, args)); + return success(cli.setRoomTopic(roomId, args)); } - return reject(this.getUsage()); + const room = cli.getRoom(roomId); + if (!room) return reject('Bad room ID: ' + roomId); + + const topicEvents = room.currentState.getStateEvents('m.room.topic', ''); + const topic = topicEvents.getContent().topic; + const topicHtml = linkifyString(sanitizeHtml(topic)); + + const QuestionDialog = sdk.getComponent('dialogs.QuestionDialog'); + Modal.createTrackedDialog('Slash Commands', 'Topic', QuestionDialog, { + title: room.name, + description:
, + hasCancelButton: false, + }); + return success(); }, }), From 5f90321d0f1a1dcbe47e46982eb26ffefaa83555 Mon Sep 17 00:00:00 2001 From: Bastian Date: Wed, 30 Jan 2019 11:57:50 +0100 Subject: [PATCH 004/165] Update i18n --- src/i18n/strings/en_EN.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index c6701156cb..69c9a77cf3 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -114,8 +114,6 @@ "Failed to invite": "Failed to invite", "Failed to invite users to the room:": "Failed to invite users to the room:", "Failed to invite the following users to the %(roomName)s room:": "Failed to invite the following users to the %(roomName)s room:", - "Waiting for %(userId)s to accept...": "Waiting for %(userId)s to accept...", - "Waiting for %(userId)s to confirm...": "Waiting for %(userId)s to confirm...", "You need to be logged in.": "You need to be logged in.", "You need to be able to invite users to do that.": "You need to be able to invite users to do that.", "Unable to create widget.": "Unable to create widget.", @@ -134,7 +132,7 @@ "To use it, just wait for autocomplete results to load and tab through them.": "To use it, just wait for autocomplete results to load and tab through them.", "Changes your display nickname": "Changes your display nickname", "Changes colour scheme of current room": "Changes colour scheme of current room", - "Sets the room topic": "Sets the room topic", + "Gets or sets the room topic": "Gets or sets the room topic", "Invites user with given id to current room": "Invites user with given id to current room", "Joins room with given alias": "Joins room with given alias", "Leave room": "Leave room", From 81880c01d3e6bd84dcc12c7b6508771742ad63c0 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 31 Jan 2019 10:16:21 -0600 Subject: [PATCH 005/165] Auto-focus username on registration --- src/components/views/auth/RegistrationForm.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/auth/RegistrationForm.js b/src/components/views/auth/RegistrationForm.js index ba48239cc6..86402256c6 100644 --- a/src/components/views/auth/RegistrationForm.js +++ b/src/components/views/auth/RegistrationForm.js @@ -305,7 +305,7 @@ module.exports = React.createClass({ const emailSection = (
From f245fa6a5273db61e2cd95510ad755051f254cb5 Mon Sep 17 00:00:00 2001 From: Bastian Date: Thu, 31 Jan 2019 17:57:57 +0100 Subject: [PATCH 006/165] Add InfoDialog Signed-off-by: Bastian --- src/components/views/dialogs/InfoDialog.js | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/components/views/dialogs/InfoDialog.js diff --git a/src/components/views/dialogs/InfoDialog.js b/src/components/views/dialogs/InfoDialog.js new file mode 100644 index 0000000000..f917a907bd --- /dev/null +++ b/src/components/views/dialogs/InfoDialog.js @@ -0,0 +1,80 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +Copyright 2017 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 PropTypes from 'prop-types'; +import sdk from '../../../index'; +import { _t } from '../../../languageHandler'; + +export default React.createClass({ + displayName: 'InfoDialog', + propTypes: { + title: PropTypes.string, + description: PropTypes.node, + extraButtons: PropTypes.node, + button: PropTypes.string, + danger: PropTypes.bool, + focus: PropTypes.bool, + onFinished: PropTypes.func.isRequired, + }, + + getDefaultProps: function() { + return { + title: "", + description: "", + extraButtons: null, + focus: true, + danger: false, + }; + }, + + onOk: function() { + this.props.onFinished(true); + }, + + onCancel: function() { + this.props.onFinished(false); + }, + + render: function() { + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); + let primaryButtonClass = ""; + if (this.props.danger) { + primaryButtonClass = "danger"; + } + return ( + +
+ { this.props.description } +
+ + { this.props.extraButtons } + +
+ ); + }, +}); From 8273662500888a5a58778ac46939d1e3988777e2 Mon Sep 17 00:00:00 2001 From: Bastian Date: Thu, 31 Jan 2019 18:00:37 +0100 Subject: [PATCH 007/165] Replace QuestionDialog with InfoDialog Display a default message if no room topic is present Signed-off-by: Bastian --- src/SlashCommands.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index d70d970796..f31bf32eac 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -154,13 +154,12 @@ export const CommandMap = { const topicEvents = room.currentState.getStateEvents('m.room.topic', ''); const topic = topicEvents.getContent().topic; - const topicHtml = linkifyString(sanitizeHtml(topic)); + const topicHtml = topic ? linkifyString(sanitizeHtml(topic)) : _t('This room has no topic.'); - const QuestionDialog = sdk.getComponent('dialogs.QuestionDialog'); - Modal.createTrackedDialog('Slash Commands', 'Topic', QuestionDialog, { + const InfoDialog = sdk.getComponent('dialogs.InfoDialog'); + Modal.createTrackedDialog('Slash Commands', 'Topic', InfoDialog, { title: room.name, description:
, - hasCancelButton: false, }); return success(); }, From 3e2bcd1d3c1e80c22c6ad90d60be8c88252d687b Mon Sep 17 00:00:00 2001 From: Bastian Date: Thu, 31 Jan 2019 18:01:53 +0100 Subject: [PATCH 008/165] Update i18n Signed-off-by: Bastian --- src/i18n/strings/en_EN.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index bb382304f9..4da2195834 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -134,6 +134,7 @@ "Changes your display nickname": "Changes your display nickname", "Changes colour scheme of current room": "Changes colour scheme of current room", "Gets or sets the room topic": "Gets or sets the room topic", + "This room has no topic.": "This room has no topic.", "Sets the room name": "Sets the room name", "Invites user with given id to current room": "Invites user with given id to current room", "Joins room with given alias": "Joins room with given alias", From 6597db6328f15a1bd2a834c789778bbbd76e9662 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 31 Jan 2019 12:01:17 -0600 Subject: [PATCH 009/165] Simplify login server URL state --- src/components/structures/auth/Login.js | 54 ++++++++++++------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/src/components/structures/auth/Login.js b/src/components/structures/auth/Login.js index d1b0aad31a..c5cdba3caa 100644 --- a/src/components/structures/auth/Login.js +++ b/src/components/structures/auth/Login.js @@ -88,8 +88,8 @@ module.exports = React.createClass({ loginIncorrect: false, serverType: null, - enteredHomeserverUrl: this.props.customHsUrl || this.props.defaultHsUrl, - enteredIdentityServerUrl: this.props.customIsUrl || this.props.defaultIsUrl, + enteredHsUrl: this.props.customHsUrl || this.props.defaultHsUrl, + enteredIsUrl: this.props.customIsUrl || this.props.defaultIsUrl, // used for preserving form values when changing homeserver username: "", @@ -102,8 +102,6 @@ module.exports = React.createClass({ currentFlow: "m.login.password", // .well-known discovery - discoveredHsUrl: "", - discoveredIsUrl: "", discoveryError: "", findingHomeserver: false, }; @@ -308,10 +306,10 @@ module.exports = React.createClass({ errorText: null, // reset err messages }; if (config.hsUrl !== undefined) { - newState.enteredHomeserverUrl = config.hsUrl; + newState.enteredHsUrl = config.hsUrl; } if (config.isUrl !== undefined) { - newState.enteredIdentityServerUrl = config.isUrl; + newState.enteredIsUrl = config.isUrl; } this.props.onServerConfigChange(config); @@ -377,7 +375,10 @@ module.exports = React.createClass({ _tryWellKnownDiscovery: async function(serverName) { if (!serverName.trim()) { // Nothing to discover - this.setState({discoveryError: "", discoveredHsUrl: "", discoveredIsUrl: "", findingHomeserver: false}); + this.setState({ + discoveryError: "", + findingHomeserver: false, + }); return; } @@ -387,33 +388,28 @@ module.exports = React.createClass({ const state = discovery["m.homeserver"].state; if (state !== AutoDiscovery.SUCCESS && state !== AutoDiscovery.PROMPT) { this.setState({ - discoveredHsUrl: "", - discoveredIsUrl: "", discoveryError: discovery["m.homeserver"].error, findingHomeserver: false, }); } else if (state === AutoDiscovery.PROMPT) { this.setState({ - discoveredHsUrl: "", - discoveredIsUrl: "", discoveryError: "", findingHomeserver: false, }); } else if (state === AutoDiscovery.SUCCESS) { this.setState({ - discoveredHsUrl: discovery["m.homeserver"].base_url, - discoveredIsUrl: - discovery["m.identity_server"].state === AutoDiscovery.SUCCESS - ? discovery["m.identity_server"].base_url - : "", discoveryError: "", findingHomeserver: false, }); + this.onServerConfigChange({ + hsUrl: discovery["m.homeserver"].base_url, + isUrl: discovery["m.identity_server"].state === AutoDiscovery.SUCCESS + ? discovery["m.identity_server"].base_url + : "", + }); } else { console.warn("Unknown state for m.homeserver in discovery response: ", discovery); this.setState({ - discoveredHsUrl: "", - discoveredIsUrl: "", discoveryError: _t("Unknown failure discovering homeserver"), findingHomeserver: false, }); @@ -429,8 +425,8 @@ module.exports = React.createClass({ _initLoginLogic: function(hsUrl, isUrl) { const self = this; - hsUrl = hsUrl || this.state.enteredHomeserverUrl; - isUrl = isUrl || this.state.enteredIdentityServerUrl; + hsUrl = hsUrl || this.state.enteredHsUrl; + isUrl = isUrl || this.state.enteredIsUrl; const fallbackHsUrl = hsUrl === this.props.defaultHsUrl ? this.props.fallbackHsUrl : null; @@ -440,8 +436,8 @@ module.exports = React.createClass({ this._loginLogic = loginLogic; this.setState({ - enteredHomeserverUrl: hsUrl, - enteredIdentityServerUrl: isUrl, + enteredHsUrl: hsUrl, + enteredIsUrl: isUrl, busy: true, loginIncorrect: false, }); @@ -507,8 +503,8 @@ module.exports = React.createClass({ if (err.cors === 'rejected') { if (window.location.protocol === 'https:' && - (this.state.enteredHomeserverUrl.startsWith("http:") || - !this.state.enteredHomeserverUrl.startsWith("http")) + (this.state.enteredHsUrl.startsWith("http:") || + !this.state.enteredHsUrl.startsWith("http")) ) { errorText = { _t("Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. " + @@ -532,7 +528,7 @@ module.exports = React.createClass({ { 'a': (sub) => { return { sub }; }, }, @@ -572,7 +568,7 @@ module.exports = React.createClass({ break; case ServerType.PREMIUM: serverDetails = ); From f58055c77877700a05bf3890bd9efad60ff09da4 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 31 Jan 2019 12:01:58 -0600 Subject: [PATCH 010/165] Skip .well-known discovery for free server type --- src/components/structures/auth/Login.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/components/structures/auth/Login.js b/src/components/structures/auth/Login.js index c5cdba3caa..159d5b71b0 100644 --- a/src/components/structures/auth/Login.js +++ b/src/components/structures/auth/Login.js @@ -263,6 +263,11 @@ module.exports = React.createClass({ username: username, discoveryError: null, }); + // If the free server type is selected, we don't show server details at all, + // so it doesn't make sense to try .well-known discovery. + if (this.state.serverType === ServerType.FREE) { + return; + } if (username[0] === "@") { const serverName = username.split(':').slice(1).join(':'); try { @@ -385,6 +390,15 @@ module.exports = React.createClass({ this.setState({findingHomeserver: true}); try { const discovery = await AutoDiscovery.findClientConfig(serverName); + + // The server type may have changed while discovery began in the background. + // If it has become the free server type which doesn't show server details, + // ignore discovery results. + if (this.state.serverType === ServerType.FREE) { + this.setState({findingHomeserver: false}); + return; + } + const state = discovery["m.homeserver"].state; if (state !== AutoDiscovery.SUCCESS && state !== AutoDiscovery.PROMPT) { this.setState({ From 9cd13a8893bf6f3dbb6c2d7b3457598207cd1d1f Mon Sep 17 00:00:00 2001 From: Bastian Date: Thu, 31 Jan 2019 22:26:07 +0100 Subject: [PATCH 011/165] Add HtmlUtils.linkifyString() Add HtmlUtils.linkifyElement() Add HtmlUtils.linkifyAndSanitize() Refactor module imports Signed-off-by: Bastian --- src/HtmlUtils.js | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index e72c0bfe4b..ff99b2386b 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -19,16 +19,21 @@ limitations under the License. import ReplyThread from "./components/views/elements/ReplyThread"; -const React = require('react'); -const sanitizeHtml = require('sanitize-html'); -const highlight = require('highlight.js'); -const linkifyMatrix = require('./linkify-matrix'); +import React from 'react'; +import sanitizeHtml from 'sanitize-html'; +import highlight from 'highlight.js'; +import * as linkify from 'linkifyjs'; +import linkifyMatrix from './linkify-matrix'; +import _linkifyElement from 'linkifyjs/element'; +import _linkifyString from 'linkifyjs/string'; import escape from 'lodash/escape'; import emojione from 'emojione'; import classNames from 'classnames'; import MatrixClientPeg from './MatrixClientPeg'; import url from 'url'; +linkifyMatrix(linkify); + emojione.imagePathSVG = 'emojione/svg/'; // Store PNG path for displaying many flags at once (for increased performance over SVG) emojione.imagePathPNG = 'emojione/png/'; @@ -508,3 +513,35 @@ export function emojifyText(text) { __html: unicodeToImage(escape(text)), }; } + +/** + * Linkifies the given string. This is a wrapper around 'linkifyjs/string'. + * + * @param {string} str + * @returns {string} + */ +export function linkifyString(str) { + return _linkifyString(str); +} + +/** + * Linkifies the given DOM element. This is a wrapper around 'linkifyjs/element'. + * + * @param {object} element DOM element to linkify + * @param {object} [options] Options for linkifyElement. Default: linkifyMatrix.options + * @returns {object} + */ +export function linkifyElement(element, options = linkifyMatrix.options) { + return _linkifyElement(element, options); +} + +/** + * Linkify the given string and sanitize the HTML afterwards. + * + * @param {string} dirtyHtml The HTML string to sanitize and linkify + * @param {object} [sanitizeHtmlOptions] Optional settings for sanitize-html + * @returns {string} + */ +export function linkifyAndSanitizeHtml(dirtyHtml, sanitizeHtmlOptions = undefined) { + return sanitizeHtml(linkifyString(dirtyHtml), sanitizeHtmlOptions); +} From 23971b3d0d5fb3627d68588f9776e32aaadedb59 Mon Sep 17 00:00:00 2001 From: Bastian Date: Thu, 31 Jan 2019 22:35:58 +0100 Subject: [PATCH 012/165] Refactor to use HtmlUtils for linkifying and sanitizing Signed-off-by: Bastian --- src/SlashCommands.js | 9 ++------- src/components/structures/RoomDirectory.js | 9 ++------- src/components/views/messages/TextualBody.js | 7 +------ src/components/views/rooms/LinkPreviewWidget.js | 12 ++++-------- src/components/views/rooms/RoomDetailRow.js | 8 ++------ src/components/views/rooms/RoomHeader.js | 8 ++------ 6 files changed, 13 insertions(+), 40 deletions(-) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index f31bf32eac..be1f4ebda8 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -27,12 +27,7 @@ import SettingsStore, {SettingLevel} from './settings/SettingsStore'; import {MATRIXTO_URL_PATTERN} from "./linkify-matrix"; import * as querystring from "querystring"; import MultiInviter from './utils/MultiInviter'; -import * as linkify from 'linkifyjs'; -import linkifyString from 'linkifyjs/string'; -import linkifyMatrix from './linkify-matrix'; -import sanitizeHtml from 'sanitize-html'; - -linkifyMatrix(linkify); +import { linkifyAndSanitizeHtml } from './HtmlUtils'; class Command { constructor({name, args='', description, runFn, hideCompletionAfterSpace=false}) { @@ -154,7 +149,7 @@ export const CommandMap = { const topicEvents = room.currentState.getStateEvents('m.room.topic', ''); const topic = topicEvents.getContent().topic; - const topicHtml = topic ? linkifyString(sanitizeHtml(topic)) : _t('This room has no topic.'); + const topicHtml = topic ? linkifyAndSanitizeHtml(topic) : _t('This room has no topic.'); const InfoDialog = sdk.getComponent('dialogs.InfoDialog'); Modal.createTrackedDialog('Slash Commands', 'Topic', InfoDialog, { diff --git a/src/components/structures/RoomDirectory.js b/src/components/structures/RoomDirectory.js index c18dd4d48a..08d3403bc3 100644 --- a/src/components/structures/RoomDirectory.js +++ b/src/components/structures/RoomDirectory.js @@ -24,10 +24,7 @@ const Modal = require('../../Modal'); const sdk = require('../../index'); const dis = require('../../dispatcher'); -const linkify = require('linkifyjs'); -const linkifyString = require('linkifyjs/string'); -const linkifyMatrix = require('../../linkify-matrix'); -const sanitizeHtml = require('sanitize-html'); +import { linkifyAndSanitizeHtml } from '../../HtmlUtils'; import Promise from 'bluebird'; import { _t } from '../../languageHandler'; @@ -37,8 +34,6 @@ import {instanceForInstanceId, protocolNameForInstanceId} from '../../utils/Dire const MAX_NAME_LENGTH = 80; const MAX_TOPIC_LENGTH = 160; -linkifyMatrix(linkify); - module.exports = React.createClass({ displayName: 'RoomDirectory', @@ -438,7 +433,7 @@ module.exports = React.createClass({ if (topic.length > MAX_TOPIC_LENGTH) { topic = `${topic.substring(0, MAX_TOPIC_LENGTH)}...`; } - topic = linkifyString(sanitizeHtml(topic)); + topic = linkifyAndSanitizeHtml(topic); rows.push( Date: Thu, 31 Jan 2019 15:54:53 -0600 Subject: [PATCH 013/165] Add error message when registration is disabled --- src/components/structures/auth/Registration.js | 4 ++++ src/i18n/strings/en_EN.json | 1 + 2 files changed, 5 insertions(+) diff --git a/src/components/structures/auth/Registration.js b/src/components/structures/auth/Registration.js index 03b071ed48..166ae69a8f 100644 --- a/src/components/structures/auth/Registration.js +++ b/src/components/structures/auth/Registration.js @@ -164,6 +164,10 @@ module.exports = React.createClass({ this.setState({ flows: e.data.flows, }); + } else if (e.httpStatus === 403 && e.errcode === "M_UNKNOWN") { + this.setState({ + errorText: _t("Registration has been disabled"), + }); } else { this.setState({ errorText: _t("Unable to query for supported registration methods"), diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index fb025a9e61..9e9f9e4fad 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1418,6 +1418,7 @@ "Failed to fetch avatar URL": "Failed to fetch avatar URL", "Set a display name:": "Set a display name:", "Upload an avatar:": "Upload an avatar:", + "Registration has been disabled": "Registration has been disabled", "Unable to query for supported registration methods": "Unable to query for supported registration methods", "This server does not support authentication with a phone number.": "This server does not support authentication with a phone number.", "Missing password.": "Missing password.", From 4036e52c24663b2da0a088edcc5b1ecfa9247805 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 29 Jan 2019 21:45:15 -0700 Subject: [PATCH 014/165] Fixed settings dialog header; Adjust padding on dialog Some recent changes to dialogs changed how this works and altered the look of the settings dialogs. This fixes that and makes it so that the header and content scroll independently. Fixes https://github.com/vector-im/riot-web/issues/8329 Fixes https://github.com/vector-im/riot-web/issues/8328 --- res/css/structures/_TabbedView.scss | 22 +++--- res/css/views/dialogs/_SettingsDialog.scss | 69 ++++++------------- src/components/structures/TabbedView.js | 4 +- .../views/dialogs/RoomSettingsDialog.js | 17 +++-- .../views/dialogs/UserSettingsDialog.js | 17 +++-- src/i18n/strings/en_EN.json | 1 + 6 files changed, 56 insertions(+), 74 deletions(-) diff --git a/res/css/structures/_TabbedView.scss b/res/css/structures/_TabbedView.scss index ed9fa368e3..2f448ff4a8 100644 --- a/res/css/structures/_TabbedView.scss +++ b/res/css/structures/_TabbedView.scss @@ -17,17 +17,21 @@ limitations under the License. .mx_TabbedView { margin: 0; - padding: 0; + padding: 0 0 0 58px; display: flex; - width: 100%; - height: 100%; + flex-direction: column; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; } .mx_TabbedView_tabLabels { width: 150px; max-width: 150px; - height: 100%; color: $tab-label-fg-color; + position: fixed; } .mx_TabbedView_tabLabel { @@ -82,13 +86,15 @@ limitations under the License. } .mx_TabbedView_tabPanel { - width: calc(100% - 320px); - display: inline-block; - margin-left: 70px; + margin-left: 220px; // 150px sidebar + 70px padding flex-grow: 1; + display: flex; + flex-direction: column; } .mx_TabbedView_tabPanelContent { flex-grow: 1; - min-width: 560px; + overflow: auto; + min-height: 0; // firefox + } \ No newline at end of file diff --git a/res/css/views/dialogs/_SettingsDialog.scss b/res/css/views/dialogs/_SettingsDialog.scss index 2cc7c08039..b1a4470b02 100644 --- a/res/css/views/dialogs/_SettingsDialog.scss +++ b/res/css/views/dialogs/_SettingsDialog.scss @@ -15,56 +15,31 @@ limitations under the License. */ .mx_SettingsDialog { - .mx_Dialog { - max-width: 784px; // 900px - 58px (left padding) - 58px (right padding) - width: 80%; - height: 80%; - border-radius: 4px; + .mx_Dialog { + max-width: 900px; + width: 80%; + height: 80%; + border-radius: 4px; + padding-top: 0; + padding-right: 0; + padding-left: 0; - .mx_TabbedView_tabLabels { - // Force the sidebar to be always visible, letting the rest of the content scroll - position: fixed; - } + .mx_TabbedView { + top: 65px; + } - .mx_TabbedView_tabPanel { - max-width: 485px; - margin-left: 206px; // 70px margin + 136px for the sidebar - } + .mx_TabbedView .mx_SettingsTab { + max-width: calc(100% - 130px); // 130px right hand padding - .mx_SettingsDialog_header { - font-size: 24px; - display: block; - text-align: center; - color: $dialog-title-fg-color; - margin-top: 16px; - margin-bottom: 24px; - padding: 0; - } + // Put some padding on the bottom to avoid the settings tab from + // colliding harshly with the dialog when scrolled down. + padding-bottom: 100px; + } - .mx_SettingsDialog_close { - position: absolute; - top: 16px; - right: 25px; + .mx_Dialog_title { + text-align: center; + margin-top: 16px; + margin-bottom: 24px; + } } - - .mx_SettingsDialog_closeIcon { - width: 16px; - height: 16px; - display: inline-block; - } - - .mx_SettingsDialog_closeIcon:before { - mask: url('$(res)/img/feather-icons/cancel.svg'); - background-color: $dialog-close-fg-color; - mask-repeat: no-repeat; - mask-size: 16px; - mask-position: center; - content: ''; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - } - } } diff --git a/src/components/structures/TabbedView.js b/src/components/structures/TabbedView.js index 2b136128f3..12dde54151 100644 --- a/src/components/structures/TabbedView.js +++ b/src/components/structures/TabbedView.js @@ -97,7 +97,9 @@ export class TabbedView extends React.Component { _renderTabPanel(tab) { return (
- {tab.body} +
+ {tab.body} +
); } diff --git a/src/components/views/dialogs/RoomSettingsDialog.js b/src/components/views/dialogs/RoomSettingsDialog.js index 6be2676d72..0578ccaffd 100644 --- a/src/components/views/dialogs/RoomSettingsDialog.js +++ b/src/components/views/dialogs/RoomSettingsDialog.js @@ -19,11 +19,11 @@ import PropTypes from 'prop-types'; import {Tab, TabbedView} from "../../structures/TabbedView"; import {_t, _td} from "../../../languageHandler"; import AdvancedRoomSettingsTab from "../settings/tabs/AdvancedRoomSettingsTab"; -import AccessibleButton from "../elements/AccessibleButton"; import dis from '../../../dispatcher'; import RolesRoomSettingsTab from "../settings/tabs/RolesRoomSettingsTab"; import GeneralRoomSettingsTab from "../settings/tabs/GeneralRoomSettingsTab"; import SecurityRoomSettingsTab from "../settings/tabs/SecurityRoomSettingsTab"; +import sdk from "../../../index"; // TODO: Ditch this whole component export class TempTab extends React.Component { @@ -93,16 +93,15 @@ export default class RoomSettingsDialog extends React.Component { } render() { + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + return ( -
-
- {_t("Settings")} - - - + +
+
- -
+ ); } } diff --git a/src/components/views/dialogs/UserSettingsDialog.js b/src/components/views/dialogs/UserSettingsDialog.js index 12c692b958..2616542bf7 100644 --- a/src/components/views/dialogs/UserSettingsDialog.js +++ b/src/components/views/dialogs/UserSettingsDialog.js @@ -18,7 +18,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import {Tab, TabbedView} from "../../structures/TabbedView"; import {_t, _td} from "../../../languageHandler"; -import AccessibleButton from "../elements/AccessibleButton"; import GeneralUserSettingsTab from "../settings/tabs/GeneralUserSettingsTab"; import dis from '../../../dispatcher'; import SettingsStore from "../../../settings/SettingsStore"; @@ -29,6 +28,7 @@ import PreferencesSettingsTab from "../settings/tabs/PreferencesSettingsTab"; import VoiceSettingsTab from "../settings/tabs/VoiceSettingsTab"; import HelpSettingsTab from "../settings/tabs/HelpSettingsTab"; import FlairSettingsTab from "../settings/tabs/FlairSettingsTab"; +import sdk from "../../../index"; // TODO: Ditch this whole component export class TempTab extends React.Component { @@ -106,16 +106,15 @@ export default class UserSettingsDialog extends React.Component { } render() { + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + return ( -
-
- {_t("Settings")} - - - + +
+
- -
+ ); } } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index fb025a9e61..ac696bc1ca 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1074,6 +1074,7 @@ "Report bugs & give feedback": "Report bugs & give feedback", "Go back": "Go back", "Visit old settings": "Visit old settings", + "Room Settings": "Room Settings", "Failed to upgrade room": "Failed to upgrade room", "The room upgrade could not be completed": "The room upgrade could not be completed", "Upgrade this room to version %(version)s": "Upgrade this room to version %(version)s", From 6905e3e54ccba58a2d3b0eebfe0a121704735054 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 31 Jan 2019 18:15:18 -0600 Subject: [PATCH 015/165] Fix typo on registration --- src/components/views/auth/RegistrationForm.js | 2 +- src/i18n/strings/en_EN.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/auth/RegistrationForm.js b/src/components/views/auth/RegistrationForm.js index ba48239cc6..bc84bd8839 100644 --- a/src/components/views/auth/RegistrationForm.js +++ b/src/components/views/auth/RegistrationForm.js @@ -379,7 +379,7 @@ module.exports = React.createClass({ { phoneSection }
{_t( - "Use an email address to receover your account. Other users " + + "Use an email address to recover your account. Other users " + "can invite you to rooms using your contact details.", )} { registerButton } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index fb025a9e61..fd56965470 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1215,7 +1215,7 @@ "Email (optional)": "Email (optional)", "Phone (optional)": "Phone (optional)", "Confirm": "Confirm", - "Use an email address to receover your account. Other users can invite you to rooms using your contact details.": "Use an email address to receover your account. Other users can invite you to rooms using your contact details.", + "Use an email address to recover your account. Other users can invite you to rooms using your contact details.": "Use an email address to recover your account. Other users can invite you to rooms using your contact details.", "Other servers": "Other servers", "Enter custom server URLs What does this mean?": "Enter custom server URLs What does this mean?", "Homeserver URL": "Homeserver URL", From 68ae72f85535928c03517c846246cdc735a3f7e1 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 31 Jan 2019 18:52:39 -0600 Subject: [PATCH 016/165] Spell homeserver correctly --- CHANGELOG.md | 2 +- src/AddThreepid.js | 2 +- src/ContentMessages.js | 2 +- src/MatrixClientPeg.js | 8 ++++---- src/Presence.js | 4 ++-- src/components/structures/GroupView.js | 2 +- src/components/structures/RoomDirectory.js | 6 +++--- src/components/structures/RoomView.js | 2 +- src/components/structures/auth/Login.js | 6 +++--- src/components/views/auth/CaptchaForm.js | 2 +- src/components/views/settings/DevicesPanel.js | 2 +- src/i18n/strings/en_EN.json | 16 ++++++++-------- 12 files changed, 27 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09ff79ae0e..7293b00d1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4081,7 +4081,7 @@ Changes in [0.6.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v [\#297](https://github.com/matrix-org/matrix-react-sdk/pull/297) * multiple URL preview support [\#290](https://github.com/matrix-org/matrix-react-sdk/pull/290) - * Add a fallback home server to log into + * Add a fallback homeserver to log into [\#293](https://github.com/matrix-org/matrix-react-sdk/pull/293) * Hopefully fix memory leak with velocity [\#291](https://github.com/matrix-org/matrix-react-sdk/pull/291) diff --git a/src/AddThreepid.js b/src/AddThreepid.js index 8de7e9e21c..adeaf84a69 100644 --- a/src/AddThreepid.js +++ b/src/AddThreepid.js @@ -19,7 +19,7 @@ import MatrixClientPeg from './MatrixClientPeg'; import { _t } from './languageHandler'; /** - * Allows a user to add a third party identifier to their Home Server and, + * Allows a user to add a third party identifier to their homeserver and, * optionally, the identity servers. * * This involves getting an email token from the identity server to "prove" that diff --git a/src/ContentMessages.js b/src/ContentMessages.js index f2bbdfafe5..a319118121 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -359,7 +359,7 @@ class ContentMessages { if (!upload.canceled) { let desc = _t('The file \'%(fileName)s\' failed to upload', {fileName: upload.fileName}) + '.'; if (err.http_status == 413) { - desc = _t('The file \'%(fileName)s\' exceeds this home server\'s size limit for uploads', {fileName: upload.fileName}); + desc = _t('The file \'%(fileName)s\' exceeds this homeserver\'s size limit for uploads', {fileName: upload.fileName}); } const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Upload failed', '', ErrorDialog, { diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index b216f5740c..882a913452 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -85,7 +85,7 @@ class MatrixClientPeg { /** * Replace this MatrixClientPeg's client with a client instance that has - * Home Server / Identity Server URLs and active credentials + * homeserver / identity server URLs and active credentials */ replaceUsingCreds(creds: MatrixClientCreds) { this._currentClientCreds = creds; @@ -164,14 +164,14 @@ class MatrixClientPeg { } /** - * Return the server name of the user's home server - * Throws an error if unable to deduce the home server name + * Return the server name of the user's homeserver + * Throws an error if unable to deduce the homeserver name * (eg. if the user is not logged in) */ getHomeServerName() { const matches = /^@.+:(.+)$/.exec(this.matrixClient.credentials.userId); if (matches === null || matches.length < 1) { - throw new Error("Failed to derive home server name from user ID!"); + throw new Error("Failed to derive homeserver name from user ID!"); } return matches[1]; } diff --git a/src/Presence.js b/src/Presence.js index 849efdef1c..8e00e95cdf 100644 --- a/src/Presence.js +++ b/src/Presence.js @@ -33,7 +33,7 @@ class Presence { } /** * Start listening the user activity to evaluate his presence state. - * Any state change will be sent to the Home Server. + * Any state change will be sent to the homeserver. */ async start() { this._unavailableTimer = new Timer(UNAVAILABLE_TIME_MS); @@ -78,7 +78,7 @@ class Presence { /** * Set the presence state. - * If the state has changed, the Home Server will be notified. + * If the state has changed, the homeserver will be notified. * @param {string} newState the new presence state (see PRESENCE enum) */ async setState(newState) { diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index bbbded6f2a..530a200a18 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -1324,7 +1324,7 @@ export default React.createClass({ } else { let extraText; if (this.state.error.errcode === 'M_UNRECOGNIZED') { - extraText =
{ _t('This Home server does not support communities') }
; + extraText =
{ _t('This homeserver does not support communities') }
; } return (
diff --git a/src/components/structures/RoomDirectory.js b/src/components/structures/RoomDirectory.js index c18dd4d48a..3fb2cc86ef 100644 --- a/src/components/structures/RoomDirectory.js +++ b/src/components/structures/RoomDirectory.js @@ -96,9 +96,9 @@ module.exports = React.createClass({ return; } const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to get protocol list from Home Server', '', ErrorDialog, { - title: _t('Failed to get protocol list from Home Server'), - description: _t('The Home Server may be too old to support third party networks'), + Modal.createTrackedDialog('Failed to get protocol list from homeserver', '', ErrorDialog, { + title: _t('Failed to get protocol list from homeserver'), + description: _t('The homeserver may be too old to support third party networks'), }); }); diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 01df8272fa..26ef3da739 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -78,7 +78,7 @@ module.exports = React.createClass({ // * invitedEmail (string) The email address that was invited to this room thirdPartyInvite: PropTypes.object, - // Any data about the room that would normally come from the Home Server + // Any data about the room that would normally come from the homeserver // but has been passed out-of-band, eg. the room name and avatar URL // from an email invite (a workaround for the fact that we can't // get this information from the HS using an email invite). diff --git a/src/components/structures/auth/Login.js b/src/components/structures/auth/Login.js index d1b0aad31a..c5e07aed5a 100644 --- a/src/components/structures/auth/Login.js +++ b/src/components/structures/auth/Login.js @@ -63,7 +63,7 @@ module.exports = React.createClass({ defaultIsUrl: PropTypes.string, // Secondary HS which we try to log into if the user is using // the default HS but login fails. Useful for migrating to a - // different home server without confusing users. + // different homeserver without confusing users. fallbackHsUrl: PropTypes.string, // An error passed along from higher up explaining that something @@ -160,7 +160,7 @@ module.exports = React.createClass({ // Some error strings only apply for logging in const usingEmail = username.indexOf("@") > 0; if (error.httpStatus === 400 && usingEmail) { - errorText = _t('This Home Server does not support login using email address.'); + errorText = _t('This homeserver does not support login using email address.'); } else if (error.errcode == 'M_RESOURCE_LIMIT_EXCEEDED') { const errorTop = messageForResourceLimitError( error.data.limit_type, @@ -241,7 +241,7 @@ module.exports = React.createClass({ }, function(error) { let errorText; if (error.httpStatus === 403) { - errorText = _t("Guest access is disabled on this Home Server."); + errorText = _t("Guest access is disabled on this homeserver."); } else { errorText = self._errorTextFromError(error); } diff --git a/src/components/views/auth/CaptchaForm.js b/src/components/views/auth/CaptchaForm.js index 01715b397c..ca450c5df4 100644 --- a/src/components/views/auth/CaptchaForm.js +++ b/src/components/views/auth/CaptchaForm.js @@ -141,7 +141,7 @@ module.exports = React.createClass({ return (
- { _t("This Home Server would like to make sure you are not a robot") } + { _t("This homeserver would like to make sure you are not a robot.") }
{ error } diff --git a/src/components/views/settings/DevicesPanel.js b/src/components/views/settings/DevicesPanel.js index 25850819bd..1f502fac2f 100644 --- a/src/components/views/settings/DevicesPanel.js +++ b/src/components/views/settings/DevicesPanel.js @@ -61,7 +61,7 @@ export default class DevicesPanel extends React.Component { let errtxt; if (error.httpStatus == 404) { // 404 probably means the HS doesn't yet support the API. - errtxt = _t("Your home server does not support device management."); + errtxt = _t("Your homeserver does not support device management."); } else { console.error("Error loading devices:", error); errtxt = _t("Unable to load device list"); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index fd56965470..e3fced8e7f 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -41,7 +41,7 @@ "Permission Required": "Permission Required", "You do not have permission to start a conference call in this room": "You do not have permission to start a conference call in this room", "The file '%(fileName)s' failed to upload": "The file '%(fileName)s' failed to upload", - "The file '%(fileName)s' exceeds this home server's size limit for uploads": "The file '%(fileName)s' exceeds this home server's size limit for uploads", + "The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "The file '%(fileName)s' exceeds this homeserver's size limit for uploads", "Upload Failed": "Upload Failed", "Failure to create room": "Failure to create room", "Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.", @@ -352,7 +352,7 @@ "New Password": "New Password", "Confirm password": "Confirm password", "Change Password": "Change Password", - "Your home server does not support device management.": "Your home server does not support device management.", + "Your homeserver does not support device management.": "Your homeserver does not support device management.", "Unable to load device list": "Unable to load device list", "Authentication": "Authentication", "Delete %(count)s devices|other": "Delete %(count)s devices", @@ -1178,7 +1178,7 @@ "Login": "Login", "powered by Matrix": "powered by Matrix", "Robot check is currently unavailable on desktop - please use a web browser": "Robot check is currently unavailable on desktop - please use a web browser", - "This Home Server would like to make sure you are not a robot": "This Home Server would like to make sure you are not a robot", + "This homeserver would like to make sure you are not a robot.": "This homeserver would like to make sure you are not a robot.", "Custom Server Options": "Custom Server Options", "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use this app with an existing Matrix account on a different homeserver.": "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use this app with an existing Matrix account on a different homeserver.", "You can also set a custom identity server, but you won't be able to invite users by email address, or be invited by email address yourself.": "You can also set a custom identity server, but you won't be able to invite users by email address, or be invited by email address yourself.", @@ -1273,7 +1273,7 @@ "Long Description (HTML)": "Long Description (HTML)", "Description": "Description", "Community %(groupId)s not found": "Community %(groupId)s not found", - "This Home server does not support communities": "This Home server does not support communities", + "This homeserver does not support communities": "This homeserver does not support communities", "Failed to load %(groupId)s": "Failed to load %(groupId)s", "Couldn't load home page": "Couldn't load home page", "You are currently using Riot anonymously as a guest.": "You are currently using Riot anonymously as a guest.", @@ -1301,8 +1301,8 @@ "Create a new community": "Create a new community", "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.", "You have no visible notifications": "You have no visible notifications", - "Failed to get protocol list from Home Server": "Failed to get protocol list from Home Server", - "The Home Server may be too old to support third party networks": "The Home Server may be too old to support third party networks", + "Failed to get protocol list from homeserver": "Failed to get protocol list from homeserver", + "The homeserver may be too old to support third party networks": "The homeserver may be too old to support third party networks", "Failed to get public room list": "Failed to get public room list", "The server may be unavailable or overloaded": "The server may be unavailable or overloaded", "Delete the room alias %(alias)s and remove %(name)s from the directory?": "Delete the room alias %(alias)s and remove %(name)s from the directory?", @@ -1399,11 +1399,11 @@ "Invalid homeserver discovery response": "Invalid homeserver discovery response", "Invalid identity server discovery response": "Invalid identity server discovery response", "General failure": "General failure", - "This Home Server does not support login using email address.": "This Home Server does not support login using email address.", + "This homeserver does not support login using email address.": "This homeserver does not support login using email address.", "Please contact your service administrator to continue using this service.": "Please contact your service administrator to continue using this service.", "Incorrect username and/or password.": "Incorrect username and/or password.", "Please note you are logging into the %(hs)s server, not matrix.org.": "Please note you are logging into the %(hs)s server, not matrix.org.", - "Guest access is disabled on this Home Server.": "Guest access is disabled on this Home Server.", + "Guest access is disabled on this homeserver.": "Guest access is disabled on this homeserver.", "Failed to perform homeserver discovery": "Failed to perform homeserver discovery", "The phone number entered looks invalid": "The phone number entered looks invalid", "Unknown failure discovering homeserver": "Unknown failure discovering homeserver", From b12b731781d3f1f3514b6fe724c860856b122650 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 21:20:30 -0700 Subject: [PATCH 017/165] Minor CSS tweaks --- res/css/structures/_TabbedView.scss | 1 - res/css/views/dialogs/_SettingsDialog.scss | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/css/structures/_TabbedView.scss b/res/css/structures/_TabbedView.scss index 2f448ff4a8..c87b4d053f 100644 --- a/res/css/structures/_TabbedView.scss +++ b/res/css/structures/_TabbedView.scss @@ -96,5 +96,4 @@ limitations under the License. flex-grow: 1; overflow: auto; min-height: 0; // firefox - } \ No newline at end of file diff --git a/res/css/views/dialogs/_SettingsDialog.scss b/res/css/views/dialogs/_SettingsDialog.scss index b1a4470b02..68206f32aa 100644 --- a/res/css/views/dialogs/_SettingsDialog.scss +++ b/res/css/views/dialogs/_SettingsDialog.scss @@ -29,7 +29,8 @@ limitations under the License. } .mx_TabbedView .mx_SettingsTab { - max-width: calc(100% - 130px); // 130px right hand padding + box-sizing: border-box; + padding-right: 130px; // Put some padding on the bottom to avoid the settings tab from // colliding harshly with the dialog when scrolled down. From a1f1dde9a4948bd92eb38e6f12fa8b597643c542 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 21:44:34 -0700 Subject: [PATCH 018/165] Remove flair from general user settings tab Fixes https://github.com/vector-im/riot-web/issues/8327 --- .../settings/tabs/GeneralUserSettingsTab.js | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/src/components/views/settings/tabs/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/GeneralUserSettingsTab.js index a504953cab..bfcc7b945c 100644 --- a/src/components/views/settings/tabs/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/GeneralUserSettingsTab.js @@ -16,11 +16,6 @@ limitations under the License. import React from 'react'; import {_t} from "../../../../languageHandler"; -import MatrixClientPeg from "../../../../MatrixClientPeg"; -import GroupUserSettings from "../../groups/GroupUserSettings"; -import PropTypes from "prop-types"; -import {MatrixClient} from "matrix-js-sdk"; -import { DragDropContext } from 'react-beautiful-dnd'; import ProfileSettings from "../ProfileSettings"; import EmailAddresses from "../EmailAddresses"; import PhoneNumbers from "../PhoneNumbers"; @@ -37,10 +32,6 @@ const Modal = require("../../../../Modal"); const dis = require("../../../../dispatcher"); export default class GeneralUserSettingsTab extends React.Component { - static childContextTypes = { - matrixClient: PropTypes.instanceOf(MatrixClient), - }; - constructor() { super(); @@ -50,12 +41,6 @@ export default class GeneralUserSettingsTab extends React.Component { }; } - getChildContext() { - return { - matrixClient: MatrixClientPeg.get(), - }; - } - _onLanguageChange = (newLanguage) => { if (this.state.language === newLanguage) return; @@ -105,16 +90,10 @@ export default class GeneralUserSettingsTab extends React.Component { }; _renderProfileSection() { - // HACK/TODO: Using DragDropContext feels wrong, but we need it. return (
{_t("Profile")} - - {_t("Flair")} - - -
); } From 0c0db4ecc70f935dad7ed4cf180881e7f7fdf4ab Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 21:48:44 -0700 Subject: [PATCH 019/165] Copy over disablement of media streams after permissions requested Fixes https://github.com/vector-im/riot-web/issues/8340 --- src/components/views/settings/tabs/VoiceSettingsTab.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/views/settings/tabs/VoiceSettingsTab.js b/src/components/views/settings/tabs/VoiceSettingsTab.js index 6e48d7f083..65f38c7841 100644 --- a/src/components/views/settings/tabs/VoiceSettingsTab.js +++ b/src/components/views/settings/tabs/VoiceSettingsTab.js @@ -40,7 +40,13 @@ export default class VoiceSettingsTab extends React.Component { this._refreshMediaDevices(); } - _refreshMediaDevices = async () => { + _refreshMediaDevices = async (stream) => { + if (stream) { + // kill stream so that we don't leave it lingering around with webcam enabled etc + // as here we called gUM to ask user for permission to their device names only + stream.getTracks().forEach((track) => track.stop()); + } + this.setState({ mediaDevices: await CallMediaHandler.getDevices(), activeAudioOutput: CallMediaHandler.getAudioOutput(), From b4fd0c3fbf6cd611d524b8d6b374f34602a342c8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 22:06:15 -0700 Subject: [PATCH 020/165] Add room directory publish button This was previously missed in the tab's layout. --- .../settings/tabs/GeneralRoomSettingsTab.js | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/components/views/settings/tabs/GeneralRoomSettingsTab.js b/src/components/views/settings/tabs/GeneralRoomSettingsTab.js index 2f7ef725b7..75373a69bc 100644 --- a/src/components/views/settings/tabs/GeneralRoomSettingsTab.js +++ b/src/components/views/settings/tabs/GeneralRoomSettingsTab.js @@ -23,6 +23,7 @@ import sdk from "../../../../index"; import AccessibleButton from "../../elements/AccessibleButton"; import {MatrixClient} from "matrix-js-sdk"; import dis from "../../../../dispatcher"; +import LabelledToggleSwitch from "../../elements/LabelledToggleSwitch"; export default class GeneralRoomSettingsTab extends React.Component { static childContextTypes = { @@ -33,12 +34,40 @@ export default class GeneralRoomSettingsTab extends React.Component { roomId: PropTypes.string.isRequired, }; + constructor() { + super(); + + this.state = { + isRoomPublished: false, // loaded async + }; + } + getChildContext() { return { matrixClient: MatrixClientPeg.get(), }; } + componentWillMount() { + MatrixClientPeg.get().getRoomDirectoryVisibility(this.props.roomId).then((result => { + this.setState({isRoomPublished: result.visibility === 'public'}); + })); + } + + onRoomPublishChange = (e) => { + const valueBefore = this.state.isRoomPublished; + const newValue = !valueBefore; + this.setState({isRoomPublished: newValue}); + + MatrixClientPeg.get().setRoomDirectoryVisibility( + this.props.roomId, + newValue ? 'public' : 'private', + ).catch(() => { + // Roll back the local echo on the change + this.setState({isRoomPublished: valueBefore}); + }); + }; + _saveAliases = (e) => { // TODO: Live modification? if (!this.refs.aliasSettings) return; @@ -67,6 +96,7 @@ export default class GeneralRoomSettingsTab extends React.Component { const room = client.getRoom(this.props.roomId); const canSetAliases = true; // Previously, we arbitrarily only allowed admins to do this + const canActuallySetAliases = room.currentState.mayClientSendStateEvent("m.room.aliases", client); const canSetCanonical = room.currentState.mayClientSendStateEvent("m.room.canonical_alias", client); const canonicalAliasEv = room.currentState.getStateEvents("m.room.canonical_alias", ''); const aliasEvents = room.currentState.getStateEvents("m.room.aliases"); @@ -90,6 +120,14 @@ export default class GeneralRoomSettingsTab extends React.Component { {_t("Save")}
+
+ +
{_t("Flair")}
From 3c3aa9197c56589e98eb8ce0690fcde876869483 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 11:24:52 +0100 Subject: [PATCH 021/165] UrlPreviewSettings doesnt have a saveSettings method anymore, which I think is intentional --- src/components/views/rooms/RoomSettings.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 9287eb3fae..46d9a0991c 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -310,12 +310,6 @@ module.exports = React.createClass({ promises.push(p); } - // url preview settings - const ps = this.saveUrlPreviewSettings(); - if (ps.length > 0) { - ps.map((p) => promises.push(p)); - } - // related groups promises.push(this.saveRelatedGroups()); @@ -346,11 +340,6 @@ module.exports = React.createClass({ return this.refs.color_settings.saveSettings(); }, - saveUrlPreviewSettings: function() { - if (!this.refs.url_preview_settings) { return Promise.resolve(); } - return this.refs.url_preview_settings.saveSettings(); - }, - saveEnableEncryption: function() { if (!this.refs.encrypt) { return Promise.resolve(); } From f2928c184dda3f4a538dd08cd8a0c8fb4a05bdff Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 13:39:25 +0100 Subject: [PATCH 022/165] create warning/verified icon to use in header/composer/member info --- res/css/_components.scss | 1 + res/css/views/rooms/_E2EIcon.scss | 33 +++++++++++++++++++ res/img/feather-icons/e2e/lock-verified.svg | 6 ++++ res/img/feather-icons/e2e/lock-warning.svg | 7 +++++ src/components/views/rooms/E2EIcon.js | 35 +++++++++++++++++++++ 5 files changed, 82 insertions(+) create mode 100644 res/css/views/rooms/_E2EIcon.scss create mode 100644 res/img/feather-icons/e2e/lock-verified.svg create mode 100644 res/img/feather-icons/e2e/lock-warning.svg create mode 100644 src/components/views/rooms/E2EIcon.js diff --git a/res/css/_components.scss b/res/css/_components.scss index e017d4b95a..ee55c000ff 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -107,6 +107,7 @@ @import "./views/rooms/_AppsDrawer.scss"; @import "./views/rooms/_Autocomplete.scss"; @import "./views/rooms/_AuxPanel.scss"; +@import "./views/rooms/_E2EIcon.scss"; @import "./views/rooms/_EntityTile.scss"; @import "./views/rooms/_EventTile.scss"; @import "./views/rooms/_JumpToBottomButton.scss"; diff --git a/res/css/views/rooms/_E2EIcon.scss b/res/css/views/rooms/_E2EIcon.scss new file mode 100644 index 0000000000..cd577df87b --- /dev/null +++ b/res/css/views/rooms/_E2EIcon.scss @@ -0,0 +1,33 @@ +/* +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_E2EIcon { + width: 25px; + height: 25px; + mask-repeat: no-repeat; + mask-position: center 0; + margin: 0 9px; +} + +.mx_E2EIcon_verified { + mask-image: url('$(res)/img/feather-icons/e2e/lock-verified.svg'); + background-color: $accent-color; +} + +.mx_E2EIcon_warning { + mask-image: url('$(res)/img/feather-icons/e2e/lock-warning.svg'); + background-color: $warning-color; +} diff --git a/res/img/feather-icons/e2e/lock-verified.svg b/res/img/feather-icons/e2e/lock-verified.svg new file mode 100644 index 0000000000..a1546daf7e --- /dev/null +++ b/res/img/feather-icons/e2e/lock-verified.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/res/img/feather-icons/e2e/lock-warning.svg b/res/img/feather-icons/e2e/lock-warning.svg new file mode 100644 index 0000000000..e6acfca965 --- /dev/null +++ b/res/img/feather-icons/e2e/lock-warning.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/components/views/rooms/E2EIcon.js b/src/components/views/rooms/E2EIcon.js new file mode 100644 index 0000000000..9be3efa450 --- /dev/null +++ b/src/components/views/rooms/E2EIcon.js @@ -0,0 +1,35 @@ +/* +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 classNames from 'classnames'; +import { _t } from '../../../languageHandler'; + +export default function(props) { + const isWarning = props.status === "warning"; + const isVerified = props.status === "verified"; + const e2eIconClasses = classNames({ + mx_E2EIcon: true, + mx_E2EIcon_warning: isWarning, + mx_E2EIcon_verified: isVerified, + }, props.className); + let e2eTitle; + if (isWarning) { + e2eTitle = _t("Some devices in this encrypted room are not trusted"); + } else if (isVerified) { + e2eTitle = _t("All devices in this encrypted room are trusted"); + } + return (
); +} From 0cdf3d0898cabf28f04b3a77bdc2b54661371114 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 13:40:19 +0100 Subject: [PATCH 023/165] add icon to room header --- src/components/views/rooms/RoomHeader.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index 3cdb9237be..dbf06fe547 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -33,6 +33,7 @@ import ManageIntegsButton from '../elements/ManageIntegsButton'; import {CancelButton} from './SimpleRoomHeader'; import SettingsStore from "../../../settings/SettingsStore"; import RoomHeaderButtons from '../right_panel/RoomHeaderButtons'; +import E2EIcon from './E2EIcon'; linkifyMatrix(linkify); @@ -52,6 +53,7 @@ module.exports = React.createClass({ onSearchClick: PropTypes.func, onLeaveClick: PropTypes.func, onCancelClick: PropTypes.func, + e2eStatus: PropTypes.string, }, getDefaultProps: function() { @@ -237,6 +239,8 @@ module.exports = React.createClass({ ); } + let e2eIcon = this.props.e2eStatus ? : undefined; + if (this.props.onCancelClick) { cancelButton = ; } @@ -413,6 +417,7 @@ module.exports = React.createClass({
{ roomAvatar }
+ { e2eIcon } { name } { topicElement } { spinner } From 09c3391dd8d2407fcc4727302fea3f8c9664557f Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 13:40:42 +0100 Subject: [PATCH 024/165] replace existing icon in composer with the new one --- res/css/views/rooms/_MessageComposer.scss | 7 +++- res/themes/dharma/css/_dharma.scss | 2 ++ res/themes/light/css/_base.scss | 2 ++ src/components/views/rooms/MessageComposer.js | 33 +++++++++---------- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss index dc4aec691b..7ee7efcaff 100644 --- a/res/css/views/rooms/_MessageComposer.scss +++ b/res/css/views/rooms/_MessageComposer.scss @@ -23,6 +23,10 @@ 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; @@ -71,9 +75,10 @@ limitations under the License. width: 100%; } -.mx_MessageComposer_e2eIcon { +.mx_MessageComposer_e2eIcon.mx_E2EIcon { position: absolute; left: 60px; + background-color: $composer-e2e-icon-color; } .mx_MessageComposer_noperm_error { diff --git a/res/themes/dharma/css/_dharma.scss b/res/themes/dharma/css/_dharma.scss index f976180144..482b3c51cb 100644 --- a/res/themes/dharma/css/_dharma.scss +++ b/res/themes/dharma/css/_dharma.scss @@ -142,6 +142,8 @@ $roomheader-addroom-color: #91A1C0; $roomtopic-color: #9fa9ba; $eventtile-meta-color: $roomtopic-color; +$composer-e2e-icon-color: #c9ced6; + // ******************** $roomtile-name-color: #61708b; diff --git a/res/themes/light/css/_base.scss b/res/themes/light/css/_base.scss index 998325e1b7..f5d7e7be04 100644 --- a/res/themes/light/css/_base.scss +++ b/res/themes/light/css/_base.scss @@ -134,6 +134,8 @@ $roomheader-color: $primary-fg-color; $roomheader-addroom-color: $primary-bg-color; $roomtopic-color: $settings-grey-fg-color; $eventtile-meta-color: $roomtopic-color; + +$composer-e2e-icon-color: #c9ced6; // ******************** $roomtile-name-color: rgba(69, 69, 69, 0.8); diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 7681c2dc13..7117825d76 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -26,6 +26,9 @@ import RoomViewStore from '../../../stores/RoomViewStore'; import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; import Stickerpicker from './Stickerpicker'; import { makeRoomPermalink } from '../../../matrix-to'; +import classNames from 'classnames'; + +import E2EIcon from './E2EIcon'; const formatButtonList = [ _td("bold"), @@ -316,25 +319,14 @@ export default class MessageComposer extends React.Component { ); } - let e2eImg; let e2eTitle; let e2eClass; - const roomIsEncrypted = MatrixClientPeg.get().isRoomEncrypted(this.props.room.roomId); - if (roomIsEncrypted) { - // FIXME: show a /!\ if there are untrusted devices in the room... - e2eImg = require("../../../../res/img/e2e-verified.svg"); - e2eTitle = _t('Encrypted room'); - e2eClass = 'mx_MessageComposer_e2eIcon'; - } else { - e2eImg = require("../../../../res/img/e2e-unencrypted.svg"); - e2eTitle = _t('Unencrypted room'); - e2eClass = 'mx_MessageComposer_e2eIcon mx_filterFlipColor'; + if (this.props.e2eStatus) { + controls.push( + ); } - controls.push( - {e2eTitle}, - ); - let callButton; let videoCallButton; let hangupButton; @@ -413,6 +405,7 @@ export default class MessageComposer extends React.Component { key="controls_formatting" /> ) : null; + const roomIsEncrypted = MatrixClientPeg.get().isRoomEncrypted(this.props.room.roomId); let placeholderText; if (this.state.isQuoting) { if (roomIsEncrypted) { @@ -509,9 +502,13 @@ export default class MessageComposer extends React.Component {
; } + const wrapperClasses = classNames({ + mx_MessageComposer_wrapper: true, + mx_MessageComposer_hasE2EIcon: !!this.props.e2eStatus, + }); return (
-
+
{ controls }
From 8abb7ebc65120300c1b33df273652eab0a78cb76 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 14:35:03 +0100 Subject: [PATCH 025/165] monitor device verification in RoomView and update e2eStatus --- src/components/structures/RoomView.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 01df8272fa..9718ef0ef6 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -168,6 +168,7 @@ module.exports = React.createClass({ MatrixClientPeg.get().on("Room.myMembership", this.onMyMembership); MatrixClientPeg.get().on("accountData", this.onAccountData); MatrixClientPeg.get().on("crypto.keyBackupStatus", this.onKeyBackupStatus); + MatrixClientPeg.get().on("deviceVerificationChanged", this.onDeviceVerificationChanged); this._fetchMediaConfig(); // Start listening for RoomViewStore updates this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate); @@ -457,6 +458,7 @@ module.exports = React.createClass({ MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember); MatrixClientPeg.get().removeListener("accountData", this.onAccountData); MatrixClientPeg.get().removeListener("crypto.keyBackupStatus", this.onKeyBackupStatus); + MatrixClientPeg.get().removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged); } window.removeEventListener('beforeunload', this.onPageUnload); @@ -642,6 +644,7 @@ module.exports = React.createClass({ this._updatePreviewUrlVisibility(room); this._loadMembersIfJoined(room); this._calculateRecommendedVersion(room); + this._updateE2EStatus(room); }, _calculateRecommendedVersion: async function(room) { @@ -733,6 +736,23 @@ module.exports = React.createClass({ }); }, + onDeviceVerificationChanged: function(userId, device) { + const room = this.state.room; + if (!MatrixClientPeg.get().isRoomEncrypted(room.roomId)) { + return; + } + if (!room.currentState.getMember(userId)) { + return; + } + this._updateE2EStatus(room); + }, + + _updateE2EStatus: function(room) { + room.hasUnverifiedDevices().then((hasUnverifiedDevices) => { + this.setState({e2eStatus: hasUnverifiedDevices ? "warning" : "verified"}); + }); + }, + updateTint: function() { const room = this.state.room; if (!room) return; @@ -1575,6 +1595,7 @@ module.exports = React.createClass({ room={this.state.room} oobData={this.props.oobData} collapsedRhs={this.props.collapsedRhs} + e2eStatus={this.state.e2eStatus} />
@@ -1622,6 +1643,7 @@ module.exports = React.createClass({ ref="header" room={this.state.room} collapsedRhs={this.props.collapsedRhs} + e2eStatus={this.state.e2eStatus} />
@@ -1767,6 +1789,7 @@ module.exports = React.createClass({ disabled={this.props.disabled} showApps={this.state.showApps} uploadAllowed={this.isFileUploadAllowed} + e2eStatus={this.state.e2eStatus} />; } @@ -1917,6 +1940,7 @@ module.exports = React.createClass({ onCancelClick={(aux && !hideCancel) ? this.onCancelClick : null} onForgetClick={(myMembership === "leave") ? this.onForgetClick : null} onLeaveClick={(myMembership === "join") ? this.onLeaveClick : null} + e2eStatus={this.state.e2eStatus} />
From 2596a0ffc23984b4a5d9d22c202e99533ad17e57 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 14:35:25 +0100 Subject: [PATCH 026/165] linting --- src/components/views/rooms/RoomHeader.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index dbf06fe547..cee1814011 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -239,7 +239,9 @@ module.exports = React.createClass({ ); } - let e2eIcon = this.props.e2eStatus ? : undefined; + const e2eIcon = this.props.e2eStatus ? + : + undefined; if (this.props.onCancelClick) { cancelButton = ; From 918d4490c75f12df1a59e7e12f0840081ef30db0 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 1 Feb 2019 08:31:36 -0600 Subject: [PATCH 027/165] Add more detail to error message --- src/components/structures/auth/Registration.js | 2 +- src/i18n/strings/en_EN.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/auth/Registration.js b/src/components/structures/auth/Registration.js index 166ae69a8f..c5539eade6 100644 --- a/src/components/structures/auth/Registration.js +++ b/src/components/structures/auth/Registration.js @@ -166,7 +166,7 @@ module.exports = React.createClass({ }); } else if (e.httpStatus === 403 && e.errcode === "M_UNKNOWN") { this.setState({ - errorText: _t("Registration has been disabled"), + errorText: _t("Registration has been disabled on this homeserver."), }); } else { this.setState({ diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 9e9f9e4fad..846a91f4e7 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1418,7 +1418,7 @@ "Failed to fetch avatar URL": "Failed to fetch avatar URL", "Set a display name:": "Set a display name:", "Upload an avatar:": "Upload an avatar:", - "Registration has been disabled": "Registration has been disabled", + "Registration has been disabled on this homeserver.": "Registration has been disabled on this homeserver.", "Unable to query for supported registration methods": "Unable to query for supported registration methods", "This server does not support authentication with a phone number.": "This server does not support authentication with a phone number.", "Missing password.": "Missing password.", From e414fe434c17b0ef956e91f03f630740380d62e2 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 1 Feb 2019 08:32:47 -0600 Subject: [PATCH 028/165] Add full stop --- src/components/structures/auth/Registration.js | 2 +- src/i18n/strings/en_EN.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/auth/Registration.js b/src/components/structures/auth/Registration.js index c5539eade6..c0b393febf 100644 --- a/src/components/structures/auth/Registration.js +++ b/src/components/structures/auth/Registration.js @@ -170,7 +170,7 @@ module.exports = React.createClass({ }); } else { this.setState({ - errorText: _t("Unable to query for supported registration methods"), + errorText: _t("Unable to query for supported registration methods."), }); } } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 846a91f4e7..9a04b30bbb 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1419,7 +1419,7 @@ "Set a display name:": "Set a display name:", "Upload an avatar:": "Upload an avatar:", "Registration has been disabled on this homeserver.": "Registration has been disabled on this homeserver.", - "Unable to query for supported registration methods": "Unable to query for supported registration methods", + "Unable to query for supported registration methods.": "Unable to query for supported registration methods.", "This server does not support authentication with a phone number.": "This server does not support authentication with a phone number.", "Missing password.": "Missing password.", "Passwords don't match.": "Passwords don't match.", From ba50ef8445de87670148428e4c3df3e5e209a6ca Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 31 Jan 2019 16:37:37 -0600 Subject: [PATCH 029/165] Clarify required auth stages --- src/components/views/auth/RegistrationForm.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/views/auth/RegistrationForm.js b/src/components/views/auth/RegistrationForm.js index 76b4cdb621..f18d2c2a49 100644 --- a/src/components/views/auth/RegistrationForm.js +++ b/src/components/views/auth/RegistrationForm.js @@ -270,11 +270,15 @@ module.exports = React.createClass({ this.validateField(FIELD_USERNAME, ev.type); }, + /** + * A step is required if all flows include that step. + * + * @param {string} step A stage name to check + * @returns {boolean} Whether it is required + */ _authStepIsRequired(step) { - // A step is required if no flow exists which does not include that step - // (Notwithstanding setups like either email or msisdn being required) - return !this.props.flows.some((flow) => { - return !flow.stages.includes(step); + return this.props.flows.every((flow) => { + return flow.stages.includes(step); }); }, From 4ed13e897aa6c6d5cf4784c20f913fa7cf60a789 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 31 Jan 2019 18:07:40 -0600 Subject: [PATCH 030/165] Hide registration fields that aren't used by any flow --- src/components/views/auth/RegistrationForm.js | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/components/views/auth/RegistrationForm.js b/src/components/views/auth/RegistrationForm.js index f18d2c2a49..acde4d03fe 100644 --- a/src/components/views/auth/RegistrationForm.js +++ b/src/components/views/auth/RegistrationForm.js @@ -282,6 +282,18 @@ module.exports = React.createClass({ }); }, + /** + * A step is used if any flows include that step. + * + * @param {string} step A stage name to check + * @returns {boolean} Whether it is used + */ + _authStepIsUsed(step) { + return this.props.flows.some((flow) => { + return flow.stages.includes(step); + }); + }, + render: function() { let yourMatrixAccountText = _t('Create your account'); try { @@ -302,24 +314,28 @@ module.exports = React.createClass({ ; } - const emailPlaceholder = this._authStepIsRequired('m.login.email.identity') ? - _t("Email") : - _t("Email (optional)"); + let emailSection; + if (this._authStepIsUsed('m.login.email.identity')) { + const emailPlaceholder = this._authStepIsRequired('m.login.email.identity') ? + _t("Email") : + _t("Email (optional)"); - const emailSection = ( -
- -
- ); + emailSection = ( +
+ +
+ ); + } + const threePidLogin = !SdkConfig.get().disable_3pid_login; const CountryDropdown = sdk.getComponent('views.auth.CountryDropdown'); let phoneSection; - if (!SdkConfig.get().disable_3pid_login) { + if (threePidLogin && this._authStepIsUsed('m.login.msisdn')) { const phonePlaceholder = this._authStepIsRequired('m.login.msisdn') ? _t("Phone") : _t("Phone (optional)"); From 88ad780b6b24e5231f72c1600c69befd8ed31bbf Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 16:43:12 +0100 Subject: [PATCH 031/165] update message e2e icons also remove encrypted icon as header/composer already indicate encryption --- res/css/views/rooms/_EventTile.scss | 17 +++++++- res/img/feather-icons/e2e/warning.svg | 6 +++ src/components/views/rooms/EventTile.js | 52 +++++++------------------ 3 files changed, 36 insertions(+), 39 deletions(-) create mode 100644 res/img/feather-icons/e2e/warning.svg diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index c920d6e390..7c9a6babea 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -281,9 +281,24 @@ limitations under the License. .mx_EventTile_e2eIcon { display: block; position: absolute; - top: 9px; + top: 8px; left: 46px; + width: 15px; + height: 15px; cursor: pointer; + mask-size: 14px; + mask-repeat: no-repeat; + mask-position: 0; +} + +.mx_EventTile_e2eIcon_undecryptable, .mx_EventTile_e2eIcon_unverified { + mask-image: url('$(res)/img/feather-icons/e2e/warning.svg'); + background-color: $warning-color; +} + +.mx_EventTile_e2eIcon_unencrypted { + mask-image: url('$(res)/img/feather-icons/e2e/warning.svg'); + background-color: $composer-e2e-icon-color; } .mx_EventTile_e2eIcon_hidden { diff --git a/res/img/feather-icons/e2e/warning.svg b/res/img/feather-icons/e2e/warning.svg new file mode 100644 index 0000000000..e6c246dba9 --- /dev/null +++ b/res/img/feather-icons/e2e/warning.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index acb122ad4e..e4a6695ff5 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -459,17 +459,21 @@ module.exports = withMatrixClient(React.createClass({ // event is encrypted, display padlock corresponding to whether or not it is verified if (ev.isEncrypted()) { - return this.state.verified ? : ; + if (this.state.verified) { + return; // no icon for verified + } else { + return (); + } } if (this.props.matrixClient.isRoomEncrypted(ev.getRoomId())) { // else if room is encrypted // and event is being encrypted or is not_sent (Unknown Devices/Network Error) if (ev.status === EventStatus.ENCRYPTING) { - return ; + return; } if (ev.status === EventStatus.NOT_SENT) { - return ; + return; } // if the event is not encrypted, but it's an e2e room, show the open padlock return ; @@ -767,57 +771,29 @@ module.exports.haveTileForEvent = function(e) { function E2ePadlockUndecryptable(props) { return ( - - ); -} - -function E2ePadlockEncrypting(props) { - return ( - - ); -} - -function E2ePadlockNotSent(props) { - return ( - - ); -} - -function E2ePadlockVerified(props) { - return ( - + ); } function E2ePadlockUnverified(props) { return ( - + ); } function E2ePadlockUnencrypted(props) { return ( - + ); } function E2ePadlock(props) { if (SettingsStore.getValue("alwaysShowEncryptionIcons")) { - return ; + return
; } else { - return ; + return
; } } From 48c0e5a3ac7fb4fd06f673dc1d5479dae74e175d Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 16:44:16 +0100 Subject: [PATCH 032/165] update icons --- res/img/feather-icons/e2e/lock-verified.svg | 6 +++--- res/img/feather-icons/e2e/lock-warning.svg | 12 +++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/res/img/feather-icons/e2e/lock-verified.svg b/res/img/feather-icons/e2e/lock-verified.svg index a1546daf7e..4cd4684ea2 100644 --- a/res/img/feather-icons/e2e/lock-verified.svg +++ b/res/img/feather-icons/e2e/lock-verified.svg @@ -1,6 +1,6 @@ - - - + + + diff --git a/res/img/feather-icons/e2e/lock-warning.svg b/res/img/feather-icons/e2e/lock-warning.svg index e6acfca965..507c532f9d 100644 --- a/res/img/feather-icons/e2e/lock-warning.svg +++ b/res/img/feather-icons/e2e/lock-warning.svg @@ -1,7 +1,9 @@ - - - - - + + + + + + + From 21fe2663944ddb142a4366ba473944aade7b809e Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 17:08:09 +0100 Subject: [PATCH 033/165] add icon to member info to indicate all devices of a user are trusted --- res/css/views/rooms/_MemberInfo.scss | 4 ++++ src/components/views/rooms/E2EIcon.js | 8 ++++++-- src/components/views/rooms/MemberInfo.js | 19 +++++++++++++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/res/css/views/rooms/_MemberInfo.scss b/res/css/views/rooms/_MemberInfo.scss index 99771fece0..707c186518 100644 --- a/res/css/views/rooms/_MemberInfo.scss +++ b/res/css/views/rooms/_MemberInfo.scss @@ -26,6 +26,10 @@ limitations under the License. display: flex; } +.mx_MemberInfo_name > .mx_E2EIcon { + margin-left: 0; +} + .mx_MemberInfo_cancel { height: 16px; padding: 10px 15px; diff --git a/src/components/views/rooms/E2EIcon.js b/src/components/views/rooms/E2EIcon.js index 9be3efa450..30891e84b7 100644 --- a/src/components/views/rooms/E2EIcon.js +++ b/src/components/views/rooms/E2EIcon.js @@ -27,9 +27,13 @@ export default function(props) { }, props.className); let e2eTitle; if (isWarning) { - e2eTitle = _t("Some devices in this encrypted room are not trusted"); + e2eTitle = props.isUser ? + _t("Some devices for this user are not trusted") : + _t("Some devices in this encrypted room are not trusted"); } else if (isVerified) { - e2eTitle = _t("All devices in this encrypted room are trusted"); + e2eTitle = props.isUser ? + _t("All devices for this user are trusted") : + _t("All devices in this encrypted room are trusted"); } return (
); } diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 9859861870..5df0da7491 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -43,6 +43,7 @@ import RoomViewStore from '../../../stores/RoomViewStore'; import SdkConfig from '../../../SdkConfig'; import MultiInviter from "../../../utils/MultiInviter"; import SettingsStore from "../../../settings/SettingsStore"; +import E2EIcon from "./E2EIcon"; module.exports = withMatrixClient(React.createClass({ displayName: 'MemberInfo', @@ -153,11 +154,19 @@ module.exports = withMatrixClient(React.createClass({ // Promise.resolve to handle transition from static result to promise; can be removed // in future Promise.resolve(this.props.matrixClient.getStoredDevicesForUser(userId)).then((devices) => { - this.setState({devices: devices}); + this.setState({ + devices: devices, + e2eStatus: this._getE2EStatus(devices), + }); }); } }, + _getE2EStatus: function(devices) { + const hasUnverifiedDevice = devices.some((device) => device.isUnverified()); + return hasUnverifiedDevice ? "warning" : "verified"; + }, + onRoom: function(room) { this.forceUpdate(); }, @@ -234,8 +243,13 @@ module.exports = withMatrixClient(React.createClass({ // we got cancelled - presumably a different user now return; } + self._disambiguateDevices(devices); - self.setState({devicesLoading: false, devices: devices}); + self.setState({ + devicesLoading: false, + devices: devices, + e2eStatus: self._getE2EStatus(devices), + }); }, function(err) { console.log("Error downloading devices", err); self.setState({devicesLoading: false}); @@ -965,6 +979,7 @@ module.exports = withMatrixClient(React.createClass({ {_t('Close')} + { this.state.e2eStatus ? : undefined } { memberName }
{ avatarElement } From ce5e56aaace7a0c669749ce28fda68a9f78298e1 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 17:32:46 +0100 Subject: [PATCH 034/165] update icons in member info device section --- res/css/views/rooms/_MemberDeviceInfo.scss | 19 +++++++++++ res/img/feather-icons/e2e/blacklisted.svg | 6 ++++ res/img/feather-icons/e2e/verified.svg | 3 ++ .../views/rooms/MemberDeviceInfo.js | 32 ++++++------------- 4 files changed, 37 insertions(+), 23 deletions(-) create mode 100644 res/img/feather-icons/e2e/blacklisted.svg create mode 100644 res/img/feather-icons/e2e/verified.svg diff --git a/res/css/views/rooms/_MemberDeviceInfo.scss b/res/css/views/rooms/_MemberDeviceInfo.scss index 6ccc4c7ae3..f780c50410 100644 --- a/res/css/views/rooms/_MemberDeviceInfo.scss +++ b/res/css/views/rooms/_MemberDeviceInfo.scss @@ -20,6 +20,25 @@ limitations under the License. align-items: start; } +.mx_MemberDeviceInfo_icon { + margin-top: 4px; + width: 12px; + height: 12px; + mask-repeat: no-repeat; +} +.mx_MemberDeviceInfo_icon_blacklisted { + mask-image: url('$(res)/img/feather-icons/e2e/blacklisted.svg'); + background-color: $warning-color; +} +.mx_MemberDeviceInfo_icon_verified { + mask-image: url('$(res)/img/feather-icons/e2e/verified.svg'); + background-color: $accent-color; +} +.mx_MemberDeviceInfo_icon_unverified { + mask-image: url('$(res)/img/feather-icons/e2e/warning.svg'); + background-color: $warning-color; +} + .mx_MemberDeviceInfo > .mx_DeviceVerifyButtons { display: flex; flex-direction: column; diff --git a/res/img/feather-icons/e2e/blacklisted.svg b/res/img/feather-icons/e2e/blacklisted.svg new file mode 100644 index 0000000000..63897c2227 --- /dev/null +++ b/res/img/feather-icons/e2e/blacklisted.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/res/img/feather-icons/e2e/verified.svg b/res/img/feather-icons/e2e/verified.svg new file mode 100644 index 0000000000..f143f854e6 --- /dev/null +++ b/res/img/feather-icons/e2e/verified.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/views/rooms/MemberDeviceInfo.js b/src/components/views/rooms/MemberDeviceInfo.js index b9c276f0d1..67f99e4d1d 100644 --- a/src/components/views/rooms/MemberDeviceInfo.js +++ b/src/components/views/rooms/MemberDeviceInfo.js @@ -18,32 +18,18 @@ import React from 'react'; import PropTypes from 'prop-types'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import classNames from 'classnames'; export default class MemberDeviceInfo extends React.Component { render() { - let indicator = null; const DeviceVerifyButtons = sdk.getComponent('elements.DeviceVerifyButtons'); - - if (this.props.device.isBlocked()) { - indicator = ( -
- {_t("Blacklisted")} -
- ); - } else if (this.props.device.isVerified()) { - indicator = ( -
- {_t("Verified")} -
- ); - } else { - indicator = ( -
- {_t("Unverified")} -
- ); - } - + const iconClasses = classNames({ + mx_MemberDeviceInfo_icon: true, + mx_MemberDeviceInfo_icon_blacklisted: this.props.device.isBlocked(), + mx_MemberDeviceInfo_icon_verified: this.props.device.isVerified(), + mx_MemberDeviceInfo_icon_unverified: this.props.device.isUnverified(), + }); + const indicator = (
); const deviceName = this.props.device.ambiguous ? (this.props.device.getDisplayName() ? this.props.device.getDisplayName() : "") + " (" + this.props.device.deviceId + ")" : this.props.device.getDisplayName(); @@ -52,10 +38,10 @@ export default class MemberDeviceInfo extends React.Component { return (
+ { indicator }
{ deviceName } - { indicator }
From e55dbfc6feeef8d95256971d76b7012413122eff Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 17:52:27 +0100 Subject: [PATCH 035/165] don't show e2e icon in unencrypted rooms upon loading the room --- src/components/structures/RoomView.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 9718ef0ef6..fb3c95fdcd 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -738,9 +738,6 @@ module.exports = React.createClass({ onDeviceVerificationChanged: function(userId, device) { const room = this.state.room; - if (!MatrixClientPeg.get().isRoomEncrypted(room.roomId)) { - return; - } if (!room.currentState.getMember(userId)) { return; } @@ -748,6 +745,9 @@ module.exports = React.createClass({ }, _updateE2EStatus: function(room) { + if (!MatrixClientPeg.get().isRoomEncrypted(room.roomId)) { + return; + } room.hasUnverifiedDevices().then((hasUnverifiedDevices) => { this.setState({e2eStatus: hasUnverifiedDevices ? "warning" : "verified"}); }); From 9134548558eba827993b7e6e356fb758353369b4 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 17:52:57 +0100 Subject: [PATCH 036/165] update room status bar warning icon --- res/css/structures/_RoomStatusBar.scss | 2 +- src/components/structures/RoomStatusBar.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/res/css/structures/_RoomStatusBar.scss b/res/css/structures/_RoomStatusBar.scss index 2a9cc9f6c7..1054654670 100644 --- a/res/css/structures/_RoomStatusBar.scss +++ b/res/css/structures/_RoomStatusBar.scss @@ -121,7 +121,7 @@ limitations under the License. .mx_RoomStatusBar_connectionLostBar img { padding-left: 10px; - padding-right: 22px; + padding-right: 10px; vertical-align: middle; float: left; } diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index b57bac805e..ab7f472931 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -290,7 +290,7 @@ module.exports = React.createClass({ } return
- +
{ title } @@ -309,7 +309,7 @@ module.exports = React.createClass({ if (this._shouldShowConnectionError()) { return (
- /!\ + /!\
{ _t('Connectivity to the server has been lost.') } From 571c059f0d46731e3b77093111584d1dd89ad269 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 18:15:19 +0100 Subject: [PATCH 037/165] fix layout --- res/css/views/dialogs/_UnknownDeviceDialog.scss | 4 ++++ src/components/views/dialogs/UnknownDeviceDialog.js | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/res/css/views/dialogs/_UnknownDeviceDialog.scss b/res/css/views/dialogs/_UnknownDeviceDialog.scss index e3801e3550..a924704769 100644 --- a/res/css/views/dialogs/_UnknownDeviceDialog.scss +++ b/res/css/views/dialogs/_UnknownDeviceDialog.scss @@ -28,6 +28,10 @@ limitations under the License. flex-direction: column; } +.mx_UnknownDeviceDialog .mx_DeviceVerifyButtons { + float: right; +} + .mx_UnknownDeviceDialog .mx_Dialog_content { margin-bottom: 24px; } diff --git a/src/components/views/dialogs/UnknownDeviceDialog.js b/src/components/views/dialogs/UnknownDeviceDialog.js index 07f8b6187f..959c14cc7d 100644 --- a/src/components/views/dialogs/UnknownDeviceDialog.js +++ b/src/components/views/dialogs/UnknownDeviceDialog.js @@ -32,8 +32,8 @@ function DeviceListEntry(props) { return (
  • - { device.deviceId } +
    { device.getDisplayName() }
  • From 728748c9cd4b222ae7ff43df6561dceaed03ca7f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 10:29:13 -0700 Subject: [PATCH 038/165] Disable old settings, making tabbed settings the default This is intentionally not removing the labs flag or other supporting structures of the old settings to make a revert as easy as possible in the event that needs to happen. All of the cruft left behind (TempTab, temp styles, labs flag, old components, etc) will be removed in the very near future. --- src/components/structures/MatrixChat.js | 2 +- src/components/views/dialogs/RoomSettingsDialog.js | 12 ++++++------ src/components/views/dialogs/UserSettingsDialog.js | 10 +++++----- src/stores/RoomViewStore.js | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index d0a5aa42c4..613d310da9 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -572,7 +572,7 @@ export default React.createClass({ this._viewIndexedRoom(payload.roomIndex); break; case 'view_user_settings': { - if (SettingsStore.isFeatureEnabled("feature_tabbed_settings")) { + if (true || SettingsStore.isFeatureEnabled("feature_tabbed_settings")) { const UserSettingsDialog = sdk.getComponent("dialogs.UserSettingsDialog"); Modal.createTrackedDialog('User settings', '', UserSettingsDialog, {}, 'mx_SettingsDialog'); } else { diff --git a/src/components/views/dialogs/RoomSettingsDialog.js b/src/components/views/dialogs/RoomSettingsDialog.js index 0578ccaffd..89e96ad011 100644 --- a/src/components/views/dialogs/RoomSettingsDialog.js +++ b/src/components/views/dialogs/RoomSettingsDialog.js @@ -81,13 +81,13 @@ export default class RoomSettingsDialog extends React.Component { tabs.push(new Tab( _td("Advanced"), "mx_RoomSettingsDialog_warningIcon", - , - )); - tabs.push(new Tab( - _td("Visit old settings"), - "mx_RoomSettingsDialog_warningIcon", - , + , )); + // tabs.push(new Tab( + // _td("Visit old settings"), + // "mx_RoomSettingsDialog_warningIcon", + // , + // )); return tabs; } diff --git a/src/components/views/dialogs/UserSettingsDialog.js b/src/components/views/dialogs/UserSettingsDialog.js index 2616542bf7..d241be7660 100644 --- a/src/components/views/dialogs/UserSettingsDialog.js +++ b/src/components/views/dialogs/UserSettingsDialog.js @@ -96,11 +96,11 @@ export default class UserSettingsDialog extends React.Component { "mx_UserSettingsDialog_helpIcon", , )); - tabs.push(new Tab( - _td("Visit old settings"), - "mx_UserSettingsDialog_helpIcon", - , - )); + // tabs.push(new Tab( + // _td("Visit old settings"), + // "mx_UserSettingsDialog_helpIcon", + // , + // )); return tabs; } diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index ba78e7687f..db49de805b 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -120,7 +120,7 @@ class RoomViewStore extends Store { }); break; case 'open_room_settings': - if (SettingsStore.isFeatureEnabled("feature_tabbed_settings")) { + if (true || SettingsStore.isFeatureEnabled("feature_tabbed_settings")) { const RoomSettingsDialog = sdk.getComponent("dialogs.RoomSettingsDialog"); Modal.createTrackedDialog('Room settings', '', RoomSettingsDialog, { roomId: this._state.roomId, From 2a9149668c82772e12e26e04d881800e358f6958 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 11:00:06 -0700 Subject: [PATCH 039/165] thisfea -> this idk what I was doing --- src/components/views/dialogs/RoomSettingsDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/RoomSettingsDialog.js b/src/components/views/dialogs/RoomSettingsDialog.js index 89e96ad011..9718d29bbc 100644 --- a/src/components/views/dialogs/RoomSettingsDialog.js +++ b/src/components/views/dialogs/RoomSettingsDialog.js @@ -81,7 +81,7 @@ export default class RoomSettingsDialog extends React.Component { tabs.push(new Tab( _td("Advanced"), "mx_RoomSettingsDialog_warningIcon", - , + , )); // tabs.push(new Tab( // _td("Visit old settings"), From ea8de6fe0706f1dea6c88f0aed955b6f4fbb5009 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 19:03:54 +0100 Subject: [PATCH 040/165] add translations --- src/i18n/strings/en_EN.json | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 2155a07a74..50f0b83c24 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -571,6 +571,10 @@ " (unsupported)": " (unsupported)", "Join as voice or video.": "Join as voice or video.", "Ongoing conference call%(supportedText)s.": "Ongoing conference call%(supportedText)s.", + "Some devices for this user are not trusted": "Some devices for this user are not trusted", + "Some devices in this encrypted room are not trusted": "Some devices in this encrypted room are not trusted", + "All devices for this user are trusted": "All devices for this user are trusted", + "All devices in this encrypted room are trusted": "All devices in this encrypted room are trusted", "This event could not be displayed": "This event could not be displayed", "%(senderName)s sent an image": "%(senderName)s sent an image", "%(senderName)s sent a video": "%(senderName)s sent a video", @@ -582,16 +586,10 @@ "Key request sent.": "Key request sent.", "Re-request encryption keys from your other devices.": "Re-request encryption keys from your other devices.", "Undecryptable": "Undecryptable", - "Encrypting": "Encrypting", - "Encrypted, not sent": "Encrypted, not sent", - "Encrypted by a verified device": "Encrypted by a verified device", "Encrypted by an unverified device": "Encrypted by an unverified device", "Unencrypted message": "Unencrypted message", "Please select the destination room for this message": "Please select the destination room for this message", "Scroll to bottom of page": "Scroll to bottom of page", - "Blacklisted": "Blacklisted", - "Verified": "Verified", - "Unverified": "Unverified", "device id: ": "device id: ", "Disinvite": "Disinvite", "Kick": "Kick", @@ -643,8 +641,6 @@ "Are you sure you want to upload the following files?": "Are you sure you want to upload the following files?", "The following files cannot be uploaded:": "The following files cannot be uploaded:", "Upload Files": "Upload Files", - "Encrypted room": "Encrypted room", - "Unencrypted room": "Unencrypted room", "Hangup": "Hangup", "Voice call": "Voice call", "Video call": "Video call", @@ -1438,6 +1434,7 @@ "Users": "Users", "unknown device": "unknown device", "NOT verified": "NOT verified", + "Blacklisted": "Blacklisted", "verified": "verified", "Name": "Name", "Verification": "Verification", From 987b11973141da54221001fa0081f2a6a0d42353 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 19:14:11 +0100 Subject: [PATCH 041/165] also update e2e icon once the room becomes encrypted --- src/components/structures/RoomView.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index fb3c95fdcd..9a81192e39 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -591,6 +591,10 @@ module.exports = React.createClass({ this._updatePreviewUrlVisibility(room); } + if (ev.getType() === "m.room.encryption") { + this._updateE2EStatus(room); + } + // ignore anything but real-time updates at the end of the room: // updates from pagination will happen when the paginate completes. if (toStartOfTimeline || !data || !data.liveEvent) return; From a09133960c33ba5b104d2df3d3bcddf93f092bf2 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 1 Feb 2019 19:16:06 +0100 Subject: [PATCH 042/165] pr feedback --- res/themes/light/css/_base.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/themes/light/css/_base.scss b/res/themes/light/css/_base.scss index f5d7e7be04..8185ba0ace 100644 --- a/res/themes/light/css/_base.scss +++ b/res/themes/light/css/_base.scss @@ -136,6 +136,7 @@ $roomtopic-color: $settings-grey-fg-color; $eventtile-meta-color: $roomtopic-color; $composer-e2e-icon-color: #c9ced6; + // ******************** $roomtile-name-color: rgba(69, 69, 69, 0.8); From b68ee8ac6a8e3c7b7b6260c2bd5d44d4b6fb97e8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 11:43:42 -0700 Subject: [PATCH 043/165] Set a minimum width on the settings tab content This prevents random controls from squishing themselves, at sacrifice of scrollbars and not-responsiveness. --- res/css/views/dialogs/_SettingsDialog.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/views/dialogs/_SettingsDialog.scss b/res/css/views/dialogs/_SettingsDialog.scss index 68206f32aa..4a9708f6d1 100644 --- a/res/css/views/dialogs/_SettingsDialog.scss +++ b/res/css/views/dialogs/_SettingsDialog.scss @@ -30,6 +30,7 @@ limitations under the License. .mx_TabbedView .mx_SettingsTab { box-sizing: border-box; + min-width: 550px; padding-right: 130px; // Put some padding on the bottom to avoid the settings tab from From bcac332d31cda9c644596fd6f1371f1b561f7e07 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 1 Feb 2019 12:46:17 -0600 Subject: [PATCH 044/165] Remove unneeded backdrop on auth pages --- res/css/views/auth/_AuthPage.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/res/css/views/auth/_AuthPage.scss b/res/css/views/auth/_AuthPage.scss index 64b69c750f..8ef48b6265 100644 --- a/res/css/views/auth/_AuthPage.scss +++ b/res/css/views/auth/_AuthPage.scss @@ -26,8 +26,6 @@ limitations under the License. display: flex; margin: 100px auto auto; border-radius: 4px; - // Not currently supported in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1178765 - backdrop-filter: blur(10px); box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.33); background-color: $authpage-modal-bg-color; } From 6dfc9b4f79b191f0dc2fb04a634d1cd92ad8c80d Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 1 Feb 2019 12:48:26 -0600 Subject: [PATCH 045/165] Change footer to padding --- res/css/views/auth/_AuthFooter.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/auth/_AuthFooter.scss b/res/css/views/auth/_AuthFooter.scss index 741be49a69..f35e39cd4d 100644 --- a/res/css/views/auth/_AuthFooter.scss +++ b/res/css/views/auth/_AuthFooter.scss @@ -19,7 +19,7 @@ limitations under the License. width: 100%; font-size: 14px; opacity: 0.72; - margin: 20px 0; + padding: 20px 0; } .mx_AuthFooter a:link, From 0b14855c4f4e335516fd9d9cc5eecf003870edda Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 1 Feb 2019 12:50:22 -0600 Subject: [PATCH 046/165] Add footer gradient --- res/css/views/auth/_AuthFooter.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/views/auth/_AuthFooter.scss b/res/css/views/auth/_AuthFooter.scss index f35e39cd4d..ab169a6898 100644 --- a/res/css/views/auth/_AuthFooter.scss +++ b/res/css/views/auth/_AuthFooter.scss @@ -20,6 +20,7 @@ limitations under the License. font-size: 14px; opacity: 0.72; padding: 20px 0; + background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.8)); } .mx_AuthFooter a:link, From 3bfd603dabefc7391258b95ba294c3c168085a0f Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 1 Feb 2019 15:24:07 -0600 Subject: [PATCH 047/165] Remove guest warning bar --- res/css/structures/_HomePage.scss | 17 ----------- src/components/structures/HomePage.js | 43 --------------------------- src/i18n/strings/en_EN.json | 2 -- 3 files changed, 62 deletions(-) diff --git a/res/css/structures/_HomePage.scss b/res/css/structures/_HomePage.scss index dc3158b39d..5f1e035e99 100644 --- a/res/css/structures/_HomePage.scss +++ b/res/css/structures/_HomePage.scss @@ -29,20 +29,3 @@ limitations under the License. height: 100%; border: 0px; } - -.mx_HomePage_body { -// margin-left: 63px; -} - -.mx_HomePage_guest_warning { - display: flex; - background-color: $secondary-accent-color; - border: 1px solid $accent-color; - margin: 20px; - padding: 20px 40px; - border-radius: 5px; -} - -.mx_HomePage_guest_warning img { - padding-right: 10px; -} diff --git a/src/components/structures/HomePage.js b/src/components/structures/HomePage.js index 948a07ee59..4deccb17dd 100644 --- a/src/components/structures/HomePage.js +++ b/src/components/structures/HomePage.js @@ -24,7 +24,6 @@ import { _t } from '../../languageHandler'; import sanitizeHtml from 'sanitize-html'; import sdk from '../../index'; import { MatrixClient } from 'matrix-js-sdk'; -import dis from '../../dispatcher'; class HomePage extends React.Component { static displayName = 'HomePage'; @@ -80,51 +79,10 @@ class HomePage extends React.Component { this._unmounted = true; } - onLoginClick(ev) { - ev.preventDefault(); - ev.stopPropagation(); - dis.dispatch({ action: 'start_login' }); - } - - onRegisterClick(ev) { - ev.preventDefault(); - ev.stopPropagation(); - dis.dispatch({ action: 'start_registration' }); - } - render() { - let guestWarning = ""; - if (this.context.matrixClient.isGuest()) { - guestWarning = ( -
    - -
    -
    - { _t("You are currently using Riot anonymously as a guest.") } -
    -
    - { _t( - 'If you would like to create a Matrix account you can register now.', - {}, - { 'a': (sub) => { sub } }, - ) } -
    -
    - { _t( - 'If you already have a Matrix account you can log in instead.', - {}, - { 'a': (sub) => { sub } }, - ) } -
    -
    -
    - ); - } - if (this.state.iframeSrc) { return (
    - { guestWarning }