From 6bd7af29176d952f171591b1be147f4711802b69 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 May 2017 14:00:09 +0100 Subject: [PATCH 01/14] Revert "Merge pull request #867 from matrix-org/t3chguy/BaseDialog-patch1" This reverts commit 3549ff254325cdba689b425307218e678c89a2c8, reversing changes made to 1db677141ea281ac2fba361006597768110f77a5. --- src/components/views/dialogs/BaseDialog.js | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 02460148b3..279dedbd43 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -57,25 +57,20 @@ export default React.createClass({ } }, - // Don't let key{down,press} events escape the modal. Consume them all. - _eatKeyEvent: function(e) { - e.stopPropagation(); - }, - // Must be when the key is released (and not pressed) otherwise componentWillUnmount // will focus another element which will receive future key events _onKeyUp: function(e) { if (e.keyCode === KeyCode.ESCAPE) { + e.stopPropagation(); e.preventDefault(); this.props.onFinished(); } else if (e.keyCode === KeyCode.ENTER) { if (this.props.onEnterPressed) { + e.stopPropagation(); e.preventDefault(); this.props.onEnterPressed(e); } } - // Consume all keyup events while Modal is open - e.stopPropagation(); }, _onCancelClick: function(e) { @@ -86,11 +81,7 @@ export default React.createClass({ const TintableSvg = sdk.getComponent("elements.TintableSvg"); return ( -
+
From f8d1a6d24042925692827f6ee100416a34fa516f Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 May 2017 14:26:46 +0100 Subject: [PATCH 02/14] Revert "Fix 'start chat' button" This reverts commit c841eb641b85995bddb235d3db2c779daffe97a1. --- src/components/views/elements/StartChatButton.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/StartChatButton.js b/src/components/views/elements/StartChatButton.js index 747f75d1b3..02d5677a7c 100644 --- a/src/components/views/elements/StartChatButton.js +++ b/src/components/views/elements/StartChatButton.js @@ -21,7 +21,7 @@ import PropTypes from 'prop-types'; const StartChatButton = function(props) { const ActionButton = sdk.getComponent('elements.ActionButton'); return ( - Date: Tue, 16 May 2017 14:30:02 +0100 Subject: [PATCH 03/14] Revert "Fix Create Room button" This reverts commit 9cae667c063e67b32e60b89e7256d714a056559b. --- src/components/views/elements/CreateRoomButton.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/CreateRoomButton.js b/src/components/views/elements/CreateRoomButton.js index 73c984a860..e7e526d36b 100644 --- a/src/components/views/elements/CreateRoomButton.js +++ b/src/components/views/elements/CreateRoomButton.js @@ -21,7 +21,7 @@ import PropTypes from 'prop-types'; const CreateRoomButton = function(props) { const ActionButton = sdk.getComponent('elements.ActionButton'); return ( - Date: Tue, 16 May 2017 14:49:55 +0100 Subject: [PATCH 04/14] Revert "Merge pull request #859 from matrix-org/dbkr/left_panel_for_newbies_2" This reverts commit 3366d3bbae203ce28ff85f8d7b80a6e3077a02a6, reversing changes made to ceb71a4ef65607cfcf5c50452839edb1aef40593. --- package.json | 1 - src/components/views/elements/ActionButton.js | 80 ------------ .../views/elements/CreateRoomButton.js | 38 ------ src/components/views/elements/HomeButton.js | 38 ------ .../views/elements/RoomDirectoryButton.js | 38 ------ .../views/elements/SettingsButton.js | 38 ------ .../views/elements/StartChatButton.js | 38 ------ src/components/views/rooms/RoomList.js | 121 ++++-------------- 8 files changed, 24 insertions(+), 368 deletions(-) delete mode 100644 src/components/views/elements/ActionButton.js delete mode 100644 src/components/views/elements/CreateRoomButton.js delete mode 100644 src/components/views/elements/HomeButton.js delete mode 100644 src/components/views/elements/RoomDirectoryButton.js delete mode 100644 src/components/views/elements/SettingsButton.js delete mode 100644 src/components/views/elements/StartChatButton.js diff --git a/package.json b/package.json index 21add8ccb7..3e1fa2d8f3 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,6 @@ "lodash": "^4.13.1", "matrix-js-sdk": "matrix-org/matrix-js-sdk#develop", "optimist": "^0.6.1", - "prop-types": "^15.5.8", "q": "^1.4.1", "react": "^15.4.0", "react-addons-css-transition-group": "15.3.2", diff --git a/src/components/views/elements/ActionButton.js b/src/components/views/elements/ActionButton.js deleted file mode 100644 index 267388daf6..0000000000 --- a/src/components/views/elements/ActionButton.js +++ /dev/null @@ -1,80 +0,0 @@ -/* -Copyright 2017 Vector Creations 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 AccessibleButton from './AccessibleButton'; -import dis from '../../../dispatcher'; -import sdk from '../../../index'; - -export default React.createClass({ - displayName: 'RoleButton', - - propTypes: { - size: PropTypes.string, - tooltip: PropTypes.bool, - action: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - iconPath: PropTypes.string.isRequired, - }, - - getDefaultProps: function() { - return { - size: "25", - tooltip: false, - }; - }, - - getInitialState: function() { - return { - showTooltip: false, - }; - }, - - _onClick: function(ev) { - ev.stopPropagation(); - dis.dispatch({action: this.props.action}); - }, - - _onMouseEnter: function() { - if (this.props.tooltip) this.setState({showTooltip: true}); - }, - - _onMouseLeave: function() { - this.setState({showTooltip: false}); - }, - - render: function() { - const TintableSvg = sdk.getComponent("elements.TintableSvg"); - - let tooltip; - if (this.state.showTooltip) { - const RoomTooltip = sdk.getComponent("rooms.RoomTooltip"); - tooltip = ; - } - - return ( - - - {tooltip} - - ); - } -}); diff --git a/src/components/views/elements/CreateRoomButton.js b/src/components/views/elements/CreateRoomButton.js deleted file mode 100644 index e7e526d36b..0000000000 --- a/src/components/views/elements/CreateRoomButton.js +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright 2017 Vector Creations 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 sdk from '../../../index'; -import PropTypes from 'prop-types'; - -const CreateRoomButton = function(props) { - const ActionButton = sdk.getComponent('elements.ActionButton'); - return ( - - ); -}; - -CreateRoomButton.propTypes = { - size: PropTypes.string, - tooltip: PropTypes.bool, -}; - -export default CreateRoomButton; diff --git a/src/components/views/elements/HomeButton.js b/src/components/views/elements/HomeButton.js deleted file mode 100644 index 5c446f24c9..0000000000 --- a/src/components/views/elements/HomeButton.js +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright 2017 Vector Creations 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 sdk from '../../../index'; -import PropTypes from 'prop-types'; - -const HomeButton = function(props) { - const ActionButton = sdk.getComponent('elements.ActionButton'); - return ( - - ); -}; - -HomeButton.propTypes = { - size: PropTypes.string, - tooltip: PropTypes.bool, -}; - -export default HomeButton; diff --git a/src/components/views/elements/RoomDirectoryButton.js b/src/components/views/elements/RoomDirectoryButton.js deleted file mode 100644 index 5e68776a15..0000000000 --- a/src/components/views/elements/RoomDirectoryButton.js +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright 2017 Vector Creations 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 sdk from '../../../index'; -import PropTypes from 'prop-types'; - -const RoomDirectoryButton = function(props) { - const ActionButton = sdk.getComponent('elements.ActionButton'); - return ( - - ); -}; - -RoomDirectoryButton.propTypes = { - size: PropTypes.string, - tooltip: PropTypes.bool, -}; - -export default RoomDirectoryButton; diff --git a/src/components/views/elements/SettingsButton.js b/src/components/views/elements/SettingsButton.js deleted file mode 100644 index c6438da277..0000000000 --- a/src/components/views/elements/SettingsButton.js +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright 2017 Vector Creations 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 sdk from '../../../index'; -import PropTypes from 'prop-types'; - -const SettingsButton = function(props) { - const ActionButton = sdk.getComponent('elements.ActionButton'); - return ( - - ); -}; - -SettingsButton.propTypes = { - size: PropTypes.string, - tooltip: PropTypes.bool, -}; - -export default SettingsButton; diff --git a/src/components/views/elements/StartChatButton.js b/src/components/views/elements/StartChatButton.js deleted file mode 100644 index 02d5677a7c..0000000000 --- a/src/components/views/elements/StartChatButton.js +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright 2017 Vector Creations 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 sdk from '../../../index'; -import PropTypes from 'prop-types'; - -const StartChatButton = function(props) { - const ActionButton = sdk.getComponent('elements.ActionButton'); - return ( - - ); -}; - -StartChatButton.propTypes = { - size: PropTypes.string, - tooltip: PropTypes.bool, -}; - -export default StartChatButton; diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index a595a91ba9..49af1560f1 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -1,6 +1,5 @@ /* Copyright 2015, 2016 OpenMarket Ltd -Copyright 2017 Vector Creations Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -29,16 +28,8 @@ var Rooms = require('../../../Rooms'); import DMRoomMap from '../../../utils/DMRoomMap'; var Receipt = require('../../../utils/Receipt'); var constantTimeDispatcher = require('../../../ConstantTimeDispatcher'); -import AccessibleButton from '../elements/AccessibleButton'; -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', -}; +var HIDE_CONFERENCE_CHANS = true; module.exports = React.createClass({ displayName: 'RoomList', @@ -62,7 +53,6 @@ module.exports = React.createClass({ getInitialState: function() { return { isLoadingLeftRooms: false, - totalRoomCount: null, lists: {}, incomingCall: null, }; @@ -83,7 +73,8 @@ module.exports = React.createClass({ // lookup for which lists a given roomId is currently in. this.listsForRoomId = {}; - this.refreshRoomList(); + var s = this.getRoomLists(); + this.setState(s); // order of the sublists //this.listOrder = []; @@ -326,29 +317,21 @@ 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. - 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.setState(this.getRoomLists()); + // this._lastRefreshRoomListTs = Date.now(); }, getRoomLists: function() { var self = this; - const lists = {}; + var s = { lists: {} }; - 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"] = []; + 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"] = []; this.listsForRoomId = {}; var otherTagNames = {}; @@ -370,7 +353,7 @@ module.exports = React.createClass({ if (me.membership == "invite") { self.listsForRoomId[room.roomId].push("im.vector.fake.invite"); - lists["im.vector.fake.invite"].push(room); + s.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 @@ -383,8 +366,8 @@ module.exports = React.createClass({ if (tagNames.length) { for (var i = 0; i < tagNames.length; i++) { var tagName = tagNames[i]; - lists[tagName] = lists[tagName] || []; - lists[tagName].push(room); + s.lists[tagName] = s.lists[tagName] || []; + s.lists[tagName].push(room); self.listsForRoomId[room.roomId].push(tagName); otherTagNames[tagName] = 1; } @@ -392,16 +375,16 @@ 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"); - lists["im.vector.fake.direct"].push(room); + s.lists["im.vector.fake.direct"].push(room); } else { self.listsForRoomId[room.roomId].push("im.vector.fake.recent"); - lists["im.vector.fake.recent"].push(room); + s.lists["im.vector.fake.recent"].push(room); } } else if (me.membership === "leave") { self.listsForRoomId[room.roomId].push("im.vector.fake.archived"); - lists["im.vector.fake.archived"].push(room); + s.lists["im.vector.fake.archived"].push(room); } else { console.error("unrecognised membership: " + me.membership + " - this should never happen"); @@ -425,7 +408,7 @@ module.exports = React.createClass({ ]; */ - return lists; + return s; }, _getScrollNode: function() { @@ -455,7 +438,6 @@ 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; @@ -479,7 +461,6 @@ 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; @@ -577,58 +558,6 @@ module.exports = React.createClass({ this.refs.gemscroll.forceUpdate(); }, - _getEmptyContent: function(section) { - const RoomDropTarget = sdk.getComponent('rooms.RoomDropTarget'); - - if (this.props.collapsed) { - return ; - } - - const StartChatButton = sdk.getComponent('elements.StartChatButton'); - const RoomDirectoryButton = sdk.getComponent('elements.RoomDirectoryButton'); - const CreateRoomButton = sdk.getComponent('elements.CreateRoomButton'); - if (this.state.totalRoomCount === 0) { - const TintableSvg = sdk.getComponent('elements.TintableSvg'); - switch (section) { - case 'im.vector.fake.direct': - return
- Press - - to start a chat with someone -
; - case 'im.vector.fake.recent': - return
- You're not in any rooms yet! Press - - to make a room or - - to browse the directory -
; - } - } - - const labelText = 'Drop here to ' + (VERBS[section] || 'tag ' + section); - - return ; - }, - - _getHeaderItems: function(section) { - const StartChatButton = sdk.getComponent('elements.StartChatButton'); - const RoomDirectoryButton = sdk.getComponent('elements.RoomDirectoryButton'); - const CreateRoomButton = sdk.getComponent('elements.CreateRoomButton'); - switch (section) { - case 'im.vector.fake.direct': - return - - ; - case 'im.vector.fake.recent': - return - - - ; - } - }, - render: function() { var RoomSubList = sdk.getComponent('structures.RoomSubList'); var self = this; @@ -652,7 +581,7 @@ module.exports = React.createClass({ Date: Tue, 16 May 2017 14:50:19 +0100 Subject: [PATCH 05/14] Revert "Merge pull request #841 from matrix-org/luke/fix-double-dialogs" This reverts commit 1913a32fbd0c303080645f2661cacff25ccff232, reversing changes made to 0c16298c452089188bcc156cf213358988ce7341. --- src/components/views/dialogs/BaseDialog.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index 279dedbd43..d0f34c5fbd 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -57,9 +57,7 @@ export default React.createClass({ } }, - // Must be when the key is released (and not pressed) otherwise componentWillUnmount - // will focus another element which will receive future key events - _onKeyUp: function(e) { + _onKeyDown: function(e) { if (e.keyCode === KeyCode.ESCAPE) { e.stopPropagation(); e.preventDefault(); @@ -81,7 +79,7 @@ export default React.createClass({ const TintableSvg = sdk.getComponent("elements.TintableSvg"); return ( -
+
From ff9c40472a5b1f52450347a890ea720c78e1aa39 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 May 2017 14:50:29 +0100 Subject: [PATCH 06/14] Revert "Merge pull request #822 from t3chguy/BaseDialog_restore_focus" This reverts commit 0ac836919d54cd04705002d8e53d3514dcce8dde, reversing changes made to 7e07ffd55fe1475ce30e172fa5b0b37061e7375f. --- src/components/views/dialogs/BaseDialog.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js index d0f34c5fbd..0b2ca5225d 100644 --- a/src/components/views/dialogs/BaseDialog.js +++ b/src/components/views/dialogs/BaseDialog.js @@ -47,16 +47,6 @@ export default React.createClass({ children: React.PropTypes.node, }, - componentWillMount: function() { - this.priorActiveElement = document.activeElement; - }, - - componentWillUnmount: function() { - if (this.priorActiveElement !== null) { - this.priorActiveElement.focus(); - } - }, - _onKeyDown: function(e) { if (e.keyCode === KeyCode.ESCAPE) { e.stopPropagation(); @@ -77,7 +67,7 @@ export default React.createClass({ render: function() { const TintableSvg = sdk.getComponent("elements.TintableSvg"); - + return (
Date: Tue, 16 May 2017 15:35:22 +0100 Subject: [PATCH 07/14] Revert "comment out spammy CTD logging" This reverts commit 19482d751d82c162321d99c5bf95ac8fe950768b. --- src/ConstantTimeDispatcher.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ConstantTimeDispatcher.js b/src/ConstantTimeDispatcher.js index 6c2c3266aa..265ee11fd4 100644 --- a/src/ConstantTimeDispatcher.js +++ b/src/ConstantTimeDispatcher.js @@ -47,7 +47,7 @@ class ConstantTimeDispatcher { dispatch(type, arg, params) { if (!this.listeners[type] || !this.listeners[type][arg]) { - //console.warn("No registered listeners for dispatch (type=" + type + ", arg=" + arg + ")"); + console.warn("No registered listeners for dispatch (type=" + type + ", arg=" + arg + ")"); return; } this.listeners[type][arg].forEach(listener=>{ From 714cd6a10fd49df86caa9df4406e7a31cc7bfea1 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 May 2017 16:00:34 +0100 Subject: [PATCH 08/14] Revert "recalculate roomlist when your invites change" This reverts commit ec6a1c4c750f959017cdf823402a6c9d86b16fe2. --- src/components/views/rooms/RoomList.js | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 49af1560f1..101f0838a9 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -265,16 +265,9 @@ module.exports = React.createClass({ }, onRoomStateMember: function(ev, state, member) { - if (ev.getStateKey() === MatrixClientPeg.get().credentials.userId && - ev.getPrevContent() && ev.getPrevContent().membership === "invite") - { - this._delayedRefreshRoomList(); - } - else { - constantTimeDispatcher.dispatch( - "RoomTile.refresh", member.roomId, {} - ); - } + constantTimeDispatcher.dispatch( + "RoomTile.refresh", member.roomId, {} + ); }, onRoomMemberName: function(ev, member) { From b063c605a86bdd9f216506e09bd93f54e42a29df Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 May 2017 16:01:14 +0100 Subject: [PATCH 09/14] Revert "fix stupid typos in RoomList's shouldComponentUpdate" This reverts commit b0288ebd89841ad362a6804b41839ef9d3bdca7f. --- src/components/views/rooms/RoomList.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 101f0838a9..b99d26376f 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -44,9 +44,9 @@ module.exports = React.createClass({ shouldComponentUpdate: function(nextProps, nextState) { if (nextProps.collapsed !== this.props.collapsed) return true; if (nextProps.searchFilter !== this.props.searchFilter) return true; - if (nextState.lists !== this.state.lists || - nextState.isLoadingLeftRooms !== this.state.isLoadingLeftRooms || - nextState.incomingCall !== this.state.incomingCall) return true; + if (nextState.lists !== this.props.lists || + nextState.isLoadingLeftRooms !== this.isLoadingLeftRooms || + nextState.incomingCall !== this.incomingCall) return true; return false; }, From 7a949b6a4591cdb7c5fe93b8aef610388ef8eba4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 May 2017 16:01:32 +0100 Subject: [PATCH 10/14] Revert "oops, actually refresh roomlist when its state changes!" This reverts commit 35a16edcccd07fdd4209783ce1efaee8115eb4b4. --- src/components/views/rooms/RoomList.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index b99d26376f..b4ab25a0f2 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -44,9 +44,6 @@ module.exports = React.createClass({ shouldComponentUpdate: function(nextProps, nextState) { if (nextProps.collapsed !== this.props.collapsed) return true; if (nextProps.searchFilter !== this.props.searchFilter) return true; - if (nextState.lists !== this.props.lists || - nextState.isLoadingLeftRooms !== this.isLoadingLeftRooms || - nextState.incomingCall !== this.incomingCall) return true; return false; }, From eddc2af92d7a465f755c472f3ea3da3cca3a185f Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 May 2017 16:01:54 +0100 Subject: [PATCH 11/14] Revert "HOW DID THIS EVER WORK?" This reverts commit 0d8d3c67106a3e84fd30de4016b9c852870f99b3. --- src/components/views/rooms/RoomList.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index b4ab25a0f2..b86d17d290 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -558,7 +558,6 @@ module.exports = React.createClass({
Date: Tue, 16 May 2017 16:02:13 +0100 Subject: [PATCH 12/14] Revert "unbreak stack overflow which fires on tests due to mocked timers" This reverts commit e69ea68133bb01dfd2093ffc5644edef24fbed70. --- src/components/views/rooms/RoomList.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index b86d17d290..d6e2ab633d 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -74,11 +74,7 @@ module.exports = React.createClass({ this.setState(s); // order of the sublists - //this.listOrder = []; - - // loop count to stop a stack overflow if the user keeps waggling the - // mouse for >30s in a row, or if running under mocha - this._delayedRefreshRoomListLoopCount = 0 + this.listOrder = []; }, componentDidMount: function() { @@ -288,12 +284,10 @@ module.exports = React.createClass({ // if the mouse has been moving over the RoomList in the last 500ms // then delay the refresh further to avoid bouncing around under the // cursor - if (Date.now() - this._lastMouseOverTs > 500 || this._delayedRefreshRoomListLoopCount > 60) { + if (Date.now() - this._lastMouseOverTs > 500) { this.refreshRoomList(); - this._delayedRefreshRoomListLoopCount = 0; } else { - this._delayedRefreshRoomListLoopCount++; this._delayedRefreshRoomList(); } }, 500), From ebfafb363972e77ef02f0e518573bf68ebc0ed15 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 May 2017 16:11:01 +0100 Subject: [PATCH 13/14] Revert "Merge pull request #807 from matrix-org/matthew/quick-search" This reverts commit 0ad1d8caf3f83aca517d1afff492f1c3d01e9ad5, reversing changes made to 1189368aab8cfb22c1895f8ce6c0d8a8fbe7ca0b. --- package.json | 2 +- src/ConstantTimeDispatcher.js | 62 ----- src/KeyCode.js | 1 - src/components/structures/TimelinePanel.js | 1 - .../views/dialogs/QuestionDialog.js | 8 +- src/components/views/rooms/RoomList.js | 233 ++++++------------ src/components/views/rooms/RoomTile.js | 57 ++--- 7 files changed, 99 insertions(+), 265 deletions(-) delete mode 100644 src/ConstantTimeDispatcher.js diff --git a/package.json b/package.json index 3e1fa2d8f3..444d1c5369 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "react": "^15.4.0", "react-addons-css-transition-group": "15.3.2", "react-dom": "^15.4.0", - "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#39d858c", + "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef", "sanitize-html": "^1.11.1", "text-encoding-utf-8": "^1.0.1", "velocity-vector": "vector-im/velocity#059e3b2", diff --git a/src/ConstantTimeDispatcher.js b/src/ConstantTimeDispatcher.js deleted file mode 100644 index 265ee11fd4..0000000000 --- a/src/ConstantTimeDispatcher.js +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 2017 Vector Creations 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. -*/ - -// singleton which dispatches invocations of a given type & argument -// rather than just a type (as per EventEmitter and Flux's dispatcher etc) -// -// This means you can have a single point which listens for an EventEmitter event -// and then dispatches out to one of thousands of RoomTiles (for instance) rather than -// having each RoomTile register for the EventEmitter event and having to -// iterate over all of them. -class ConstantTimeDispatcher { - constructor() { - // type -> arg -> [ listener(arg, params) ] - this.listeners = {}; - } - - register(type, arg, listener) { - if (!this.listeners[type]) this.listeners[type] = {}; - if (!this.listeners[type][arg]) this.listeners[type][arg] = []; - this.listeners[type][arg].push(listener); - } - - unregister(type, arg, listener) { - if (this.listeners[type] && this.listeners[type][arg]) { - var i = this.listeners[type][arg].indexOf(listener); - if (i > -1) { - this.listeners[type][arg].splice(i, 1); - } - } - else { - console.warn("Unregistering unrecognised listener (type=" + type + ", arg=" + arg + ")"); - } - } - - dispatch(type, arg, params) { - if (!this.listeners[type] || !this.listeners[type][arg]) { - console.warn("No registered listeners for dispatch (type=" + type + ", arg=" + arg + ")"); - return; - } - this.listeners[type][arg].forEach(listener=>{ - listener.call(arg, params); - }); - } -} - -if (!global.constantTimeDispatcher) { - global.constantTimeDispatcher = new ConstantTimeDispatcher(); -} -module.exports = global.constantTimeDispatcher; diff --git a/src/KeyCode.js b/src/KeyCode.js index f164dbc15c..c9cac01239 100644 --- a/src/KeyCode.js +++ b/src/KeyCode.js @@ -32,5 +32,4 @@ module.exports = { DELETE: 46, KEY_D: 68, KEY_E: 69, - KEY_K: 75, }; diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index de43bd1c19..8794713501 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -590,7 +590,6 @@ var TimelinePanel = React.createClass({ this.props.timelineSet.room.setUnreadNotificationCount('highlight', 0); dis.dispatch({ action: 'on_room_read', - room: this.props.timelineSet.room, }); } } diff --git a/src/components/views/dialogs/QuestionDialog.js b/src/components/views/dialogs/QuestionDialog.js index 8e20b0d2bc..6012541b94 100644 --- a/src/components/views/dialogs/QuestionDialog.js +++ b/src/components/views/dialogs/QuestionDialog.js @@ -47,12 +47,6 @@ export default React.createClass({ this.props.onFinished(false); }, - componentDidMount: function() { - if (this.props.focus) { - this.refs.button.focus(); - } - }, - render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const cancelButton = this.props.hasCancelButton ? ( @@ -69,7 +63,7 @@ export default React.createClass({ {this.props.description}
- {this.props.extraButtons} diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index d6e2ab633d..611dd10780 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -21,13 +21,13 @@ var GeminiScrollbar = require('react-gemini-scrollbar'); var MatrixClientPeg = require("../../../MatrixClientPeg"); var CallHandler = require('../../../CallHandler'); var RoomListSorter = require("../../../RoomListSorter"); +var Unread = require('../../../Unread'); var dis = require("../../../dispatcher"); var sdk = require('../../../index'); var rate_limited_func = require('../../../ratelimitedfunc'); var Rooms = require('../../../Rooms'); import DMRoomMap from '../../../utils/DMRoomMap'; var Receipt = require('../../../utils/Receipt'); -var constantTimeDispatcher = require('../../../ConstantTimeDispatcher'); var HIDE_CONFERENCE_CHANS = true; @@ -37,16 +37,10 @@ module.exports = React.createClass({ propTypes: { ConferenceHandler: React.PropTypes.any, collapsed: React.PropTypes.bool.isRequired, - selectedRoom: React.PropTypes.string, + currentRoom: React.PropTypes.string, searchFilter: React.PropTypes.string, }, - shouldComponentUpdate: function(nextProps, nextState) { - if (nextProps.collapsed !== this.props.collapsed) return true; - if (nextProps.searchFilter !== this.props.searchFilter) return true; - return false; - }, - getInitialState: function() { return { isLoadingLeftRooms: false, @@ -63,18 +57,12 @@ module.exports = React.createClass({ cli.on("Room.name", this.onRoomName); cli.on("Room.tags", this.onRoomTags); cli.on("Room.receipt", this.onRoomReceipt); - cli.on("RoomState.members", this.onRoomStateMember); + cli.on("RoomState.events", this.onRoomStateEvents); cli.on("RoomMember.name", this.onRoomMemberName); cli.on("accountData", this.onAccountData); - // lookup for which lists a given roomId is currently in. - this.listsForRoomId = {}; - var s = this.getRoomLists(); this.setState(s); - - // order of the sublists - this.listOrder = []; }, componentDidMount: function() { @@ -83,22 +71,7 @@ module.exports = React.createClass({ this._updateStickyHeaders(true); }, - componentWillReceiveProps: function(nextProps) { - // short-circuit react when the room changes - // to avoid rerendering all the sublists everywhere - if (nextProps.selectedRoom !== this.props.selectedRoom) { - if (this.props.selectedRoom) { - constantTimeDispatcher.dispatch( - "RoomTile.select", this.props.selectedRoom, {} - ); - } - constantTimeDispatcher.dispatch( - "RoomTile.select", nextProps.selectedRoom, { selected: true } - ); - } - }, - - componentDidUpdate: function(prevProps, prevState) { + componentDidUpdate: function() { // Reinitialise the stickyHeaders when the component is updated this._updateStickyHeaders(true); this._repositionIncomingCallBox(undefined, false); @@ -124,24 +97,10 @@ module.exports = React.createClass({ } break; case 'on_room_read': - // poke the right RoomTile to refresh, using the constantTimeDispatcher - // to avoid each and every RoomTile registering to the 'on_room_read' event - // XXX: if we like the constantTimeDispatcher we might want to dispatch - // directly from TimelinePanel rather than needlessly bouncing via here. - constantTimeDispatcher.dispatch( - "RoomTile.refresh", payload.room.roomId, {} - ); - - // also have to poke the right list(s) - var lists = this.listsForRoomId[payload.room.roomId]; - if (lists) { - lists.forEach(list=>{ - constantTimeDispatcher.dispatch( - "RoomSubList.refreshHeader", list, { room: payload.room } - ); - }); - } - + // Force an update because the notif count state is too deep to cause + // an update. This forces the local echo of reading notifs to be + // reflected by the RoomTiles. + this.forceUpdate(); break; } }, @@ -155,7 +114,7 @@ module.exports = React.createClass({ MatrixClientPeg.get().removeListener("Room.name", this.onRoomName); MatrixClientPeg.get().removeListener("Room.tags", this.onRoomTags); MatrixClientPeg.get().removeListener("Room.receipt", this.onRoomReceipt); - MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember); + MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents); MatrixClientPeg.get().removeListener("RoomMember.name", this.onRoomMemberName); MatrixClientPeg.get().removeListener("accountData", this.onAccountData); } @@ -164,14 +123,10 @@ module.exports = React.createClass({ }, onRoom: function(room) { - // XXX: this happens rarely; ideally we should only update the correct - // sublists when it does (e.g. via a constantTimeDispatch to the right sublist) this._delayedRefreshRoomList(); }, onDeleteRoom: function(roomId) { - // XXX: this happens rarely; ideally we should only update the correct - // sublists when it does (e.g. via a constantTimeDispatch to the right sublist) this._delayedRefreshRoomList(); }, @@ -194,10 +149,6 @@ module.exports = React.createClass({ } }, - _onMouseOver: function(ev) { - this._lastMouseOverTs = Date.now(); - }, - onSubListHeaderClick: function(isHidden, scrollToPosition) { // The scroll area has expanded or contracted, so re-calculate sticky headers positions this._updateStickyHeaders(true, scrollToPosition); @@ -207,89 +158,41 @@ module.exports = React.createClass({ if (toStartOfTimeline) return; if (!room) return; if (data.timeline.getTimelineSet() !== room.getUnfilteredTimelineSet()) return; - - // rather than regenerate our full roomlists, which is very heavy, we poke the - // correct sublists to just re-sort themselves. This isn't enormously reacty, - // but is much faster than the default react reconciler, or having to do voodoo - // with shouldComponentUpdate and a pleaseRefresh property or similar. - var lists = this.listsForRoomId[room.roomId]; - if (lists) { - lists.forEach(list=>{ - constantTimeDispatcher.dispatch("RoomSubList.sort", list, { room: room }); - }); - } - - // we have to explicitly hit the roomtile which just changed - constantTimeDispatcher.dispatch( - "RoomTile.refresh", room.roomId, {} - ); + this._delayedRefreshRoomList(); }, onRoomReceipt: function(receiptEvent, room) { // because if we read a notification, it will affect notification count // only bother updating if there's a receipt from us if (Receipt.findReadReceiptFromUserId(receiptEvent, MatrixClientPeg.get().credentials.userId)) { - var lists = this.listsForRoomId[room.roomId]; - if (lists) { - lists.forEach(list=>{ - constantTimeDispatcher.dispatch( - "RoomSubList.refreshHeader", list, { room: room } - ); - }); - } - - // we have to explicitly hit the roomtile which just changed - constantTimeDispatcher.dispatch( - "RoomTile.refresh", room.roomId, {} - ); + this._delayedRefreshRoomList(); } }, onRoomName: function(room) { - constantTimeDispatcher.dispatch( - "RoomTile.refresh", room.roomId, {} - ); - }, - - onRoomTags: function(event, room) { - // XXX: this happens rarely; ideally we should only update the correct - // sublists when it does (e.g. via a constantTimeDispatch to the right sublist) this._delayedRefreshRoomList(); }, - onRoomStateMember: function(ev, state, member) { - constantTimeDispatcher.dispatch( - "RoomTile.refresh", member.roomId, {} - ); + onRoomTags: function(event, room) { + this._delayedRefreshRoomList(); + }, + + onRoomStateEvents: function(ev, state) { + this._delayedRefreshRoomList(); }, onRoomMemberName: function(ev, member) { - constantTimeDispatcher.dispatch( - "RoomTile.refresh", member.roomId, {} - ); + this._delayedRefreshRoomList(); }, onAccountData: function(ev) { if (ev.getType() == 'm.direct') { - // XXX: this happens rarely; ideally we should only update the correct - // sublists when it does (e.g. via a constantTimeDispatch to the right sublist) - this._delayedRefreshRoomList(); - } - else if (ev.getType() == 'm.push_rules') { this._delayedRefreshRoomList(); } }, _delayedRefreshRoomList: new rate_limited_func(function() { - // if the mouse has been moving over the RoomList in the last 500ms - // then delay the refresh further to avoid bouncing around under the - // cursor - if (Date.now() - this._lastMouseOverTs > 500) { - this.refreshRoomList(); - } - else { - this._delayedRefreshRoomList(); - } + this.refreshRoomList(); }, 500), refreshRoomList: function() { @@ -297,10 +200,12 @@ module.exports = React.createClass({ // (!this._lastRefreshRoomListTs ? "-" : (Date.now() - this._lastRefreshRoomListTs)) // ); - // TODO: ideally we'd calculate this once at start, and then maintain - // any changes to it incrementally, updating the appropriate sublists - // as needed. - // Alternatively we'd do something magical with Immutable.js or similar. + // TODO: rather than bluntly regenerating and re-sorting everything + // every time we see any kind of room change from the JS SDK + // we could do incremental updates on our copy of the state + // based on the room which has actually changed. This would stop + // us re-rendering all the sublists every time anything changes anywhere + // in the state of the client. this.setState(this.getRoomLists()); // this._lastRefreshRoomListTs = Date.now(); @@ -317,9 +222,6 @@ module.exports = React.createClass({ s.lists["m.lowpriority"] = []; s.lists["im.vector.fake.archived"] = []; - this.listsForRoomId = {}; - var otherTagNames = {}; - const dmRoomMap = new DMRoomMap(MatrixClientPeg.get()); MatrixClientPeg.get().getRooms().forEach(function(room) { @@ -331,12 +233,7 @@ module.exports = React.createClass({ // ", target = " + me.events.member.getStateKey() + // ", prevMembership = " + me.events.member.getPrevContent().membership); - if (!self.listsForRoomId[room.roomId]) { - self.listsForRoomId[room.roomId] = []; - } - if (me.membership == "invite") { - self.listsForRoomId[room.roomId].push("im.vector.fake.invite"); s.lists["im.vector.fake.invite"].push(room); } else if (HIDE_CONFERENCE_CHANS && Rooms.isConfCallRoom(room, me, self.props.ConferenceHandler)) { @@ -347,27 +244,23 @@ module.exports = React.createClass({ { // Used to split rooms via tags var tagNames = Object.keys(room.tags); + 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); - self.listsForRoomId[room.roomId].push(tagName); - otherTagNames[tagName] = 1; + s.lists[tagNames[i]].push(room); } } 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); } else { - self.listsForRoomId[room.roomId].push("im.vector.fake.recent"); s.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); } else { @@ -375,22 +268,44 @@ module.exports = React.createClass({ } }); - // we actually apply the sorting to this when receiving the prop in RoomSubLists. + 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"] = []; - // 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", - "im.vector.fake.recent", - "im.vector.fake.direct", - Object.keys(otherTagNames).filter(tagName=>{ - return (!tagName.match(/^m\.(favourite|lowpriority)$/)); - }).sort(), - "m.lowpriority", - "im.vector.fake.archived" - ]; -*/ + for (const room of oldRecents) { + const me = room.getMember(MatrixClientPeg.get().credentials.userId); + + if (me && Rooms.looksLikeDirectMessageRoom(room, me)) { + s.lists["im.vector.fake.direct"].push(room); + } else { + 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; + } + + // 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. return s; }, @@ -548,15 +463,15 @@ module.exports = React.createClass({ return ( -
+ autoshow={true} onScroll={ self._whenScrolling } ref="gemscroll"> +
@@ -567,9 +482,9 @@ module.exports = React.createClass({ verb="favourite" editable={ true } order="manual" + selectedRoom={ self.props.selectedRoom } incomingCall={ self.state.incomingCall } collapsed={ self.props.collapsed } - selectedRoom={ self.props.selectedRoom } searchFilter={ self.props.searchFilter } onHeaderClick={ self.onSubListHeaderClick } onShowMoreRooms={ self.onShowMoreRooms } /> @@ -580,9 +495,9 @@ module.exports = React.createClass({ verb="tag direct chat" editable={ true } order="recent" + selectedRoom={ self.props.selectedRoom } incomingCall={ self.state.incomingCall } collapsed={ self.props.collapsed } - selectedRoom={ self.props.selectedRoom } alwaysShowHeader={ true } searchFilter={ self.props.searchFilter } onHeaderClick={ self.onSubListHeaderClick } @@ -593,14 +508,14 @@ module.exports = React.createClass({ editable={ true } verb="restore" order="recent" + selectedRoom={ self.props.selectedRoom } incomingCall={ self.state.incomingCall } collapsed={ self.props.collapsed } - selectedRoom={ self.props.selectedRoom } searchFilter={ self.props.searchFilter } onHeaderClick={ self.onSubListHeaderClick } onShowMoreRooms={ self.onShowMoreRooms } /> - { Object.keys(self.state.lists).sort().map(function(tagName) { + { Object.keys(self.state.lists).map(function(tagName) { if (!tagName.match(/^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { return ; @@ -625,9 +540,9 @@ module.exports = React.createClass({ verb="demote" editable={ true } order="recent" + selectedRoom={ self.props.selectedRoom } incomingCall={ self.state.incomingCall } collapsed={ self.props.collapsed } - selectedRoom={ self.props.selectedRoom } searchFilter={ self.props.searchFilter } onHeaderClick={ self.onSubListHeaderClick } onShowMoreRooms={ self.onShowMoreRooms } /> @@ -636,8 +551,8 @@ module.exports = React.createClass({ label="Historical" editable={ false } order="recent" - collapsed={ self.props.collapsed } selectedRoom={ self.props.selectedRoom } + collapsed={ self.props.collapsed } alwaysShowHeader={ true } startAsHidden={ true } showSpinner={ self.state.isLoadingLeftRooms } diff --git a/src/components/views/rooms/RoomTile.js b/src/components/views/rooms/RoomTile.js index 3b37d4608f..c123f31d19 100644 --- a/src/components/views/rooms/RoomTile.js +++ b/src/components/views/rooms/RoomTile.js @@ -27,8 +27,6 @@ var RoomNotifs = require('../../../RoomNotifs'); var FormattingUtils = require('../../../utils/FormattingUtils'); import AccessibleButton from '../elements/AccessibleButton'; var UserSettingsStore = require('../../../UserSettingsStore'); -var constantTimeDispatcher = require('../../../ConstantTimeDispatcher'); -var Unread = require('../../../Unread'); module.exports = React.createClass({ displayName: 'RoomTile', @@ -38,10 +36,12 @@ module.exports = React.createClass({ connectDropTarget: React.PropTypes.func, onClick: React.PropTypes.func, isDragging: React.PropTypes.bool, - selectedRoom: React.PropTypes.string, room: React.PropTypes.object.isRequired, collapsed: React.PropTypes.bool.isRequired, + selected: React.PropTypes.bool.isRequired, + unread: React.PropTypes.bool.isRequired, + highlight: React.PropTypes.bool.isRequired, isInvite: React.PropTypes.bool.isRequired, incomingCall: React.PropTypes.object, }, @@ -54,11 +54,10 @@ module.exports = React.createClass({ getInitialState: function() { return({ - hover: false, - badgeHover: false, + hover : false, + badgeHover : false, menuDisplayed: false, notifState: RoomNotifs.getRoomNotifsState(this.props.room.roomId), - selected: this.props.room ? (this.props.selectedRoom === this.props.room.roomId) : false, }); }, @@ -80,32 +79,23 @@ module.exports = React.createClass({ } }, + onAccountData: function(accountDataEvent) { + if (accountDataEvent.getType() == 'm.push_rules') { + this.setState({ + notifState: RoomNotifs.getRoomNotifsState(this.props.room.roomId), + }); + } + }, + componentWillMount: function() { - constantTimeDispatcher.register("RoomTile.refresh", this.props.room.roomId, this.onRefresh); - constantTimeDispatcher.register("RoomTile.select", this.props.room.roomId, this.onSelect); - this.onRefresh(); + MatrixClientPeg.get().on("accountData", this.onAccountData); }, componentWillUnmount: function() { - constantTimeDispatcher.unregister("RoomTile.refresh", this.props.room.roomId, this.onRefresh); - constantTimeDispatcher.unregister("RoomTile.select", this.props.room.roomId, this.onSelect); - }, - - componentWillReceiveProps: function(nextProps) { - this.onRefresh(); - }, - - onRefresh: function(params) { - this.setState({ - unread: Unread.doesRoomHaveUnreadMessages(this.props.room), - highlight: this.props.room.getUnreadNotificationCount('highlight') > 0 || this.props.isInvite, - }); - }, - - onSelect: function(params) { - this.setState({ - selected: params.selected, - }); + var cli = MatrixClientPeg.get(); + if (cli) { + MatrixClientPeg.get().removeListener("accountData", this.onAccountData); + } }, onClick: function(ev) { @@ -179,13 +169,13 @@ module.exports = React.createClass({ // var highlightCount = this.props.room.getUnreadNotificationCount("highlight"); const notifBadges = notificationCount > 0 && this._shouldShowNotifBadge(); - const mentionBadges = this.state.highlight && this._shouldShowMentionBadge(); + const mentionBadges = this.props.highlight && this._shouldShowMentionBadge(); const badges = notifBadges || mentionBadges; var classes = classNames({ 'mx_RoomTile': true, - 'mx_RoomTile_selected': this.state.selected, - 'mx_RoomTile_unread': this.state.unread, + 'mx_RoomTile_selected': this.props.selected, + 'mx_RoomTile_unread': this.props.unread, 'mx_RoomTile_unreadNotify': notifBadges, 'mx_RoomTile_highlight': mentionBadges, 'mx_RoomTile_invited': (me && me.membership == 'invite'), @@ -231,7 +221,7 @@ module.exports = React.createClass({ 'mx_RoomTile_badgeShown': badges || this.state.badgeHover || this.state.menuDisplayed, }); - if (this.state.selected) { + if (this.props.selected) { let nameSelected = {name}; label =
{ nameSelected }
; @@ -265,8 +255,7 @@ module.exports = React.createClass({ let ret = (
{ /* Only native elements can be wrapped in a DnD object. */} - +
From 75eea89c08354caf2f65e9bbeb60a572830c21c2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 16 May 2017 16:12:57 +0100 Subject: [PATCH 14/14] Revert "Merge pull request #765 from t3chguy/t3chguy/escape-closes-user-settings" This reverts commit a29d8c2af200af9bd5f55da60a10d1fc9c473764, reversing changes made to 1d836c7d02a6935313bfb05d94fc38ae05439480. --- src/components/structures/LoggedInView.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index c4eeb03d5f..25ca025a23 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -107,18 +107,6 @@ export default React.createClass({ var handled = false; switch (ev.keyCode) { - case KeyCode.ESCAPE: - - // Implemented this way so possible handling for other pages is neater - switch (this.props.page_type) { - case PageTypes.UserSettings: - this.props.onUserSettingsClose(); - handled = true; - break; - } - - break; - case KeyCode.UP: case KeyCode.DOWN: if (ev.altKey && !ev.shiftKey && !ev.ctrlKey && !ev.metaKey) {