From 77515f0b582d65f7bef9e64fbad49c05bea65a22 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 8 Apr 2019 14:40:08 +0100 Subject: [PATCH 01/31] Remove duplicate space in credits --- src/components/views/settings/tabs/user/HelpUserSettingsTab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/settings/tabs/user/HelpUserSettingsTab.js b/src/components/views/settings/tabs/user/HelpUserSettingsTab.js index e45b0d0389..996618bcca 100644 --- a/src/components/views/settings/tabs/user/HelpUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/HelpUserSettingsTab.js @@ -136,7 +136,7 @@ export default class HelpUserSettingsTab extends React.Component {
  • The default cover photo is (C)  - Jesús Roncero  + Jesús Roncero{' '} used under the terms of  CC-BY-SA 4.0. No warranties are given. From c49afe4d720598377d35117380651bc3423796a4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Apr 2019 16:23:00 -0600 Subject: [PATCH 02/31] Use dedicated permalink creators in search results with multiple rooms Fixes https://github.com/vector-im/riot-web/issues/9376 This also would have happened in "All Rooms" searches. --- src/components/structures/RoomView.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 4f20b354d3..a60f19b35e 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1161,6 +1161,10 @@ module.exports = React.createClass({ } }; + // We cache the permalink creators to avoid creating a ton of them in popular searches + const permalinkCreators = {}; // [roomId] => creator + permalinkCreators[this.state.room.roomId] = this.state.permalinkCreator; + let lastRoomId; for (let i = this.state.searchResults.results.length - 1; i >= 0; i--) { @@ -1168,6 +1172,7 @@ module.exports = React.createClass({ const mxEv = result.context.getEvent(); const roomId = mxEv.getRoomId(); + const room = cli.getRoom(roomId); if (!EventTile.haveTileForEvent(mxEv)) { // XXX: can this ever happen? It will make the result count @@ -1177,7 +1182,6 @@ module.exports = React.createClass({ if (this.state.searchScope === 'All') { if (roomId != lastRoomId) { - const room = cli.getRoom(roomId); // XXX: if we've left the room, we might not know about // it. We should tell the js sdk to go and find out about @@ -1194,11 +1198,17 @@ module.exports = React.createClass({ const resultLink = "#/room/"+roomId+"/"+mxEv.getId(); + let permalinkCreator = permalinkCreators[roomId]; + if (!permalinkCreator) { + permalinkCreator = permalinkCreators[roomId] = new RoomPermalinkCreator(room); + permalinkCreator.stop(); // We're not interested in monitoring for updates here. + } + ret.push(); } return ret; From e4a9d4f5c889699525e27d8297601de1625cf301 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 9 Apr 2019 12:01:09 -0600 Subject: [PATCH 03/31] Cache permalink creators out of the component's state --- src/components/structures/RoomView.js | 42 +++++++++++++-------------- src/matrix-to.js | 7 +++++ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index a60f19b35e..3f9d93c9b1 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -272,6 +272,20 @@ module.exports = React.createClass({ return this.state.room ? this.state.room.roomId : this.state.roomId; }, + _getPermalinkCreatorForRoom: function(room) { + if (!this._permalinkCreators) this._permalinkCreators = {}; + if (this._permalinkCreators[room.roomId]) return this._permalinkCreators[room.roomId]; + + return this._permalinkCreators[room.roomId] = new RoomPermalinkCreator(room); + }, + + _stopAllPermalinkCreators: function() { + if (!this._permalinkCreators) return; + for (const roomId of Object.keys(this._permalinkCreators)) { + this._permalinkCreators[roomId].stop(); + } + }, + _onWidgetEchoStoreUpdate: function() { this.setState({ showApps: this._shouldShowApps(this.state.room), @@ -436,9 +450,7 @@ module.exports = React.createClass({ } // stop tracking room changes to format permalinks - if (this.state.permalinkCreator) { - this.state.permalinkCreator.stop(); - } + this._stopAllPermalinkCreators(); if (this.refs.roomView) { // disconnect the D&D event listeners from the room view. This @@ -650,11 +662,9 @@ module.exports = React.createClass({ this._loadMembersIfJoined(room); this._calculateRecommendedVersion(room); this._updateE2EStatus(room); - if (!this.state.permalinkCreator) { - const permalinkCreator = new RoomPermalinkCreator(room); - permalinkCreator.start(); - this.setState({permalinkCreator}); - } + + let creator = this._getPermalinkCreatorForRoom(room); + if (!creator.isStarted()) creator.start(); }, _calculateRecommendedVersion: async function(room) { @@ -1161,10 +1171,6 @@ module.exports = React.createClass({ } }; - // We cache the permalink creators to avoid creating a ton of them in popular searches - const permalinkCreators = {}; // [roomId] => creator - permalinkCreators[this.state.room.roomId] = this.state.permalinkCreator; - let lastRoomId; for (let i = this.state.searchResults.results.length - 1; i >= 0; i--) { @@ -1198,17 +1204,11 @@ module.exports = React.createClass({ const resultLink = "#/room/"+roomId+"/"+mxEv.getId(); - let permalinkCreator = permalinkCreators[roomId]; - if (!permalinkCreator) { - permalinkCreator = permalinkCreators[roomId] = new RoomPermalinkCreator(room); - permalinkCreator.stop(); // We're not interested in monitoring for updates here. - } - ret.push(); } return ret; @@ -1733,7 +1733,7 @@ module.exports = React.createClass({ disabled={this.props.disabled} showApps={this.state.showApps} e2eStatus={this.state.e2eStatus} - permalinkCreator={this.state.permalinkCreator} + permalinkCreator={this._getPermalinkCreatorForRoom(this.state.room)} />; } @@ -1835,7 +1835,7 @@ module.exports = React.createClass({ showUrlPreview = {this.state.showUrlPreview} className="mx_RoomView_messagePanel" membersLoaded={this.state.membersLoaded} - permalinkCreator={this.state.permalinkCreator} + permalinkCreator={this._getPermalinkCreatorForRoom(this.state.room)} resizeNotifier={this.props.resizeNotifier} />); diff --git a/src/matrix-to.js b/src/matrix-to.js index bb7ddfbd94..a198bb422e 100644 --- a/src/matrix-to.js +++ b/src/matrix-to.js @@ -77,6 +77,7 @@ export class RoomPermalinkCreator { this._bannedHostsRegexps = null; this._allowedHostsRegexps = null; this._serverCandidates = null; + this._started = false; this.onMembership = this.onMembership.bind(this); this.onRoomState = this.onRoomState.bind(this); @@ -101,11 +102,17 @@ export class RoomPermalinkCreator { this.load(); this._room.on("RoomMember.membership", this.onMembership); this._room.on("RoomState.events", this.onRoomState); + this._started = true; } stop() { this._room.removeListener("RoomMember.membership", this.onMembership); this._room.removeListener("RoomState.events", this.onRoomState); + this._started = false; + } + + isStarted() { + return this._started; } forEvent(eventId) { From 5fb9276ef303b302f062d062accf0361b387e66b Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 10 Apr 2019 13:20:03 +0200 Subject: [PATCH 04/31] add togglePhase method, where we can show the panel if needed without needing to resort to redispatching the original action --- .../views/right_panel/HeaderButtons.js | 49 ++++++++++--------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/src/components/views/right_panel/HeaderButtons.js b/src/components/views/right_panel/HeaderButtons.js index b7155b922f..fb124e8d3f 100644 --- a/src/components/views/right_panel/HeaderButtons.js +++ b/src/components/views/right_panel/HeaderButtons.js @@ -40,14 +40,36 @@ export default class HeaderButtons extends React.Component { dis.unregister(this.dispatcherRef); } + componentDidUpdate(prevProps) { + if (!prevProps.collapsedRhs && this.props.collapsedRhs) { + this.setState({ + phase: null, + }); + } + } + setPhase(phase, extras) { - // TODO: delay? + if (this.props.collapsedRhs) { + dis.dispatch({ + action: 'show_right_panel', + }); + } dis.dispatch(Object.assign({ action: 'view_right_panel_phase', phase: phase, }, extras)); } + togglePhase(phase) { + if (this.state.phase === phase) { + dis.dispatch({ + action: 'hide_right_panel', + }); + } else { + this.setPhase(phase); + } + } + isPhase(phases) { if (this.props.collapsedRhs) { return false; @@ -61,28 +83,9 @@ export default class HeaderButtons extends React.Component { onAction(payload) { if (payload.action === "view_right_panel_phase") { - // only actions coming from header buttons should collapse the right panel - if (this.state.phase === payload.phase && payload.fromHeader) { - dis.dispatch({ - action: 'hide_right_panel', - }); - this.setState({ - phase: null, - }); - } else { - if (this.props.collapsedRhs && payload.fromHeader) { - dis.dispatch({ - action: 'show_right_panel', - }); - // emit payload again as the RightPanel didn't exist up - // till show_right_panel, just without the fromHeader flag - // as that would hide the right panel again - dis.dispatch(Object.assign({}, payload, {fromHeader: false})); - } - this.setState({ - phase: payload.phase, - }); - } + this.setState({ + phase: payload.phase, + }); } } From 2b4b6feba2d087c2d0b0245e8b774b1ac6649d6d Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 10 Apr 2019 13:21:07 +0200 Subject: [PATCH 05/31] call togglePhase from header buttons --- src/components/views/right_panel/GroupHeaderButtons.js | 4 ++-- src/components/views/right_panel/HeaderButton.js | 6 +----- src/components/views/right_panel/RoomHeaderButtons.js | 6 +++--- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/components/views/right_panel/GroupHeaderButtons.js b/src/components/views/right_panel/GroupHeaderButtons.js index 13379d49e3..494ccb88fa 100644 --- a/src/components/views/right_panel/GroupHeaderButtons.js +++ b/src/components/views/right_panel/GroupHeaderButtons.js @@ -68,13 +68,13 @@ export default class GroupHeaderButtons extends HeaderButtons { this.togglePhase(RightPanel.Phase.GroupMemberList)} analytics={['Right Panel', 'Group Member List Button', 'click']} />, this.togglePhase(RightPanel.Phase.GroupRoomList)} analytics={['Right Panel', 'Group Room List Button', 'click']} />, ]; diff --git a/src/components/views/right_panel/HeaderButton.js b/src/components/views/right_panel/HeaderButton.js index cc78373117..decce417d8 100644 --- a/src/components/views/right_panel/HeaderButton.js +++ b/src/components/views/right_panel/HeaderButton.js @@ -32,11 +32,7 @@ export default class HeaderButton extends React.Component { onClick(ev) { Analytics.trackEvent(...this.props.analytics); - dis.dispatch({ - action: 'view_right_panel_phase', - phase: this.props.clickPhase, - fromHeader: true, - }); + this.props.onClick(); } render() { diff --git a/src/components/views/right_panel/RoomHeaderButtons.js b/src/components/views/right_panel/RoomHeaderButtons.js index 51e436bfc2..5c64cb799b 100644 --- a/src/components/views/right_panel/RoomHeaderButtons.js +++ b/src/components/views/right_panel/RoomHeaderButtons.js @@ -62,19 +62,19 @@ export default class RoomHeaderButtons extends HeaderButtons { this.togglePhase(RightPanel.Phase.RoomMemberList)} analytics={['Right Panel', 'Member List Button', 'click']} />, this.togglePhase(RightPanel.Phase.FilePanel)} analytics={['Right Panel', 'File List Button', 'click']} />, this.togglePhase(RightPanel.Phase.NotificationPanel)} analytics={['Right Panel', 'Notification List Button', 'click']} />, ]; From fe63b6b5bd3645cf5ef6363463f2e996d0b31b96 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 10 Apr 2019 13:21:42 +0200 Subject: [PATCH 06/31] setPhase can now open the panel, don't open it if closed on view_room --- src/components/views/right_panel/RoomHeaderButtons.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/right_panel/RoomHeaderButtons.js b/src/components/views/right_panel/RoomHeaderButtons.js index 5c64cb799b..aff5274cec 100644 --- a/src/components/views/right_panel/RoomHeaderButtons.js +++ b/src/components/views/right_panel/RoomHeaderButtons.js @@ -40,7 +40,7 @@ export default class RoomHeaderButtons extends HeaderButtons { } else { this.setPhase(RightPanel.Phase.RoomMemberList); } - } else if (payload.action === "view_room") { + } else if (payload.action === "view_room" && !this.props.collapsedRhs) { this.setPhase(RightPanel.Phase.RoomMemberList); } else if (payload.action === "view_3pid_invite") { if (payload.event) { From 6ca1a879c966709bf272a7f47865d8ac6f18261c Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 10 Apr 2019 13:22:31 +0200 Subject: [PATCH 07/31] remove hacks, now that emitting show_right_panel is centralized --- src/components/structures/MatrixChat.js | 14 -------------- .../views/right_panel/GroupHeaderButtons.js | 3 --- .../views/right_panel/RoomHeaderButtons.js | 3 --- 3 files changed, 20 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 387f2ca69d..fe0deb0d49 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -565,20 +565,6 @@ export default React.createClass({ }, }); break; - case 'view_user': - // FIXME: ugly hack to expand the RightPanel and then re-dispatch. - if (this.state.collapsedRhs) { - setTimeout(()=>{ - dis.dispatch({ - action: 'show_right_panel', - }); - dis.dispatch({ - action: 'view_user', - member: payload.member, - }); - }, 0); - } - break; case 'view_room': // Takes either a room ID or room alias: if switching to a room the client is already // known to be in (eg. user clicks on a room in the recents panel), supply the ID diff --git a/src/components/views/right_panel/GroupHeaderButtons.js b/src/components/views/right_panel/GroupHeaderButtons.js index 494ccb88fa..9bc69de1ab 100644 --- a/src/components/views/right_panel/GroupHeaderButtons.js +++ b/src/components/views/right_panel/GroupHeaderButtons.js @@ -33,9 +33,6 @@ export default class GroupHeaderButtons extends HeaderButtons { super.onAction(payload); if (payload.action === "view_user") { - dis.dispatch({ - action: 'show_right_panel', - }); if (payload.member) { this.setPhase(RightPanel.Phase.RoomMemberInfo, {member: payload.member}); } else { diff --git a/src/components/views/right_panel/RoomHeaderButtons.js b/src/components/views/right_panel/RoomHeaderButtons.js index aff5274cec..cbdc2cd81b 100644 --- a/src/components/views/right_panel/RoomHeaderButtons.js +++ b/src/components/views/right_panel/RoomHeaderButtons.js @@ -32,9 +32,6 @@ export default class RoomHeaderButtons extends HeaderButtons { onAction(payload) { super.onAction(payload); if (payload.action === "view_user") { - dis.dispatch({ - action: 'show_right_panel', - }); if (payload.member) { this.setPhase(RightPanel.Phase.RoomMemberInfo, {member: payload.member}); } else { From 49e96dc4047766c759f4abc87a80c5a7c693a80b Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 10 Apr 2019 13:31:27 +0200 Subject: [PATCH 08/31] remove unused dispatcher import --- src/components/views/right_panel/GroupHeaderButtons.js | 1 - src/components/views/right_panel/HeaderButton.js | 1 - src/components/views/right_panel/RoomHeaderButtons.js | 1 - 3 files changed, 3 deletions(-) diff --git a/src/components/views/right_panel/GroupHeaderButtons.js b/src/components/views/right_panel/GroupHeaderButtons.js index 9bc69de1ab..e01474f523 100644 --- a/src/components/views/right_panel/GroupHeaderButtons.js +++ b/src/components/views/right_panel/GroupHeaderButtons.js @@ -19,7 +19,6 @@ limitations under the License. import React from 'react'; import { _t } from '../../../languageHandler'; -import dis from '../../../dispatcher'; import HeaderButton from './HeaderButton'; import HeaderButtons from './HeaderButtons'; import RightPanel from '../../structures/RightPanel'; diff --git a/src/components/views/right_panel/HeaderButton.js b/src/components/views/right_panel/HeaderButton.js index decce417d8..ffd3d87616 100644 --- a/src/components/views/right_panel/HeaderButton.js +++ b/src/components/views/right_panel/HeaderButton.js @@ -20,7 +20,6 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; -import dis from '../../../dispatcher'; import Analytics from '../../../Analytics'; import AccessibleButton from '../elements/AccessibleButton'; diff --git a/src/components/views/right_panel/RoomHeaderButtons.js b/src/components/views/right_panel/RoomHeaderButtons.js index cbdc2cd81b..f3bc0967a4 100644 --- a/src/components/views/right_panel/RoomHeaderButtons.js +++ b/src/components/views/right_panel/RoomHeaderButtons.js @@ -19,7 +19,6 @@ limitations under the License. import React from 'react'; import { _t } from '../../../languageHandler'; -import dis from '../../../dispatcher'; import HeaderButton from './HeaderButton'; import HeaderButtons from './HeaderButtons'; import RightPanel from '../../structures/RightPanel'; From 15e8ce7a7f65a7f8e95b501e16b59dbe4b8f6d8b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 10 Apr 2019 15:00:02 -0600 Subject: [PATCH 09/31] Add a link in room settings to get at the tombstoned room if it exists Fixes https://github.com/vector-im/riot-web/issues/8542 --- res/css/views/settings/tabs/_SettingsTab.scss | 4 ++ .../views/dialogs/RoomSettingsDialog.js | 2 +- .../tabs/room/AdvancedRoomSettingsTab.js | 47 +++++++++++++++++++ src/i18n/strings/en_EN.json | 1 + 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/res/css/views/settings/tabs/_SettingsTab.scss b/res/css/views/settings/tabs/_SettingsTab.scss index 88735f99b2..def28bfbd2 100644 --- a/res/css/views/settings/tabs/_SettingsTab.scss +++ b/res/css/views/settings/tabs/_SettingsTab.scss @@ -72,3 +72,7 @@ limitations under the License. // give them more visual distinction between the sections. margin-top: 30px; } + +.mx_SettingsTab a { + color: $accent-color-alt; +} \ No newline at end of file diff --git a/src/components/views/dialogs/RoomSettingsDialog.js b/src/components/views/dialogs/RoomSettingsDialog.js index 22b7857264..05ed262078 100644 --- a/src/components/views/dialogs/RoomSettingsDialog.js +++ b/src/components/views/dialogs/RoomSettingsDialog.js @@ -52,7 +52,7 @@ export default class RoomSettingsDialog extends React.Component { tabs.push(new Tab( _td("Advanced"), "mx_RoomSettingsDialog_warningIcon", - , + , )); return tabs; diff --git a/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js b/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js index 20c270fe29..183631ae7a 100644 --- a/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js +++ b/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js @@ -21,10 +21,12 @@ import MatrixClientPeg from "../../../../../MatrixClientPeg"; import sdk from "../../../../.."; import AccessibleButton from "../../../elements/AccessibleButton"; import Modal from "../../../../../Modal"; +import dis from "../../../../../dispatcher"; export default class AdvancedRoomSettingsTab extends React.Component { static propTypes = { roomId: PropTypes.string.isRequired, + closeSettingsFn: PropTypes.func.isRequired, }; constructor() { @@ -41,9 +43,21 @@ export default class AdvancedRoomSettingsTab extends React.Component { const room = MatrixClientPeg.get().getRoom(this.props.roomId); room.getRecommendedVersion().then((v) => { const tombstone = room.currentState.getStateEvents("m.room.tombstone", ""); + + let additionalStateChanges = {}; + const createEvent = room.currentState.getStateEvents("m.room.create", ""); + let predecessor = createEvent ? createEvent.getContent().predecessor : null; + if (predecessor && predecessor.room_id) { + additionalStateChanges['oldRoomId'] = predecessor.room_id; + additionalStateChanges['oldEventId'] = predecessor.event_id; + additionalStateChanges['hasPreviousRoom'] = true; + } + + this.setState({ upgraded: tombstone && tombstone.getContent().replacement_room, upgradeRecommendation: v, + ...additionalStateChanges, }); }); } @@ -59,6 +73,18 @@ export default class AdvancedRoomSettingsTab extends React.Component { Modal.createDialog(DevtoolsDialog, {roomId: this.props.roomId}); }; + _onOldRoomClicked = (e) => { + e.preventDefault(); + e.stopPropagation(); + + dis.dispatch({ + action: 'view_room', + room_id: this.state.oldRoomId, + event_id: this.state.oldEventId, + }); + this.props.closeSettingsFn(); + }; + render() { const client = MatrixClientPeg.get(); const room = client.getRoom(this.props.roomId); @@ -91,6 +117,26 @@ export default class AdvancedRoomSettingsTab extends React.Component { ); } + let oldRoomLink; + if (this.state.hasPreviousRoom) { + oldRoomLink = ( +
    + {_t( + "This is the upgraded version of another room. Click here to visit the old room.", + {}, { + 'a': (sub) => { + return ( + + {sub} + + ); + }, + }, + )} +
    + ); + } + return (
    {_t("Advanced")}
    @@ -108,6 +154,7 @@ export default class AdvancedRoomSettingsTab extends React.Component { {_t("Room version:")}  {room.getVersion()}
    + {oldRoomLink} {roomUpgradeButton}
    diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8e3f0d9f6e..c20ea08a91 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -599,6 +599,7 @@ "Voice & Video": "Voice & Video", "This room is not accessible by remote Matrix servers": "This room is not accessible by remote Matrix servers", "Upgrade this room to the recommended room version": "Upgrade this room to the recommended room version", + "This is the upgraded version of another room. Click here to visit the old room.": "This is the upgraded version of another room. Click here to visit the old room.", "Room information": "Room information", "Internal room ID:": "Internal room ID:", "Room version": "Room version", From 64423e1f7d8dbd905aace061f185c0b140d0b02e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 10 Apr 2019 15:34:06 -0600 Subject: [PATCH 10/31] let -> const --- .../views/settings/tabs/room/AdvancedRoomSettingsTab.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js b/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js index 183631ae7a..b09274adfd 100644 --- a/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js +++ b/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js @@ -44,9 +44,9 @@ export default class AdvancedRoomSettingsTab extends React.Component { room.getRecommendedVersion().then((v) => { const tombstone = room.currentState.getStateEvents("m.room.tombstone", ""); - let additionalStateChanges = {}; + const additionalStateChanges = {}; const createEvent = room.currentState.getStateEvents("m.room.create", ""); - let predecessor = createEvent ? createEvent.getContent().predecessor : null; + const predecessor = createEvent ? createEvent.getContent().predecessor : null; if (predecessor && predecessor.room_id) { additionalStateChanges['oldRoomId'] = predecessor.room_id; additionalStateChanges['oldEventId'] = predecessor.event_id; From b3946c7766ba1e263ce50c8e7d9e33a1d4828a1e Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 11 Apr 2019 10:55:53 +0100 Subject: [PATCH 11/31] Add period to the end of upgrade notice --- src/SlashCommands.js | 2 +- src/i18n/strings/en_EN.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index 8db9c4400d..f72ba1e005 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -155,7 +155,7 @@ export const CommandMap = {

    {_t( "Please confirm that you'd like to go forward with upgrading this room " + - "from to ", + "from to .", {}, { oldVersion: () => {room ? room.getVersion() : "1"}, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8e3f0d9f6e..52680ce91d 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -142,7 +142,7 @@ "Room upgrades are usually recommended when a room version is considered unstable. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Room upgrades are usually recommended when a room version is considered unstable. Unstable room versions might have bugs, missing features, or security vulnerabilities.", "Room upgrades usually only affect server-side processing of the room. If you're having problems with your Riot client, please file an issue with .": "Room upgrades usually only affect server-side processing of the room. If you're having problems with your Riot client, please file an issue with .", "Warning: Upgrading a room will not automatically migrate room members to the new version of the room. We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "Warning: Upgrading a room will not automatically migrate room members to the new version of the room. We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.", - "Please confirm that you'd like to go forward with upgrading this room from to ": "Please confirm that you'd like to go forward with upgrading this room from to ", + "Please confirm that you'd like to go forward with upgrading this room from to .": "Please confirm that you'd like to go forward with upgrading this room from to .", "Upgrade": "Upgrade", "Changes your display nickname": "Changes your display nickname", "Changes your display nickname in the current room only": "Changes your display nickname in the current room only", From 02792132e1a8abc73ad5a319c20fff8e9a00f132 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 11 Apr 2019 13:22:47 +0200 Subject: [PATCH 12/31] dont create functions in render --- .../views/right_panel/GroupHeaderButtons.js | 14 +++++++++++-- .../views/right_panel/RoomHeaderButtons.js | 21 ++++++++++++++++--- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/components/views/right_panel/GroupHeaderButtons.js b/src/components/views/right_panel/GroupHeaderButtons.js index e01474f523..1b8e6a4a46 100644 --- a/src/components/views/right_panel/GroupHeaderButtons.js +++ b/src/components/views/right_panel/GroupHeaderButtons.js @@ -26,6 +26,8 @@ import RightPanel from '../../structures/RightPanel'; export default class GroupHeaderButtons extends HeaderButtons { constructor(props) { super(props, RightPanel.Phase.GroupMemberList); + this._onMembersClicked = this._onMembersClicked.bind(this); + this._onRoomsClicked = this._onRoomsClicked.bind(this); } onAction(payload) { @@ -50,6 +52,14 @@ export default class GroupHeaderButtons extends HeaderButtons { } } + _onMembersClicked() { + this.togglePhase(RightPanel.Phase.GroupMemberList); + } + + _onRoomsClicked() { + this.togglePhase(RightPanel.Phase.GroupRoomList); + } + renderButtons() { const groupPhases = [ RightPanel.Phase.GroupMemberInfo, @@ -64,13 +74,13 @@ export default class GroupHeaderButtons extends HeaderButtons { this.togglePhase(RightPanel.Phase.GroupMemberList)} + onClick={this._onMembersClicked} analytics={['Right Panel', 'Group Member List Button', 'click']} />, this.togglePhase(RightPanel.Phase.GroupRoomList)} + onClick={this._onRoomsClicked} analytics={['Right Panel', 'Group Room List Button', 'click']} />, ]; diff --git a/src/components/views/right_panel/RoomHeaderButtons.js b/src/components/views/right_panel/RoomHeaderButtons.js index f3bc0967a4..65d74c7a0b 100644 --- a/src/components/views/right_panel/RoomHeaderButtons.js +++ b/src/components/views/right_panel/RoomHeaderButtons.js @@ -26,6 +26,9 @@ import RightPanel from '../../structures/RightPanel'; export default class RoomHeaderButtons extends HeaderButtons { constructor(props) { super(props, RightPanel.Phase.RoomMemberList); + this._onMembersClicked = this._onMembersClicked.bind(this); + this._onFilesClicked = this._onFilesClicked.bind(this); + this._onNotificationsClicked = this._onNotificationsClicked.bind(this); } onAction(payload) { @@ -47,6 +50,18 @@ export default class RoomHeaderButtons extends HeaderButtons { } } + _onMembersClicked() { + this.togglePhase(RightPanel.Phase.RoomMemberList); + } + + _onFilesClicked() { + this.togglePhase(RightPanel.Phase.FilePanel); + } + + _onNotificationsClicked() { + this.togglePhase(RightPanel.Phase.NotificationPanel); + } + renderButtons() { const membersPhases = [ RightPanel.Phase.RoomMemberList, @@ -58,19 +73,19 @@ export default class RoomHeaderButtons extends HeaderButtons { this.togglePhase(RightPanel.Phase.RoomMemberList)} + onClick={this._onMembersClicked} analytics={['Right Panel', 'Member List Button', 'click']} />, this.togglePhase(RightPanel.Phase.FilePanel)} + onClick={this._onFilesClicked} analytics={['Right Panel', 'File List Button', 'click']} />, this.togglePhase(RightPanel.Phase.NotificationPanel)} + onClick={this._onNotificationsClicked} analytics={['Right Panel', 'Notification List Button', 'click']} />, ]; From 483b7fc14d0eccced2cb21c3b7769adf96964501 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 11 Apr 2019 13:31:21 +0200 Subject: [PATCH 13/31] take buttons into account that are active over multiple phases when toggling --- .../views/right_panel/GroupHeaderButtons.js | 26 +++++++++---------- .../views/right_panel/HeaderButtons.js | 4 +-- .../views/right_panel/RoomHeaderButtons.js | 16 ++++++------ 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/components/views/right_panel/GroupHeaderButtons.js b/src/components/views/right_panel/GroupHeaderButtons.js index 1b8e6a4a46..ec14331ad2 100644 --- a/src/components/views/right_panel/GroupHeaderButtons.js +++ b/src/components/views/right_panel/GroupHeaderButtons.js @@ -23,6 +23,15 @@ import HeaderButton from './HeaderButton'; import HeaderButtons from './HeaderButtons'; import RightPanel from '../../structures/RightPanel'; +const GROUP_PHASES = [ + RightPanel.Phase.GroupMemberInfo, + RightPanel.Phase.GroupMemberList, +]; +const ROOM_PHASES = [ + RightPanel.Phase.GroupRoomList, + RightPanel.Phase.GroupRoomInfo, +]; + export default class GroupHeaderButtons extends HeaderButtons { constructor(props) { super(props, RightPanel.Phase.GroupMemberList); @@ -53,33 +62,24 @@ export default class GroupHeaderButtons extends HeaderButtons { } _onMembersClicked() { - this.togglePhase(RightPanel.Phase.GroupMemberList); + this.togglePhase(RightPanel.Phase.GroupMemberList, GROUP_PHASES); } _onRoomsClicked() { - this.togglePhase(RightPanel.Phase.GroupRoomList); + this.togglePhase(RightPanel.Phase.GroupRoomList, ROOM_PHASES); } renderButtons() { - const groupPhases = [ - RightPanel.Phase.GroupMemberInfo, - RightPanel.Phase.GroupMemberList, - ]; - const roomPhases = [ - RightPanel.Phase.GroupRoomList, - RightPanel.Phase.GroupRoomInfo, - ]; - return [ , , diff --git a/src/components/views/right_panel/HeaderButtons.js b/src/components/views/right_panel/HeaderButtons.js index fb124e8d3f..2fa9935ab8 100644 --- a/src/components/views/right_panel/HeaderButtons.js +++ b/src/components/views/right_panel/HeaderButtons.js @@ -60,8 +60,8 @@ export default class HeaderButtons extends React.Component { }, extras)); } - togglePhase(phase) { - if (this.state.phase === phase) { + togglePhase(phase, validPhases = [phase]) { + if (validPhases.includes(this.state.phase)) { dis.dispatch({ action: 'hide_right_panel', }); diff --git a/src/components/views/right_panel/RoomHeaderButtons.js b/src/components/views/right_panel/RoomHeaderButtons.js index 65d74c7a0b..950fa30e38 100644 --- a/src/components/views/right_panel/RoomHeaderButtons.js +++ b/src/components/views/right_panel/RoomHeaderButtons.js @@ -23,6 +23,12 @@ import HeaderButton from './HeaderButton'; import HeaderButtons from './HeaderButtons'; import RightPanel from '../../structures/RightPanel'; +const MEMBER_PHASES = [ + RightPanel.Phase.RoomMemberList, + RightPanel.Phase.RoomMemberInfo, + RightPanel.Phase.Room3pidMemberInfo, +]; + export default class RoomHeaderButtons extends HeaderButtons { constructor(props) { super(props, RightPanel.Phase.RoomMemberList); @@ -51,7 +57,7 @@ export default class RoomHeaderButtons extends HeaderButtons { } _onMembersClicked() { - this.togglePhase(RightPanel.Phase.RoomMemberList); + this.togglePhase(RightPanel.Phase.RoomMemberList, MEMBER_PHASES); } _onFilesClicked() { @@ -63,16 +69,10 @@ export default class RoomHeaderButtons extends HeaderButtons { } renderButtons() { - const membersPhases = [ - RightPanel.Phase.RoomMemberList, - RightPanel.Phase.RoomMemberInfo, - RightPanel.Phase.Room3pidMemberInfo, - ]; - return [ , From 6e8e62e6192ced9df854b25e774d3c0cfde8ae6a Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 11 Apr 2019 16:16:29 +0200 Subject: [PATCH 14/31] use medium agent for e2e tests --- .buildkite/pipeline.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 7cb859234e..60964de469 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -9,6 +9,10 @@ steps: image: "node:10" - label: ":chains: End-to-End Tests" + agents: + # We use a medium sized instance instead of the normal small ones because + # e2e tests otherwise take +-8min + queue: "medium" command: # TODO: Remove hacky chmod for BuildKite - "echo '--- Setup'" From fee30d4482d1fc70dade9ac539ea5f964ad62d41 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 11 Apr 2019 18:32:38 +0200 Subject: [PATCH 15/31] adjust prop in HeaderButton --- src/components/views/right_panel/HeaderButton.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/views/right_panel/HeaderButton.js b/src/components/views/right_panel/HeaderButton.js index ffd3d87616..2c1e15898e 100644 --- a/src/components/views/right_panel/HeaderButton.js +++ b/src/components/views/right_panel/HeaderButton.js @@ -54,9 +54,8 @@ export default class HeaderButton extends React.Component { HeaderButton.propTypes = { // Whether this button is highlighted isHighlighted: PropTypes.bool.isRequired, - // The phase to swap to when the button is clicked - clickPhase: PropTypes.string.isRequired, - + // click handler + onClick: PropTypes.func.isRequired, // The badge to display above the icon badge: PropTypes.node, // The parameters to track the click event From ec01f6ffb121b0cb88c55ac9f6390f6c28cebdba Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 11 Apr 2019 10:40:25 -0600 Subject: [PATCH 16/31] Change wording for old room link --- .../tabs/room/AdvancedRoomSettingsTab.js | 20 ++++++------------- src/i18n/strings/en_EN.json | 3 ++- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js b/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js index b09274adfd..101cd036e5 100644 --- a/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js +++ b/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.js @@ -119,21 +119,13 @@ export default class AdvancedRoomSettingsTab extends React.Component { let oldRoomLink; if (this.state.hasPreviousRoom) { + let name = _t("this room"); + const room = MatrixClientPeg.get().getRoom(this.props.roomId); + if (room && room.name) name = room.name; oldRoomLink = ( -

    - {_t( - "This is the upgraded version of another room. Click here to visit the old room.", - {}, { - 'a': (sub) => { - return ( - - {sub} - - ); - }, - }, - )} -
    + + {_t("View older messages in %(roomName)s.", {roomName: name})} + ); } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index c20ea08a91..6b9bc413a2 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -599,7 +599,8 @@ "Voice & Video": "Voice & Video", "This room is not accessible by remote Matrix servers": "This room is not accessible by remote Matrix servers", "Upgrade this room to the recommended room version": "Upgrade this room to the recommended room version", - "This is the upgraded version of another room. Click here to visit the old room.": "This is the upgraded version of another room. Click here to visit the old room.", + "this room": "this room", + "View older messages in %(roomName)s": "View older messages in %(roomName)s", "Room information": "Room information", "Internal room ID:": "Internal room ID:", "Room version": "Room version", From ccf292f05368f63dc4f0f5fd01135224d38f5b97 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 11 Apr 2019 10:59:00 -0600 Subject: [PATCH 17/31] Load permalink creators to get proper state of the room --- src/components/structures/RoomView.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 3f9d93c9b1..1bcbec4845 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -276,7 +276,9 @@ module.exports = React.createClass({ if (!this._permalinkCreators) this._permalinkCreators = {}; if (this._permalinkCreators[room.roomId]) return this._permalinkCreators[room.roomId]; - return this._permalinkCreators[room.roomId] = new RoomPermalinkCreator(room); + this._permalinkCreators[room.roomId] = new RoomPermalinkCreator(room); + this._permalinkCreators[room.roomId].load(); + return this._permalinkCreators[room.roomId]; }, _stopAllPermalinkCreators: function() { From 934ca6908fb0bd1c1fff5ea0507583628e229b96 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 11 Apr 2019 11:07:31 -0600 Subject: [PATCH 18/31] Remove breadcrumb scroll tolerances and use sensible defaults Fixes https://github.com/vector-im/riot-web/issues/9394 Fixes https://github.com/vector-im/riot-web/issues/9400 Numbers chosen based on user feedback. The setting has also been removed because it isn't really needed anymore. --- .../structures/IndicatorScrollbar.js | 30 +++++++------------ src/components/views/rooms/RoomBreadcrumbs.js | 10 ++----- src/settings/Settings.js | 7 ----- 3 files changed, 13 insertions(+), 34 deletions(-) diff --git a/src/components/structures/IndicatorScrollbar.js b/src/components/structures/IndicatorScrollbar.js index 2470f9fa11..a615717104 100644 --- a/src/components/structures/IndicatorScrollbar.js +++ b/src/components/structures/IndicatorScrollbar.js @@ -29,13 +29,6 @@ export default class IndicatorScrollbar extends React.Component { // scroll horizontally rather than vertically. This should only be used on components // with no vertical scroll opportunity. verticalScrollsHorizontally: PropTypes.bool, - - // An object containing 2 numbers: xyThreshold and yReduction. xyThreshold is the amount - // of horizontal movement required in order to ignore any vertical changes in scroll, and - // only applies when verticalScrollsHorizontally is true. yReduction is the factor to - // multiply the vertical delta by when verticalScrollsHorizontally is true. The default - // behaviour is to have an xyThreshold of infinity and a yReduction of 0.8 - scrollTolerances: PropTypes.object, }; constructor(props) { @@ -127,20 +120,19 @@ export default class IndicatorScrollbar extends React.Component { onMouseWheel = (e) => { if (this.props.verticalScrollsHorizontally && this._scrollElement) { - const xyThreshold = this.props.scrollTolerances - ? this.props.scrollTolerances.xyThreshold - : Number.MAX_SAFE_INTEGER; + // xyThreshold is the amount of horizontal motion required for the component to + // ignore the vertical delta in a scroll. Used to stop trackpads from acting in + // strange ways. Should be positive. + const xyThreshold = 0; - const yReduction = this.props.scrollTolerances - ? this.props.scrollTolerances.yReduction - : 0.8; + // yRetention is the factor multiplied by the vertical delta to try and reduce + // the harshness of the scroll behaviour. Should be a value between 0 and 1. + const yRetention = 1.0; - // Don't apply vertical motion to horizontal scrolls. This is meant to eliminate - // trackpads causing excessive scroll motion. - if (e.deltaX >= xyThreshold) return; - - // noinspection JSSuspiciousNameCombination - this._scrollElement.scrollLeft += e.deltaY * yReduction; + if (Math.abs(e.deltaX) < xyThreshold) { + // noinspection JSSuspiciousNameCombination + this._scrollElement.scrollLeft += e.deltaY * yRetention; + } } }; diff --git a/src/components/views/rooms/RoomBreadcrumbs.js b/src/components/views/rooms/RoomBreadcrumbs.js index 7c5947e049..fff1fa7f3c 100644 --- a/src/components/views/rooms/RoomBreadcrumbs.js +++ b/src/components/views/rooms/RoomBreadcrumbs.js @@ -33,12 +33,7 @@ const MAX_ROOMS = 20; export default class RoomBreadcrumbs extends React.Component { constructor(props) { super(props); - - const tolerances = SettingsStore.getValue("breadcrumb_scroll_tolerances"); - this.state = {rooms: [], scrollTolerances: tolerances}; - - // Record this for debugging purposes - console.log("Breadcrumbs scroll tolerances:", tolerances); + this.state = {rooms: []}; this.onAction = this.onAction.bind(this); this._dispatcherRef = null; @@ -343,8 +338,7 @@ export default class RoomBreadcrumbs extends React.Component { }); return ( + trackHorizontalOverflow={true} verticalScrollsHorizontally={true}> { avatars } ); diff --git a/src/settings/Settings.js b/src/settings/Settings.js index dcd6f91aef..35baa718b9 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -262,13 +262,6 @@ export const SETTINGS = { supportedLevels: ['account'], default: [], }, - "breadcrumb_scroll_tolerances": { - supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS, - default: { - xyThreshold: 10, - yReduction: 0.8, - }, - }, "analyticsOptIn": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, displayName: _td('Send analytics data'), From cecd2cbd71d87cffc3bd9925dc40d551414862f5 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 11 Apr 2019 18:41:51 +0100 Subject: [PATCH 19/31] Focus the composer view on file upload --- src/ContentMessages.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ContentMessages.js b/src/ContentMessages.js index bb0852d3d6..42b7971b87 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -450,6 +450,9 @@ export default class ContentMessages { }, }; + // Focus the composer view + dis.dispatch({action: 'focus_composer'}) + // if we have a mime type for the file, add it to the message metadata if (file.type) { content.info.mimetype = file.type; From aadc1a8d7591e029a0b818e47943e480e2a2b6fc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 11 Apr 2019 15:52:37 -0600 Subject: [PATCH 20/31] Add a generic error page element for startup errors Used by Riot to communicate configuration problems. --- res/css/_components.scss | 1 + res/css/structures/_GenericErrorPage.scss | 19 ++++++++++ src/components/structures/GenericErrorPage.js | 38 +++++++++++++++++++ src/i18n/strings/en_EN.json | 2 + 4 files changed, 60 insertions(+) create mode 100644 res/css/structures/_GenericErrorPage.scss create mode 100644 src/components/structures/GenericErrorPage.js diff --git a/res/css/_components.scss b/res/css/_components.scss index 25022acd2e..1f896d270d 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -6,6 +6,7 @@ @import "./structures/_CreateRoom.scss"; @import "./structures/_CustomRoomTagPanel.scss"; @import "./structures/_FilePanel.scss"; +@import "./structures/_GenericErrorPage.scss"; @import "./structures/_GroupView.scss"; @import "./structures/_HeaderButtons.scss"; @import "./structures/_HomePage.scss"; diff --git a/res/css/structures/_GenericErrorPage.scss b/res/css/structures/_GenericErrorPage.scss new file mode 100644 index 0000000000..9c973af411 --- /dev/null +++ b/res/css/structures/_GenericErrorPage.scss @@ -0,0 +1,19 @@ +.mx_GenericErrorPage { + width: 100%; + height: 100%; + background-color: #fff; +} + +.mx_GenericErrorPage_box { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + width: 500px; + height: 200px; + border: 1px solid #f22; + padding: 10px; + background-color: #fcc; +} diff --git a/src/components/structures/GenericErrorPage.js b/src/components/structures/GenericErrorPage.js new file mode 100644 index 0000000000..1962b471f3 --- /dev/null +++ b/src/components/structures/GenericErrorPage.js @@ -0,0 +1,38 @@ +/* +Copyright 2019 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; +import PropTypes from 'prop-types'; +import {_t} from "../../languageHandler"; + +export default class GenericErrorPage extends React.PureComponent { + static propTypes = { + message: PropTypes.string.isRequired, + }; + + render() { + return
    +
    +

    {_t("Error loading Riot")}

    +

    {this.props.message}

    +

    {_t( + "If this is unexpected, please contact your system administrator " + + "or technical support representative.", + )}

    +
    +
    ; + } +} \ No newline at end of file diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 52680ce91d..107aedc2a1 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1336,6 +1336,8 @@ "You must register to use this functionality": "You must register to use this functionality", "You must join the room to see its files": "You must join the room to see its files", "There are no visible files in this room": "There are no visible files in this room", + "Error loading Riot": "Error loading Riot", + "If this is unexpected, please contact your system administrator or technical support representative.": "If this is unexpected, please contact your system administrator or technical support representative.", "

    HTML for your community's page

    \n

    \n Use the long description to introduce new members to the community, or distribute\n some important links\n

    \n

    \n You can even use 'img' tags\n

    \n": "

    HTML for your community's page

    \n

    \n Use the long description to introduce new members to the community, or distribute\n some important links\n

    \n

    \n You can even use 'img' tags\n

    \n", "Add rooms to the community summary": "Add rooms to the community summary", "Which rooms would you like to add to this summary?": "Which rooms would you like to add to this summary?", From 9d55d0c89703f5a11641077a4c6ecd78ebf9fdd3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 11 Apr 2019 15:54:37 -0600 Subject: [PATCH 21/31] Add strings for js-sdk autodiscovery errors For https://github.com/matrix-org/matrix-js-sdk/pull/894 --- src/components/structures/auth/Login.js | 5 +++++ src/i18n/strings/en_EN.json | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/components/structures/auth/Login.js b/src/components/structures/auth/Login.js index 61b55b49d6..2940346a4f 100644 --- a/src/components/structures/auth/Login.js +++ b/src/components/structures/auth/Login.js @@ -42,7 +42,12 @@ const PHASES_ENABLED = true; // These are used in several places, and come from the js-sdk's autodiscovery // stuff. We define them here so that they'll be picked up by i18n. _td("Invalid homeserver discovery response"); +_td("Failed to get autodiscovery configuration from server"); +_td("Invalid base_url for m.homeserver"); +_td("Homeserver URL does not appear to be a valid Matrix homeserver"); _td("Invalid identity server discovery response"); +_td("Invalid base_url for m.identity_server"); +_td("Identity server URL does not appear to be a valid identity server"); _td("General failure"); /** diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 52680ce91d..efcd031c99 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1476,7 +1476,12 @@ "Return to login screen": "Return to login screen", "Set a new password": "Set a new password", "Invalid homeserver discovery response": "Invalid homeserver discovery response", + "Failed to get autodiscovery configuration from server": "Failed to get autodiscovery configuration from server", + "Invalid base_url for m.homeserver": "Invalid base_url for m.homeserver", + "Homeserver URL does not appear to be a valid Matrix homeserver": "Homeserver URL does not appear to be a valid Matrix homeserver", "Invalid identity server discovery response": "Invalid identity server discovery response", + "Invalid base_url for m.identity_server": "Invalid base_url for m.identity_server", + "Identity server URL does not appear to be a valid identity server": "Identity server URL does not appear to be a valid identity server", "General failure": "General failure", "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.", From d431e37d9b965557dee0bab8d63bac660345a76c Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 12 Apr 2019 10:37:14 +0100 Subject: [PATCH 22/31] Move and lint --- src/ContentMessages.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ContentMessages.js b/src/ContentMessages.js index 42b7971b87..ee3e8f1390 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -450,9 +450,6 @@ export default class ContentMessages { }, }; - // Focus the composer view - dis.dispatch({action: 'focus_composer'}) - // if we have a mime type for the file, add it to the message metadata if (file.type) { content.info.mimetype = file.type; @@ -495,6 +492,9 @@ export default class ContentMessages { this.inprogress.push(upload); dis.dispatch({action: 'upload_started'}); + // Focus the composer view + dis.dispatch({action: 'focus_composer'}); + let error; function onProgress(ev) { From 11bd82ee4cc78e6d33d415c3b93b5d38140199a6 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 12 Apr 2019 15:05:07 +0100 Subject: [PATCH 23/31] Ensure tags appear bold for all browsers In Firefox, the default style is such that it doesn't appear bold with our current selection of specific font weights. This specifically sets a working font weight. --- res/css/_common.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/res/css/_common.scss b/res/css/_common.scss index 4a9c2945f5..11894e414a 100644 --- a/res/css/_common.scss +++ b/res/css/_common.scss @@ -36,6 +36,12 @@ body { color: $warning-color; } +b { + // On Firefox, the default weight for `` is `bolder` which results in no bold + // effect since we only have specific weights of our fonts available. + font-weight: bold; +} + h2 { color: $primary-fg-color; font-weight: 400; From 5ee9de04c37aeac7d5d67842a7eea0f0e2ef2236 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 12 Apr 2019 16:23:54 +0100 Subject: [PATCH 24/31] Fix key backup status when missing device We might not have the device in `sig.device`, so we have to check for it's existence first. This fixes the "Unable to load key backup status" message that is incorrectly triggering. Fixes https://github.com/vector-im/riot-web/issues/9442 --- src/components/views/settings/KeyBackupPanel.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/views/settings/KeyBackupPanel.js b/src/components/views/settings/KeyBackupPanel.js index 7667e11d46..42ebf1c89d 100644 --- a/src/components/views/settings/KeyBackupPanel.js +++ b/src/components/views/settings/KeyBackupPanel.js @@ -221,7 +221,10 @@ export default class KeyBackupPanel extends React.PureComponent { {sub} ; const device = sub => {deviceName}; - const fromThisDevice = sig.device.getFingerprint() === MatrixClientPeg.get().getDeviceEd25519Key(); + const fromThisDevice = ( + sig.device && + sig.device.getFingerprint() === MatrixClientPeg.get().getDeviceEd25519Key() + ); let sigStatus; if (!sig.device) { sigStatus = _t( From 0479901daa288bd87a645d8827b6530db92b2190 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 12 Apr 2019 10:38:39 -0600 Subject: [PATCH 25/31] Load data for permalink creators once --- src/components/structures/RoomView.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 1bcbec4845..acece9271c 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -277,7 +277,13 @@ module.exports = React.createClass({ if (this._permalinkCreators[room.roomId]) return this._permalinkCreators[room.roomId]; this._permalinkCreators[room.roomId] = new RoomPermalinkCreator(room); - this._permalinkCreators[room.roomId].load(); + if (this.state.room && room.roomId === this.state.room.roomId) { + // We want to watch for changes in the creator for the primary room in the view, but + // don't need to do so for search results. + this._permalinkCreators[room.roomId].start(); + } else { + this._permalinkCreators[room.roomId].load(); + } return this._permalinkCreators[room.roomId]; }, @@ -664,9 +670,6 @@ module.exports = React.createClass({ this._loadMembersIfJoined(room); this._calculateRecommendedVersion(room); this._updateE2EStatus(room); - - let creator = this._getPermalinkCreatorForRoom(room); - if (!creator.isStarted()) creator.start(); }, _calculateRecommendedVersion: async function(room) { From 9478ccc6836e8988a7f16a346ff0c78e49d70421 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 14 Apr 2019 20:46:32 -0600 Subject: [PATCH 26/31] Add missing newline --- src/components/structures/GenericErrorPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/GenericErrorPage.js b/src/components/structures/GenericErrorPage.js index 1962b471f3..f28f66064c 100644 --- a/src/components/structures/GenericErrorPage.js +++ b/src/components/structures/GenericErrorPage.js @@ -35,4 +35,4 @@ export default class GenericErrorPage extends React.PureComponent {
    ; } -} \ No newline at end of file +} From e256dd6b057e737e987a83e6092cc92a763d9ecb Mon Sep 17 00:00:00 2001 From: Thomas Karner Date: Mon, 15 Apr 2019 09:13:18 +0200 Subject: [PATCH 27/31] use SdkConfig brand name instead of static "Riot" Signed-off-by: Thomas Karner --- src/components/structures/MatrixChat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index fe0deb0d49..f6ca6fbdd9 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1797,7 +1797,7 @@ export default React.createClass({ }, _setPageSubtitle: function(subtitle='') { - document.title = `Riot ${subtitle}`; + document.title = `${SdkConfig.get().brand || 'Riot'} ${subtitle}`; }, updateStatusIndicator: function(state, prevState) { From 9a59b0d390a5bbcd995e12791dcbf7a11c4a05aa Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 12 Apr 2019 12:38:35 +0100 Subject: [PATCH 28/31] Clarify that use backup means restore "Use key backup" feels like it's telling me I haven't set it up at all. This changes to "Restore ..." which seems more reassuring. Fixes https://github.com/vector-im/riot-web/issues/9438 --- src/components/views/settings/KeyBackupPanel.js | 3 +-- src/i18n/strings/en_EN.json | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/views/settings/KeyBackupPanel.js b/src/components/views/settings/KeyBackupPanel.js index 42ebf1c89d..5575f08be5 100644 --- a/src/components/views/settings/KeyBackupPanel.js +++ b/src/components/views/settings/KeyBackupPanel.js @@ -176,7 +176,7 @@ export default class KeyBackupPanel extends React.PureComponent { } else if (this.state.backupInfo) { const EmojiText = sdk.getComponent('elements.EmojiText'); let clientBackupStatus; - let restoreButtonCaption = _t("Restore from Backup"); + const restoreButtonCaption = _t("Restore from Backup"); if (MatrixClientPeg.get().getKeyBackupEnabled()) { clientBackupStatus =
    @@ -192,7 +192,6 @@ export default class KeyBackupPanel extends React.PureComponent { )}

    {_t("Back up your keys before signing out to avoid losing them.")}

    ; - restoreButtonCaption = _t("Use key backup"); } let uploadStatus; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index e4d1d3ea80..78733dae7c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -469,7 +469,6 @@ "This device is backing up your keys. ": "This device is backing up your keys. ", "This device is not backing up your keys.": "This device is not backing up your keys.", "Back up your keys before signing out to avoid losing them.": "Back up your keys before signing out to avoid losing them.", - "Use key backup": "Use key backup", "Backing up %(sessionsRemaining)s keys...": "Backing up %(sessionsRemaining)s keys...", "All keys backed up": "All keys backed up", "Backup has a signature from unknown device with ID %(deviceId)s.": "Backup has a signature from unknown device with ID %(deviceId)s.", From bded275f6a2ed62251bc4093ff5032cf6fa4842f Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 12 Apr 2019 17:40:22 +0100 Subject: [PATCH 29/31] Clarify messaging when key backup exists but is unused This makes the key backup panel much more explicit about the case where an existing backup does exist, but this device just isn't using it. You can join the device to the backup and restore from it by going through the restore workflow. Fixes https://github.com/vector-im/riot-web/issues/9446 --- src/components/views/settings/KeyBackupPanel.js | 10 ++++++++-- src/i18n/strings/en_EN.json | 5 +++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/components/views/settings/KeyBackupPanel.js b/src/components/views/settings/KeyBackupPanel.js index 5575f08be5..e85491bf60 100644 --- a/src/components/views/settings/KeyBackupPanel.js +++ b/src/components/views/settings/KeyBackupPanel.js @@ -187,10 +187,16 @@ export default class KeyBackupPanel extends React.PureComponent { clientBackupStatus =

    {encryptedMessageAreEncrypted}

    {_t( - "This device is not backing up your keys.", {}, + "This device is not backing up your keys, " + + "but there is an existing backup you can restore from " + + "and add to going forward.", {}, {b: sub => {sub}}, )}

    -

    {_t("Back up your keys before signing out to avoid losing them.")}

    +

    {_t( + "Enable key backup on this device via the restore " + + "process before signing out to avoid losing any keys " + + "that may only be on this device.", + )}

    ; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 78733dae7c..5d390f815a 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -467,8 +467,8 @@ "Unable to load key backup status": "Unable to load key backup status", "Restore from Backup": "Restore from Backup", "This device is backing up your keys. ": "This device is backing up your keys. ", - "This device is not backing up your keys.": "This device is not backing up your keys.", - "Back up your keys before signing out to avoid losing them.": "Back up your keys before signing out to avoid losing them.", + "This device is not backing up your keys, but there is an existing backup you can restore from and add to going forward.": "This device is not backing up your keys, but there is an existing backup you can restore from and add to going forward.", + "Enable key backup on this device via the restore process before signing out to avoid losing any keys that may only be on this device.": "Enable key backup on this device via the restore process before signing out to avoid losing any keys that may only be on this device.", "Backing up %(sessionsRemaining)s keys...": "Backing up %(sessionsRemaining)s keys...", "All keys backed up": "All keys backed up", "Backup has a signature from unknown device with ID %(deviceId)s.": "Backup has a signature from unknown device with ID %(deviceId)s.", @@ -484,6 +484,7 @@ "Backup version: ": "Backup version: ", "Algorithm: ": "Algorithm: ", "Your keys are not being backed up from this device.": "Your keys are not being backed up from this device.", + "Back up your keys before signing out to avoid losing them.": "Back up your keys before signing out to avoid losing them.", "Start using Key Backup": "Start using Key Backup", "Error saving email notification preferences": "Error saving email notification preferences", "An error occurred whilst saving your email notification preferences.": "An error occurred whilst saving your email notification preferences.", From 2054d5378274000572d7a932e844d70f1ead15ec Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 15 Apr 2019 15:10:19 +0100 Subject: [PATCH 30/31] Tweaked wording after discussing with @lampholder --- src/components/views/settings/KeyBackupPanel.js | 10 +++++----- src/i18n/strings/en_EN.json | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/components/views/settings/KeyBackupPanel.js b/src/components/views/settings/KeyBackupPanel.js index e85491bf60..2ba05a0e6b 100644 --- a/src/components/views/settings/KeyBackupPanel.js +++ b/src/components/views/settings/KeyBackupPanel.js @@ -176,7 +176,7 @@ export default class KeyBackupPanel extends React.PureComponent { } else if (this.state.backupInfo) { const EmojiText = sdk.getComponent('elements.EmojiText'); let clientBackupStatus; - const restoreButtonCaption = _t("Restore from Backup"); + let restoreButtonCaption = _t("Restore from Backup"); if (MatrixClientPeg.get().getKeyBackupEnabled()) { clientBackupStatus =
    @@ -188,16 +188,16 @@ export default class KeyBackupPanel extends React.PureComponent {

    {encryptedMessageAreEncrypted}

    {_t( "This device is not backing up your keys, " + - "but there is an existing backup you can restore from " + + "but you do have an existing backup you can restore from " + "and add to going forward.", {}, {b: sub => {sub}}, )}

    {_t( - "Enable key backup on this device via the restore " + - "process before signing out to avoid losing any keys " + - "that may only be on this device.", + "Connect this device to key backup before signing out to avoid " + + "losing any keys that may only be on this device.", )}

    ; + restoreButtonCaption = _t("Connect this device to Key Backup"); } let uploadStatus; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 5d390f815a..d0f265e430 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -467,8 +467,9 @@ "Unable to load key backup status": "Unable to load key backup status", "Restore from Backup": "Restore from Backup", "This device is backing up your keys. ": "This device is backing up your keys. ", - "This device is not backing up your keys, but there is an existing backup you can restore from and add to going forward.": "This device is not backing up your keys, but there is an existing backup you can restore from and add to going forward.", - "Enable key backup on this device via the restore process before signing out to avoid losing any keys that may only be on this device.": "Enable key backup on this device via the restore process before signing out to avoid losing any keys that may only be on this device.", + "This device is not backing up your keys, but you do have an existing backup you can restore from and add to going forward.": "This device is not backing up your keys, but you do have an existing backup you can restore from and add to going forward.", + "Connect this device to key backup before signing out to avoid losing any keys that may only be on this device.": "Connect this device to key backup before signing out to avoid losing any keys that may only be on this device.", + "Connect this device to Key Backup": "Connect this device to Key Backup", "Backing up %(sessionsRemaining)s keys...": "Backing up %(sessionsRemaining)s keys...", "All keys backed up": "All keys backed up", "Backup has a signature from unknown device with ID %(deviceId)s.": "Backup has a signature from unknown device with ID %(deviceId)s.", From a11cf88e07100974997363e5218cf6e7eca4d942 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 15 Apr 2019 14:46:00 -0600 Subject: [PATCH 31/31] Add a function to append/overwrite objects in the config on the fly Intended to be used to overwrite settings which may be calculated rather than provided. --- src/SdkConfig.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/SdkConfig.js b/src/SdkConfig.js index 78dd050a1e..eb18dad453 100644 --- a/src/SdkConfig.js +++ b/src/SdkConfig.js @@ -41,6 +41,12 @@ class SdkConfig { static unset() { global.mxReactSdkConfig = undefined; } + + static add(cfg) { + const liveConfig = SdkConfig.get(); + const newConfig = Object.assign({}, liveConfig, cfg); + SdkConfig.put(newConfig); + } } module.exports = SdkConfig;