From 665f507537602878bff2373490ede4a7366ae482 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 21 Apr 2017 18:18:35 +0100 Subject: [PATCH 01/73] Update js-sdk dependency --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0a0a51fc0b..67dfa165af 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "isomorphic-fetch": "^2.2.1", "linkifyjs": "^2.1.3", "lodash": "^4.13.1", - "matrix-js-sdk": "0.7.6", + "matrix-js-sdk": "0.7.7-rc.1", "optimist": "^0.6.1", "q": "^1.4.1", "react": "^15.4.0", From 2f08340ff0ee2bf767998fbe6d8e2bfee7187752 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 21 Apr 2017 18:22:39 +0100 Subject: [PATCH 02/73] Prepare changelog for v0.8.8-rc.1 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 292e60607d..7d4a69fb5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.8.8-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.8.8-rc.1) (2017-04-21) +============================================================================================================= +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.8.7...v0.8.8-rc.1) + + * Update js-sdk to fix registration without a captcha (https://github.com/vector-im/riot-web/issues/3621) + + Changes in [0.8.7](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.8.7) (2017-04-12) =================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.8.7-rc.4...v0.8.7) From a55eb00dad61e6485ace58737d44a898c08a41f2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 21 Apr 2017 18:22:39 +0100 Subject: [PATCH 03/73] v0.8.8-rc.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 67dfa165af..38d08344e0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.8.7", + "version": "0.8.8-rc.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 0590ce7faf9680d9d720a43de786545e7da5e7e6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 23 Apr 2017 06:06:23 +0100 Subject: [PATCH 04/73] Conform damn you (mostly) Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/Notifier.js | 53 ++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/Notifier.js b/src/Notifier.js index 92770877b7..617135a2c8 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -15,11 +15,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -var MatrixClientPeg = require("./MatrixClientPeg"); -var PlatformPeg = require("./PlatformPeg"); -var TextForEvent = require('./TextForEvent'); -var Avatar = require('./Avatar'); -var dis = require("./dispatcher"); +import MatrixClientPeg from './MatrixClientPeg'; +import PlatformPeg from './PlatformPeg'; +import TextForEvent from './TextForEvent'; +import Avatar from './Avatar'; +import dis from './dispatcher'; /* * Dispatches: @@ -29,7 +29,7 @@ var dis = require("./dispatcher"); * } */ -var Notifier = { +const Notifier = { notifsByRoom: {}, notificationMessageForEvent: function(ev) { @@ -48,16 +48,16 @@ var Notifier = { return; } - var msg = this.notificationMessageForEvent(ev); + let msg = this.notificationMessageForEvent(ev); if (!msg) return; - var title; - if (!ev.sender || room.name == ev.sender.name) { + let title; + if (!ev.sender || room.name === ev.sender.name) { title = room.name; // notificationMessageForEvent includes sender, // but we already have the sender here if (ev.getContent().body) msg = ev.getContent().body; - } else if (ev.getType() == 'm.room.member') { + } else if (ev.getType() === 'm.room.member') { // context is all in the message here, we don't need // to display sender info title = room.name; @@ -68,7 +68,7 @@ var Notifier = { if (ev.getContent().body) msg = ev.getContent().body; } - var avatarUrl = ev.sender ? Avatar.avatarUrlForMember( + const avatarUrl = ev.sender ? Avatar.avatarUrlForMember( ev.sender, 40, 40, 'crop' ) : null; @@ -83,7 +83,7 @@ var Notifier = { }, _playAudioNotification: function(ev, room) { - var e = document.getElementById("messageAudio"); + const e = document.getElementById("messageAudio"); if (e) { e.load(); e.play(); @@ -95,7 +95,7 @@ var Notifier = { this.boundOnSyncStateChange = this.onSyncStateChange.bind(this); this.boundOnRoomReceipt = this.onRoomReceipt.bind(this); MatrixClientPeg.get().on('Room.timeline', this.boundOnRoomTimeline); - MatrixClientPeg.get().on("Room.receipt", this.boundOnRoomReceipt); + MatrixClientPeg.get().on('Room.receipt', this.boundOnRoomReceipt); MatrixClientPeg.get().on("sync", this.boundOnSyncStateChange); this.toolbarHidden = false; this.isSyncing = false; @@ -104,7 +104,7 @@ var Notifier = { stop: function() { if (MatrixClientPeg.get() && this.boundOnRoomTimeline) { MatrixClientPeg.get().removeListener('Room.timeline', this.boundOnRoomTimeline); - MatrixClientPeg.get().removeListener("Room.receipt", this.boundOnRoomReceipt); + MatrixClientPeg.get().removeListener('Room.receipt', this.boundOnRoomReceipt); MatrixClientPeg.get().removeListener('sync', this.boundOnSyncStateChange); } this.isSyncing = false; @@ -121,7 +121,7 @@ var Notifier = { // make sure that we persist the current setting audio_enabled setting // before changing anything if (global.localStorage) { - if(global.localStorage.getItem('audio_notifications_enabled') == null) { + if (global.localStorage.getItem('audio_notifications_enabled') === null) { this.setAudioEnabled(this.isEnabled()); } } @@ -141,7 +141,7 @@ var Notifier = { if (callback) callback(); dis.dispatch({ action: "notifier_enabled", - value: true + value: true, }); }); // clear the notifications_hidden flag, so that if notifications are @@ -152,7 +152,7 @@ var Notifier = { global.localStorage.setItem('notifications_enabled', 'false'); dis.dispatch({ action: "notifier_enabled", - value: false + value: false, }); } }, @@ -165,7 +165,7 @@ var Notifier = { if (!global.localStorage) return true; - var enabled = global.localStorage.getItem('notifications_enabled'); + const enabled = global.localStorage.getItem('notifications_enabled'); if (enabled === null) return true; return enabled === 'true'; }, @@ -173,12 +173,12 @@ var Notifier = { setAudioEnabled: function(enable) { if (!global.localStorage) return; global.localStorage.setItem('audio_notifications_enabled', - enable ? 'true' : 'false'); + enable ? 'true' : 'false'); }, isAudioEnabled: function(enable) { if (!global.localStorage) return true; - var enabled = global.localStorage.getItem( + const enabled = global.localStorage.getItem( 'audio_notifications_enabled'); // default to true if the popups are enabled if (enabled === null) return this.isEnabled(); @@ -192,7 +192,7 @@ var Notifier = { // this is nothing to do with notifier_enabled dis.dispatch({ action: "notifier_enabled", - value: this.isEnabled() + value: this.isEnabled(), }); // update the info to localStorage for persistent settings @@ -215,8 +215,7 @@ var Notifier = { onSyncStateChange: function(state) { if (state === "SYNCING") { this.isSyncing = true; - } - else if (state === "STOPPED" || state === "ERROR") { + } else if (state === "STOPPED" || state === "ERROR") { this.isSyncing = false; } }, @@ -225,10 +224,10 @@ var Notifier = { if (toStartOfTimeline) return; if (!room) return; if (!this.isSyncing) return; // don't alert for any messages initially - if (ev.sender && ev.sender.userId == MatrixClientPeg.get().credentials.userId) return; + if (ev.sender && ev.sender.userId === MatrixClientPeg.get().credentials.userId) return; if (data.timeline.getTimelineSet() !== room.getUnfilteredTimelineSet()) return; - var actions = MatrixClientPeg.get().getPushActionsForEvent(ev); + const actions = MatrixClientPeg.get().getPushActionsForEvent(ev); if (actions && actions.notify) { if (this.isEnabled()) { this._displayPopupNotification(ev, room); @@ -240,7 +239,7 @@ var Notifier = { }, onRoomReceipt: function(ev, room) { - if (room.getUnreadNotificationCount() == 0) { + if (room.getUnreadNotificationCount() === 0) { // ideally we would clear each notification when it was read, // but we have no way, given a read receipt, to know whether // the receipt comes before or after an event, so we can't @@ -255,7 +254,7 @@ var Notifier = { } delete this.notifsByRoom[room.roomId]; } - } + }, }; if (!global.mxNotifier) { From 5e8b43f3edc70cd8d73a920c9a231c0f681c43fb Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 23 Apr 2017 06:16:25 +0100 Subject: [PATCH 05/73] if we're not granted, show an ErrorDialog with some text which needs changing Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/Notifier.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Notifier.js b/src/Notifier.js index 617135a2c8..fed2760732 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -20,6 +20,8 @@ import PlatformPeg from './PlatformPeg'; import TextForEvent from './TextForEvent'; import Avatar from './Avatar'; import dis from './dispatcher'; +import sdk from './index'; +import Modal from './Modal'; /* * Dispatches: @@ -131,6 +133,14 @@ const Notifier = { plaf.requestNotificationPermission().done((result) => { if (result !== 'granted') { // The permission request was dismissed or denied + const description = result === 'denied' + ? 'Your browser is not permitting this app to send you notifications.' + : 'It seems you didn\'t accept notifications when your browser asked'; + const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); + Modal.createDialog(ErrorDialog, { + title: 'Unable to enable Notifications', + description, + }); return; } From 74e92d6c235e629802184c86d0323587dec9f82f Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 24 Apr 2017 15:44:45 +0100 Subject: [PATCH 06/73] Remove DM-guessing code --- src/components/views/rooms/RoomList.js | 53 +++----------------------- 1 file changed, 6 insertions(+), 47 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 3810f7d4d6..5839b66d1c 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -97,7 +97,7 @@ module.exports = React.createClass({ if (this.props.selectedRoom) { constantTimeDispatcher.dispatch( "RoomTile.select", this.props.selectedRoom, {} - ); + ); } constantTimeDispatcher.dispatch( "RoomTile.select", nextProps.selectedRoom, { selected: true } @@ -265,7 +265,7 @@ module.exports = React.createClass({ }, onRoomStateMember: function(ev, state, member) { - if (ev.getStateKey() === MatrixClientPeg.get().credentials.userId && + if (ev.getStateKey() === MatrixClientPeg.get().credentials.userId && ev.getPrevContent() && ev.getPrevContent().membership === "invite") { this._delayedRefreshRoomList(); @@ -290,7 +290,7 @@ module.exports = React.createClass({ this._delayedRefreshRoomList(); } else if (ev.getType() == 'm.push_rules') { - this._delayedRefreshRoomList(); + this._delayedRefreshRoomList(); } }, @@ -318,7 +318,7 @@ module.exports = React.createClass({ // as needed. // Alternatively we'd do something magical with Immutable.js or similar. this.setState(this.getRoomLists()); - + // this._lastRefreshRoomListTs = Date.now(); }, @@ -341,7 +341,7 @@ module.exports = React.createClass({ MatrixClientPeg.get().getRooms().forEach(function(room) { const me = room.getMember(MatrixClientPeg.get().credentials.userId); if (!me) return; - + // console.log("room = " + room.name + ", me.membership = " + me.membership + // ", sender = " + me.events.member.getSender() + // ", target = " + me.events.member.getStateKey() + @@ -391,51 +391,10 @@ module.exports = React.createClass({ } }); - if (s.lists["im.vector.fake.direct"].length == 0 && - MatrixClientPeg.get().getAccountData('m.direct') === undefined && - !MatrixClientPeg.get().isGuest()) - { - // scan through the 'recents' list for any rooms which look like DM rooms - // and make them DM rooms - const oldRecents = s.lists["im.vector.fake.recent"]; - s.lists["im.vector.fake.recent"] = []; - - for (const room of oldRecents) { - const me = room.getMember(MatrixClientPeg.get().credentials.userId); - - if (me && Rooms.looksLikeDirectMessageRoom(room, me)) { - self.listsForRoomId[room.roomId].push("im.vector.fake.direct"); - s.lists["im.vector.fake.direct"].push(room); - } else { - self.listsForRoomId[room.roomId].push("im.vector.fake.recent"); - s.lists["im.vector.fake.recent"].push(room); - } - } - - // save these new guessed DM rooms into the account data - const newMDirectEvent = {}; - for (const room of s.lists["im.vector.fake.direct"]) { - const me = room.getMember(MatrixClientPeg.get().credentials.userId); - const otherPerson = Rooms.getOnlyOtherMember(room, me); - if (!otherPerson) continue; - - const roomList = newMDirectEvent[otherPerson.userId] || []; - roomList.push(room.roomId); - newMDirectEvent[otherPerson.userId] = roomList; - } - - console.warn("Resetting room DM state to be " + JSON.stringify(newMDirectEvent)); - - // if this fails, fine, we'll just do the same thing next time we get the room lists - MatrixClientPeg.get().setAccountData('m.direct', newMDirectEvent).done(); - } - - //console.log("calculated new roomLists; im.vector.fake.recent = " + s.lists["im.vector.fake.recent"]); - // we actually apply the sorting to this when receiving the prop in RoomSubLists. // we'll need this when we get to iterating through lists programatically - e.g. ctrl-shift-up/down -/* +/* this.listOrder = [ "im.vector.fake.invite", "m.favourite", From bb6dd363d70d9ebeaa650a8349c233251c0b00be Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 10 Apr 2017 12:07:39 +0100 Subject: [PATCH 07/73] unbreak in-app permalinks correctly --- src/linkify-matrix.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linkify-matrix.js b/src/linkify-matrix.js index e085b1a27a..c8e20316a9 100644 --- a/src/linkify-matrix.js +++ b/src/linkify-matrix.js @@ -122,7 +122,7 @@ var escapeRegExp = function(string) { // anyone else really should be using matrix.to. matrixLinkify.VECTOR_URL_PATTERN = "^(?:https?:\/\/)?(?:" + escapeRegExp(window.location.host + window.location.pathname) + "|" - + "(?:www\\.)?(riot|vector)\\.im/(?:beta|staging|develop)/" + + "(?:www\\.)?(?:riot|vector)\\.im/(?:beta|staging|develop)/" + ")(#.*)"; matrixLinkify.MATRIXTO_URL_PATTERN = "^(?:https?:\/\/)?(?:www\\.)?matrix\\.to/#/((#|@|!).*)"; From cf2cf66caebea125912b1ff228935d2fc2497213 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 22 Apr 2017 21:06:38 +0100 Subject: [PATCH 08/73] fix deep-linking to riot.im/app --- src/linkify-matrix.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linkify-matrix.js b/src/linkify-matrix.js index c8e20316a9..d9b0b78982 100644 --- a/src/linkify-matrix.js +++ b/src/linkify-matrix.js @@ -122,7 +122,7 @@ var escapeRegExp = function(string) { // anyone else really should be using matrix.to. matrixLinkify.VECTOR_URL_PATTERN = "^(?:https?:\/\/)?(?:" + escapeRegExp(window.location.host + window.location.pathname) + "|" - + "(?:www\\.)?(?:riot|vector)\\.im/(?:beta|staging|develop)/" + + "(?:www\\.)?(?:riot|vector)\\.im/(?:app|beta|staging|develop)/" + ")(#.*)"; matrixLinkify.MATRIXTO_URL_PATTERN = "^(?:https?:\/\/)?(?:www\\.)?matrix\\.to/#/((#|@|!).*)"; From 8e6981db44c7a765cc26f21c3fde76d5a723debe Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 24 Apr 2017 18:24:28 +0100 Subject: [PATCH 09/73] Prepare changelog for v0.8.8-rc.2 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d4a69fb5b..32f16c46ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.8.8-rc.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.8.8-rc.2) (2017-04-24) +============================================================================================================= +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.8.8-rc.1...v0.8.8-rc.2) + + * Fix bug where links to Riot would fail to open. + + Changes in [0.8.8-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.8.8-rc.1) (2017-04-21) ============================================================================================================= [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.8.7...v0.8.8-rc.1) From e569144d6f700cf05e52f67b66aa92237ee7546f Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 24 Apr 2017 18:24:29 +0100 Subject: [PATCH 10/73] v0.8.8-rc.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 38d08344e0..5fc8bc2750 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.8.8-rc.1", + "version": "0.8.8-rc.2", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 74dabb20873cb4650041710085d2ed06b3476218 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 25 Apr 2017 10:52:44 +0100 Subject: [PATCH 11/73] Released js-sdk --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5fc8bc2750..d14bc2b766 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "isomorphic-fetch": "^2.2.1", "linkifyjs": "^2.1.3", "lodash": "^4.13.1", - "matrix-js-sdk": "0.7.7-rc.1", + "matrix-js-sdk": "0.7.7", "optimist": "^0.6.1", "q": "^1.4.1", "react": "^15.4.0", From f6fd7b04ac01d7a7e3ef83ca186d9c462b047cb1 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 25 Apr 2017 10:53:58 +0100 Subject: [PATCH 12/73] Prepare changelog for v0.8.8 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32f16c46ae..97dda666de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.8.8](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.8.8) (2017-04-25) +=================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.8.8-rc.2...v0.8.8) + + * No changes + + Changes in [0.8.8-rc.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.8.8-rc.2) (2017-04-24) ============================================================================================================= [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.8.8-rc.1...v0.8.8-rc.2) From d81adb234a7581169a2ddbf2f0ee6375e5c340ce Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 25 Apr 2017 10:53:59 +0100 Subject: [PATCH 13/73] v0.8.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d14bc2b766..00dc902cc9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.8.8-rc.2", + "version": "0.8.8", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From c9c72036f38e500a88f5b9e0b7b57808a583f0ab Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@googlemail.com> Date: Fri, 28 Apr 2017 01:00:10 +0100 Subject: [PATCH 14/73] Change wording Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/Notifier.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Notifier.js b/src/Notifier.js index fed2760732..f68b7e562c 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -134,8 +134,10 @@ const Notifier = { if (result !== 'granted') { // The permission request was dismissed or denied const description = result === 'denied' - ? 'Your browser is not permitting this app to send you notifications.' - : 'It seems you didn\'t accept notifications when your browser asked'; + ? 'Riot does not have permission to send you notifications' + + ' - please check your browser settings' + : 'Riot was not given permission to send notifications' + + '- please try again'; const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); Modal.createDialog(ErrorDialog, { title: 'Unable to enable Notifications', From 47827e0b81c8db6977d2a628451daf9db348c5b5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@googlemail.com> Date: Fri, 28 Apr 2017 01:00:50 +0100 Subject: [PATCH 15/73] un-eat the space Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/Notifier.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Notifier.js b/src/Notifier.js index f68b7e562c..6473ab4d9c 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -137,7 +137,7 @@ const Notifier = { ? 'Riot does not have permission to send you notifications' + ' - please check your browser settings' : 'Riot was not given permission to send notifications' - + '- please try again'; + + ' - please try again'; const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); Modal.createDialog(ErrorDialog, { title: 'Unable to enable Notifications', From f5f35e32946a6690615eaecffe77c723f8567950 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 26 Apr 2017 18:59:16 +0100 Subject: [PATCH 16/73] Make the left panel more friendly to new users https://github.com/vector-im/riot-web/issues/3609 --- src/components/views/rooms/RoomList.js | 118 +++++++++++++++++++------ 1 file changed, 89 insertions(+), 29 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 96ff65498f..39d3406b73 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -29,7 +29,14 @@ import DMRoomMap from '../../../utils/DMRoomMap'; var Receipt = require('../../../utils/Receipt'); var constantTimeDispatcher = require('../../../ConstantTimeDispatcher'); -var HIDE_CONFERENCE_CHANS = true; +const HIDE_CONFERENCE_CHANS = true; + +const VERBS = { + 'm.favourite': 'favourite', + 'im.vector.fake.direct': 'tag direct chat', + 'im.vector.fake.recent': 'restore', + 'm.lowpriority': 'demote', +}; module.exports = React.createClass({ displayName: 'RoomList', @@ -53,6 +60,7 @@ module.exports = React.createClass({ getInitialState: function() { return { isLoadingLeftRooms: false, + totalRoomCount: null, lists: {}, incomingCall: null, }; @@ -73,8 +81,7 @@ module.exports = React.createClass({ // lookup for which lists a given roomId is currently in. this.listsForRoomId = {}; - var s = this.getRoomLists(); - this.setState(s); + this.refreshRoomList(); // order of the sublists //this.listOrder = []; @@ -317,21 +324,29 @@ module.exports = React.createClass({ // any changes to it incrementally, updating the appropriate sublists // as needed. // Alternatively we'd do something magical with Immutable.js or similar. - this.setState(this.getRoomLists()); + const lists = this.getRoomLists(); + let totalRooms = 0; + for (const l of Object.values(lists)) { + totalRooms += l.length; + } + this.setState({ + lists: this.getRoomLists(), + totalRoomCount: totalRooms, + }); // this._lastRefreshRoomListTs = Date.now(); }, getRoomLists: function() { var self = this; - var s = { lists: {} }; + const lists = {}; - s.lists["im.vector.fake.invite"] = []; - s.lists["m.favourite"] = []; - s.lists["im.vector.fake.recent"] = []; - s.lists["im.vector.fake.direct"] = []; - s.lists["m.lowpriority"] = []; - s.lists["im.vector.fake.archived"] = []; + lists["im.vector.fake.invite"] = []; + lists["m.favourite"] = []; + lists["im.vector.fake.recent"] = []; + lists["im.vector.fake.direct"] = []; + lists["m.lowpriority"] = []; + lists["im.vector.fake.archived"] = []; this.listsForRoomId = {}; var otherTagNames = {}; @@ -353,7 +368,7 @@ module.exports = React.createClass({ if (me.membership == "invite") { self.listsForRoomId[room.roomId].push("im.vector.fake.invite"); - s.lists["im.vector.fake.invite"].push(room); + lists["im.vector.fake.invite"].push(room); } else if (HIDE_CONFERENCE_CHANS && Rooms.isConfCallRoom(room, me, self.props.ConferenceHandler)) { // skip past this room & don't put it in any lists @@ -366,8 +381,8 @@ module.exports = React.createClass({ if (tagNames.length) { for (var i = 0; i < tagNames.length; i++) { var tagName = tagNames[i]; - s.lists[tagName] = s.lists[tagName] || []; - s.lists[tagName].push(room); + lists[tagName] = lists[tagName] || []; + lists[tagName].push(room); self.listsForRoomId[room.roomId].push(tagName); otherTagNames[tagName] = 1; } @@ -375,46 +390,46 @@ module.exports = React.createClass({ else if (dmRoomMap.getUserIdForRoomId(room.roomId)) { // "Direct Message" rooms (that we're still in and that aren't otherwise tagged) self.listsForRoomId[room.roomId].push("im.vector.fake.direct"); - s.lists["im.vector.fake.direct"].push(room); + lists["im.vector.fake.direct"].push(room); } else { self.listsForRoomId[room.roomId].push("im.vector.fake.recent"); - s.lists["im.vector.fake.recent"].push(room); + lists["im.vector.fake.recent"].push(room); } } else if (me.membership === "leave") { self.listsForRoomId[room.roomId].push("im.vector.fake.archived"); - s.lists["im.vector.fake.archived"].push(room); + lists["im.vector.fake.archived"].push(room); } else { console.error("unrecognised membership: " + me.membership + " - this should never happen"); } }); - if (s.lists["im.vector.fake.direct"].length == 0 && + if (lists["im.vector.fake.direct"].length == 0 && MatrixClientPeg.get().getAccountData('m.direct') === undefined && !MatrixClientPeg.get().isGuest()) { // scan through the 'recents' list for any rooms which look like DM rooms // and make them DM rooms - const oldRecents = s.lists["im.vector.fake.recent"]; - s.lists["im.vector.fake.recent"] = []; + const oldRecents = lists["im.vector.fake.recent"]; + lists["im.vector.fake.recent"] = []; for (const room of oldRecents) { const me = room.getMember(MatrixClientPeg.get().credentials.userId); if (me && Rooms.looksLikeDirectMessageRoom(room, me)) { self.listsForRoomId[room.roomId].push("im.vector.fake.direct"); - s.lists["im.vector.fake.direct"].push(room); + lists["im.vector.fake.direct"].push(room); } else { self.listsForRoomId[room.roomId].push("im.vector.fake.recent"); - s.lists["im.vector.fake.recent"].push(room); + lists["im.vector.fake.recent"].push(room); } } // save these new guessed DM rooms into the account data const newMDirectEvent = {}; - for (const room of s.lists["im.vector.fake.direct"]) { + for (const room of lists["im.vector.fake.direct"]) { const me = room.getMember(MatrixClientPeg.get().credentials.userId); const otherPerson = Rooms.getOnlyOtherMember(room, me); if (!otherPerson) continue; @@ -449,7 +464,7 @@ module.exports = React.createClass({ ]; */ - return s; + return lists; }, _getScrollNode: function() { @@ -479,6 +494,7 @@ module.exports = React.createClass({ var incomingCallBox = document.getElementById("incomingCallBox"); if (incomingCallBox && incomingCallBox.parentElement) { var scrollArea = this._getScrollNode(); + if (!scrollArea) return; // Use the offset of the top of the scroll area from the window // as this is used to calculate the CSS fixed top position for the stickies var scrollAreaOffset = scrollArea.getBoundingClientRect().top + window.pageYOffset; @@ -502,6 +518,7 @@ module.exports = React.createClass({ // properly through React _initAndPositionStickyHeaders: function(initialise, scrollToPosition) { var scrollArea = this._getScrollNode(); + if (!scrollArea) return; // Use the offset of the top of the scroll area from the window // as this is used to calculate the CSS fixed top position for the stickies var scrollAreaOffset = scrollArea.getBoundingClientRect().top + window.pageYOffset; @@ -599,6 +616,49 @@ module.exports = React.createClass({ this.refs.gemscroll.forceUpdate(); }, + _getEmptyContent: function(section) { + let greyed = false; + if (this.state.totalRoomCount === 0) { + const TintableSvg = sdk.getComponent('elements.TintableSvg'); + switch (section) { + case 'm.favourite': + case 'm.lowpriority': + greyed = true; + break; + case 'im.vector.fake.direct': + return
+
+ +
+ Use the button below to chat with someone! +
; + case 'im.vector.fake.recent': + return
+
+ +
+ Use the button below to browse the room directory +

+
+ +
+ or this button to start a new one! +
; + } + } + const RoomDropTarget = sdk.getComponent('rooms.RoomDropTarget'); + + const labelText = 'Drop here to ' + (VERBS[section] || 'tag ' + section); + + let label; + if (greyed) { + label = {labelText}; + } else { + label = labelText; + } + return ; + }, + render: function() { var RoomSubList = sdk.getComponent('structures.RoomSubList'); var self = this; @@ -622,7 +682,7 @@ module.exports = React.createClass({ Date: Fri, 28 Apr 2017 11:20:29 +0100 Subject: [PATCH 17/73] Other empty sections no longer need to be greyed --- src/components/views/rooms/RoomList.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 39d3406b73..963f5ad425 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -617,14 +617,9 @@ module.exports = React.createClass({ }, _getEmptyContent: function(section) { - let greyed = false; if (this.state.totalRoomCount === 0) { const TintableSvg = sdk.getComponent('elements.TintableSvg'); switch (section) { - case 'm.favourite': - case 'm.lowpriority': - greyed = true; - break; case 'im.vector.fake.direct': return
@@ -650,13 +645,7 @@ module.exports = React.createClass({ const labelText = 'Drop here to ' + (VERBS[section] || 'tag ' + section); - let label; - if (greyed) { - label = {labelText}; - } else { - label = labelText; - } - return ; + return ; }, render: function() { From 6685cbcb25e76abd9304319e6f2f16dfc53e58f8 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 29 Apr 2017 06:13:03 +0100 Subject: [PATCH 18/73] make MessageComposerInput (new and old) warn on unload new needs binding due to class this ref being softer couldn't do this nicely in MessageComposer/Input as isTyping wasn't propagated. Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MessageComposerInput.js | 10 ++++++++++ src/components/views/rooms/MessageComposerInputOld.js | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 8efd2fa579..672279ef54 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -93,6 +93,7 @@ export default class MessageComposerInput extends React.Component { this.onEscape = this.onEscape.bind(this); this.setDisplayedCompletion = this.setDisplayedCompletion.bind(this); this.onMarkdownToggleClicked = this.onMarkdownToggleClicked.bind(this); + this.onPageUnload = this.onPageUnload.bind(this); const isRichtextEnabled = UserSettingsStore.getSyncedSetting('MessageComposerInput.isRichTextEnabled', false); @@ -233,11 +234,13 @@ export default class MessageComposerInput extends React.Component { this.refs.editor, this.props.room.roomId ); + window.addEventListener('beforeunload', this.onPageUnload); } componentWillUnmount() { dis.unregister(this.dispatcherRef); this.sentHistory.saveLastTextEntry(); + window.removeEventListener('beforeunload', this.onPageUnload); } componentWillUpdate(nextProps, nextState) { @@ -249,6 +252,13 @@ export default class MessageComposerInput extends React.Component { } } + onPageUnload(event) { + if (this.isTyping) { + return event.returnValue = + 'You seem to be typing a message, are you sure you want to quit?'; + } + } + onAction(payload) { let editor = this.refs.editor; let contentState = this.state.editorState.getCurrentContent(); diff --git a/src/components/views/rooms/MessageComposerInputOld.js b/src/components/views/rooms/MessageComposerInputOld.js index 378644478c..2a992cdf5f 100644 --- a/src/components/views/rooms/MessageComposerInputOld.js +++ b/src/components/views/rooms/MessageComposerInputOld.js @@ -177,11 +177,20 @@ export default React.createClass({ if (this.props.tabComplete) { this.props.tabComplete.setTextArea(this.refs.textarea); } + window.addEventListener('beforeunload', this.onPageUnload); }, componentWillUnmount: function() { dis.unregister(this.dispatcherRef); this.sentHistory.saveLastTextEntry(); + window.removeEventListener('beforeunload', this.onPageUnload); + }, + + onPageUnload(event) { + if (this.isTyping) { + return event.returnValue = + 'You seem to be typing a message, are you sure you want to quit?'; + } }, onAction: function(payload) { From daae3bd1ecfae565ff1ed7958c564ff73fb0eae0 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 29 Apr 2017 06:25:30 +0100 Subject: [PATCH 19/73] warn on unload when uploading file(s) Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomView.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index a0c36374b6..9414a59e01 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -271,6 +271,7 @@ module.exports = React.createClass({ this._updateConfCallNotification(); + window.addEventListener('beforeunload', this.onPageUnload); window.addEventListener('resize', this.onResize); this.onResize(); @@ -353,6 +354,7 @@ module.exports = React.createClass({ MatrixClientPeg.get().removeListener("accountData", this.onAccountData); } + window.removeEventListener('beforeunload', this.onPageUnload); window.removeEventListener('resize', this.onResize); document.removeEventListener("keydown", this.onKeyDown); @@ -365,6 +367,14 @@ module.exports = React.createClass({ // Tinter.tint(); // reset colourscheme }, + onPageUnload(event) { + if (ContentMessages.getCurrentUploads().length > 0) { + return event.returnValue = + 'You seem to be uploading files, are you sure you want to quit?'; + } + }, + + onKeyDown: function(ev) { let handled = false; const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0; From 86a5ff42e952c52218f68937b83ac179fe290b83 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 29 Apr 2017 14:22:06 +0100 Subject: [PATCH 20/73] Change max-len 90->120 Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .eslintrc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index 6cd0e1015e..74790a2964 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -64,7 +64,7 @@ module.exports = { // to JSX. ignorePattern: '^\\s*<', ignoreComments: true, - code: 90, + code: 120, }], "valid-jsdoc": ["warn"], "new-cap": ["warn"], From c8fb18dc932bdfe6e64bce328b515a52d6c32607 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@googlemail.com> Date: Sun, 30 Apr 2017 13:00:47 +0100 Subject: [PATCH 21/73] Pin filesize ver to fix break upstream https://travis-ci.org/vector-im/riot-web/builds/227340622 https://github.com/avoidwork/filesize.js/issues/87 3.5.7 and 3.5.8 ver released <24h ago and broke stuff for us --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5c96a74f5b..95a82bbb73 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "draft-js-export-markdown": "^0.2.0", "emojione": "2.2.3", "file-saver": "^1.3.3", - "filesize": "^3.1.2", + "filesize": "3.5.6", "flux": "^2.0.3", "fuse.js": "^2.2.0", "glob": "^5.0.14", From 3f25928380b36834e0cbe249938581ede9dc3c6e Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 2 May 2017 16:34:39 +0100 Subject: [PATCH 22/73] Fix jumping to an unread event when in MELS This adds the `data-contained-scroll-tokens` API to elements in `ScrollPanel` which allows arbitrary containers of elements with scroll tokens to declare their contained scroll tokens. When jumping to a scroll token inside a container, the `ScrollPanel` will act as if it is scrolling to the container itself, not the child. MELS has been modified such that it exposes the scroll tokens of all events that exist within it.This means "Jump to unread message" will work if the unread event is within a MELS (which is any member event, because even individual member events surrounded by other events are put inside a MELS). --- src/components/structures/MessagePanel.js | 1 - src/components/structures/ScrollPanel.js | 5 +++++ src/components/views/elements/MemberEventListSummary.js | 5 +++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 246f351841..74aec61511 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -354,7 +354,6 @@ module.exports = React.createClass({ {eventTiles} diff --git a/src/components/structures/ScrollPanel.js b/src/components/structures/ScrollPanel.js index d43e22e2f1..da3b303d89 100644 --- a/src/components/structures/ScrollPanel.js +++ b/src/components/structures/ScrollPanel.js @@ -551,6 +551,11 @@ module.exports = React.createClass({ var messages = this.refs.itemlist.children; for (var i = messages.length-1; i >= 0; --i) { var m = messages[i]; + if (m.dataset.containedScrollTokens && + m.dataset.containedScrollTokens.indexOf(scrollToken) !== -1) { + node = m; + break; + } if (!m.dataset.scrollToken) continue; if (m.dataset.scrollToken == scrollToken) { node = m; diff --git a/src/components/views/elements/MemberEventListSummary.js b/src/components/views/elements/MemberEventListSummary.js index 63bd2a7c39..a24e19577d 100644 --- a/src/components/views/elements/MemberEventListSummary.js +++ b/src/components/views/elements/MemberEventListSummary.js @@ -369,6 +369,7 @@ module.exports = React.createClass({ render: function() { const eventsToRender = this.props.events; + const eventIds = eventsToRender.map(e => e.getId()); const fewEvents = eventsToRender.length < this.props.threshold; const expanded = this.state.expanded || fewEvents; @@ -379,7 +380,7 @@ module.exports = React.createClass({ if (fewEvents) { return ( -
+
{expandedEvents}
); @@ -437,7 +438,7 @@ module.exports = React.createClass({ ); return ( -
+
{toggleButton} {summaryContainer} {expanded ?
 
: null} From fe83a99ab709121d2259b25d1a735babb2a022ee Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 2 May 2017 17:36:59 +0100 Subject: [PATCH 23/73] Update ScrollPanel docs --- src/components/structures/ScrollPanel.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/structures/ScrollPanel.js b/src/components/structures/ScrollPanel.js index da3b303d89..7fa320d784 100644 --- a/src/components/structures/ScrollPanel.js +++ b/src/components/structures/ScrollPanel.js @@ -50,6 +50,10 @@ if (DEBUG_SCROLL) { * serialise the scroll state, and returned as the 'trackedScrollToken' * attribute by getScrollState(). * + * Child elements that contain elements that have scroll tokens must declare the + * contained scroll tokens using 'data-contained-scroll-tokens`. When scrolling + * to a contained scroll token, the ScrollPanel will scroll to the container. + * * Some notes about the implementation: * * The saved 'scrollState' can exist in one of two states: From 4febc63aeecee7613681749b3aa435cbd25ea17f Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 2 May 2017 17:41:09 +0100 Subject: [PATCH 24/73] Add comment to _scrollToToken --- src/components/structures/ScrollPanel.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/structures/ScrollPanel.js b/src/components/structures/ScrollPanel.js index 7fa320d784..3f36fac89b 100644 --- a/src/components/structures/ScrollPanel.js +++ b/src/components/structures/ScrollPanel.js @@ -555,6 +555,9 @@ module.exports = React.createClass({ var messages = this.refs.itemlist.children; for (var i = messages.length-1; i >= 0; --i) { var m = messages[i]; + // 'data-contained-scroll-tokens' has been set, indicating that a child + // element contains elements that each have a token. Check this array of + // tokens for `scrollToken`. if (m.dataset.containedScrollTokens && m.dataset.containedScrollTokens.indexOf(scrollToken) !== -1) { node = m; From af137f8867dce643232c8edfa92294b8f87b3b89 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 2 May 2017 18:30:46 +0100 Subject: [PATCH 25/73] Validate phone number on login To prevent confusion when accidently inputting mxid or email. Fixes https://github.com/vector-im/riot-web/issues/3637 --- src/components/structures/login/Login.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js index 315a0ea242..a3635177e2 100644 --- a/src/components/structures/login/Login.js +++ b/src/components/structures/login/Login.js @@ -23,6 +23,9 @@ import url from 'url'; import sdk from '../../../index'; import Login from '../../../Login'; +// For validating phone numbers without country codes +const PHONE_NUMBER_REGEX = /^[0-9\(\)\-\s]*$/; + /** * A wire component which glues together login UI components and Login logic */ @@ -125,7 +128,16 @@ module.exports = React.createClass({ }, onPhoneNumberChanged: function(phoneNumber) { - this.setState({ phoneNumber: phoneNumber }); + // Validate the phone number entered + if (!PHONE_NUMBER_REGEX.test(phoneNumber)) { + this.setState({ errorText: 'The phone number entered looks invalid' }); + return; + } + + this.setState({ + phoneNumber: phoneNumber, + errorText: null, + }); }, onServerConfigChange: function(config) { From 76e98d42679e5a1167ebad419ec66abfd70f7a3c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 2 May 2017 21:12:58 +0100 Subject: [PATCH 26/73] improve version hyperlinking removed redundant v prefix (key already says version) links to most applicable version/tag tag-commit -> commit commit1-commit2-commit3 -> commit1 (v)x.y.z -> tag commit -> commit Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/UserSettings.js | 25 +++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index ba5d5780b4..88e6829514 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -32,13 +32,22 @@ import AccessibleButton from '../views/elements/AccessibleButton'; // if this looks like a release, use the 'version' from package.json; else use // the git sha. Prepend version with v, to look like riot-web version -const REACT_SDK_VERSION = 'dist' in package_json ? `v${package_json.version}` : package_json.gitHead || ''; +const REACT_SDK_VERSION = 'dist' in package_json ? package_json.version : package_json.gitHead || ''; // Simple method to help prettify GH Release Tags and Commit Hashes. -const GHVersionUrl = function(repo, token) { - const uriTail = (token.startsWith('v') && token.includes('.')) ? `releases/tag/${token}` : `commit/${token}`; - return `https://github.com/${repo}/${uriTail}`; -} +const semVerRegex = /^v?(\d+\.\d+\.\d+)(?:-(?:\d+-g)?(.+))?|$/i; +const gHVersionLabel = function(repo, token) { + const match = token.match(semVerRegex); + let url; // assume commit hash + if (match && match[1]) { // basic semVer string possibly with commit hash + url = (match.length > 1 && match[2]) + ? `https://github.com/${repo}/commit/${match[2]}` + : `https://github.com/${repo}/releases/tag/v${match[1]}`; + } else { + url = `https://github.com/${repo}/commit/${token.split('-')[0]}`; + } + return {token}; +}; // Enumerate some simple 'flip a bit' UI settings (if any). // 'id' gives the key name in the im.vector.web.settings account data event @@ -911,7 +920,7 @@ module.exports = React.createClass({ // we are using a version old version of olm. We assume the former. let olmVersionString = ""; if (olmVersion !== undefined) { - olmVersionString = `v${olmVersion[0]}.${olmVersion[1]}.${olmVersion[2]}`; + olmVersionString = `${olmVersion[0]}.${olmVersion[1]}.${olmVersion[2]}`; } return ( @@ -995,11 +1004,11 @@ module.exports = React.createClass({
matrix-react-sdk version: {(REACT_SDK_VERSION !== '') - ? {REACT_SDK_VERSION} + ? gHVersionLabel('matrix-org/matrix-react-sdk', REACT_SDK_VERSION) : REACT_SDK_VERSION }
riot-web version: {(this.state.vectorVersion !== null) - ? {this.state.vectorVersion} + ? gHVersionLabel('vector-im/riot-web', this.state.vectorVersion) : 'unknown' }
olm version: {olmVersionString}
From 74b2c86f93db0692311750c2a1d38339a44eb72a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 2 May 2017 21:17:12 +0100 Subject: [PATCH 27/73] tidy up UserSettings Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/UserSettings.js | 177 +++++++++++----------- 1 file changed, 88 insertions(+), 89 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 88e6829514..4b63c8d888 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -14,25 +14,25 @@ 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. */ -var React = require('react'); -var ReactDOM = require('react-dom'); -var sdk = require('../../index'); -var MatrixClientPeg = require("../../MatrixClientPeg"); -var PlatformPeg = require("../../PlatformPeg"); -var Modal = require('../../Modal'); -var dis = require("../../dispatcher"); -var q = require('q'); -var package_json = require('../../../package.json'); -var UserSettingsStore = require('../../UserSettingsStore'); -var GeminiScrollbar = require('react-gemini-scrollbar'); -var Email = require('../../email'); -var AddThreepid = require('../../AddThreepid'); -var SdkConfig = require('../../SdkConfig'); +const React = require('react'); +const ReactDOM = require('react-dom'); +const sdk = require('../../index'); +const MatrixClientPeg = require("../../MatrixClientPeg"); +const PlatformPeg = require("../../PlatformPeg"); +const Modal = require('../../Modal'); +const dis = require("../../dispatcher"); +const q = require('q'); +const packageJson = require('../../../package.json'); +const UserSettingsStore = require('../../UserSettingsStore'); +const GeminiScrollbar = require('react-gemini-scrollbar'); +const Email = require('../../email'); +const AddThreepid = require('../../AddThreepid'); +const SdkConfig = require('../../SdkConfig'); import AccessibleButton from '../views/elements/AccessibleButton'; // if this looks like a release, use the 'version' from package.json; else use // the git sha. Prepend version with v, to look like riot-web version -const REACT_SDK_VERSION = 'dist' in package_json ? package_json.version : package_json.gitHead || ''; +const REACT_SDK_VERSION = 'dist' in packageJson ? packageJson.version : packageJson.gitHead || ''; // Simple method to help prettify GH Release Tags and Commit Hashes. const semVerRegex = /^v?(\d+\.\d+\.\d+)(?:-(?:\d+-g)?(.+))?|$/i; @@ -59,7 +59,7 @@ const SETTINGS_LABELS = [ }, { id: 'hideReadReceipts', - label: 'Hide read receipts' + label: 'Hide read receipts', }, { id: 'dontSendTypingNotifications', @@ -115,7 +115,7 @@ const THEMES = [ id: 'theme', label: 'Dark theme', value: 'dark', - } + }, ]; @@ -189,7 +189,7 @@ module.exports = React.createClass({ }); this._refreshFromServer(); - var syncedSettings = UserSettingsStore.getSyncedSettings(); + const syncedSettings = UserSettingsStore.getSyncedSettings(); if (!syncedSettings.theme) { syncedSettings.theme = 'light'; } @@ -211,16 +211,16 @@ module.exports = React.createClass({ middleOpacity: 1.0, }); dis.unregister(this.dispatcherRef); - let cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.get(); if (cli) { cli.removeListener("RoomMember.membership", this._onInviteStateChange); } }, _refreshFromServer: function() { - var self = this; + const self = this; q.all([ - UserSettingsStore.loadProfileInfo(), UserSettingsStore.loadThreePids() + UserSettingsStore.loadProfileInfo(), UserSettingsStore.loadThreePids(), ]).done(function(resps) { self.setState({ avatarUrl: resps[0].avatar_url, @@ -228,7 +228,7 @@ module.exports = React.createClass({ phase: "UserSettings.DISPLAY", }); }, function(error) { - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to load user settings: " + error); Modal.createDialog(ErrorDialog, { title: "Can't load user settings", @@ -245,7 +245,7 @@ module.exports = React.createClass({ onAvatarPickerClick: function(ev) { if (MatrixClientPeg.get().isGuest()) { - var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); + const NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); Modal.createDialog(NeedToRegisterDialog, { title: "Please Register", description: "Guests can't set avatars. Please register.", @@ -259,8 +259,8 @@ module.exports = React.createClass({ }, onAvatarSelected: function(ev) { - var self = this; - var changeAvatar = this.refs.changeAvatar; + const self = this; + const changeAvatar = this.refs.changeAvatar; if (!changeAvatar) { console.error("No ChangeAvatar found to upload image to!"); return; @@ -269,9 +269,9 @@ module.exports = React.createClass({ // dunno if the avatar changed, re-check it. self._refreshFromServer(); }, function(err) { - var errMsg = (typeof err === "string") ? err : (err.error || ""); + // const errMsg = (typeof err === "string") ? err : (err.error || ""); console.error("Failed to set avatar: " + err); - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createDialog(ErrorDialog, { title: "Failed to set avatar", description: ((err && err.message) ? err.message : "Operation failed"), @@ -280,7 +280,7 @@ module.exports = React.createClass({ }, onLogoutClicked: function(ev) { - var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); Modal.createDialog(QuestionDialog, { title: "Sign out?", description: @@ -295,7 +295,7 @@ module.exports = React.createClass({ + , ], onFinished: (confirmed) => { if (confirmed) { @@ -309,34 +309,33 @@ module.exports = React.createClass({ }, onPasswordChangeError: function(err) { - var errMsg = err.error || ""; + let errMsg = err.error || ""; if (err.httpStatus === 403) { errMsg = "Failed to change password. Is your password correct?"; - } - else if (err.httpStatus) { + } else if (err.httpStatus) { errMsg += ` (HTTP status ${err.httpStatus})`; } - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to change password: " + errMsg); Modal.createDialog(ErrorDialog, { title: "Error", - description: errMsg + description: errMsg, }); }, onPasswordChanged: function() { - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createDialog(ErrorDialog, { title: "Success", description: `Your password was successfully changed. You will not receive push notifications on other devices until you - log back in to them.` + log back in to them.`, }); }, onUpgradeClicked: function() { dis.dispatch({ - action: "start_upgrade_registration" + action: "start_upgrade_registration", }); }, @@ -350,11 +349,11 @@ module.exports = React.createClass({ }, _addEmail: function() { - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - var email_address = this.refs.add_email_input.value; - if (!Email.looksValid(email_address)) { + const emailAddress = this.refs.add_email_input.value; + if (!Email.looksValid(emailAddress)) { Modal.createDialog(ErrorDialog, { title: "Invalid Email Address", description: "This doesn't appear to be a valid email address", @@ -364,7 +363,7 @@ module.exports = React.createClass({ this._addThreepid = new AddThreepid(); // we always bind emails when registering, so let's do the // same here. - this._addThreepid.addEmailAddress(email_address, true).done(() => { + this._addThreepid.addEmailAddress(emailAddress, true).done(() => { Modal.createDialog(QuestionDialog, { title: "Verification Pending", description: "Please check your email and click on the link it contains. Once this is done, click continue.", @@ -373,7 +372,7 @@ module.exports = React.createClass({ }); }, (err) => { this.setState({email_add_pending: false}); - console.error("Unable to add email address " + email_address + " " + err); + console.error("Unable to add email address " + emailAddress + " " + err); Modal.createDialog(ErrorDialog, { title: "Unable to add email address", description: ((err && err.message) ? err.message : "Operation failed"), @@ -427,9 +426,9 @@ module.exports = React.createClass({ this.setState({email_add_pending: false}); }, (err) => { this.setState({email_add_pending: false}); - if (err.errcode == 'M_THREEPID_AUTH_FAILED') { - var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - var message = "Unable to verify email address. "; + if (err.errcode === 'M_THREEPID_AUTH_FAILED') { + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + let message = "Unable to verify email address. "; message += "Please check your email and click on the link it contains. Once this is done, click continue."; Modal.createDialog(QuestionDialog, { title: "Verification Pending", @@ -438,7 +437,7 @@ module.exports = React.createClass({ onFinished: this.onEmailDialogFinished, }); } else { - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Unable to verify email address: " + err); Modal.createDialog(ErrorDialog, { title: "Unable to verify email address", @@ -478,17 +477,17 @@ module.exports = React.createClass({ _onRejectAllInvitesClicked: function(rooms, ev) { this.setState({ - rejectingInvites: true + rejectingInvites: true, }); // reject the invites - let promises = rooms.map((room) => { + const promises = rooms.map((room) => { return MatrixClientPeg.get().leave(room.roomId); }); // purposefully drop errors to the floor: we'll just have a non-zero number on the UI // after trying to reject all the invites. q.allSettled(promises).then(() => { this.setState({ - rejectingInvites: false + rejectingInvites: false, }); }).done(); }, @@ -501,7 +500,7 @@ module.exports = React.createClass({ }, "e2e-export"); }, { matrixClient: MatrixClientPeg.get(), - } + }, ); }, @@ -513,7 +512,7 @@ module.exports = React.createClass({ }, "e2e-export"); }, { matrixClient: MatrixClientPeg.get(), - } + }, ); }, @@ -539,7 +538,7 @@ module.exports = React.createClass({ }, _renderUserInterfaceSettings: function() { - var client = MatrixClientPeg.get(); + // const client = MatrixClientPeg.get(); return (
@@ -558,7 +557,7 @@ module.exports = React.createClass({ UserSettingsStore.setUrlPreviewsDisabled(e.target.checked) } + onChange={ (e) => UserSettingsStore.setUrlPreviewsDisabled(e.target.checked) } />