From 8c30d05eb8eef1361d226dbe2af3f03fa9e6060c Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 17 Jan 2019 10:29:37 +0100 Subject: [PATCH] Revert "Merge pull request #2348 from matrix-org/bwindels/roomgridview-experimental" This reverts commit ece5cb1fcc78589442eb549f234b60254bb8d038, reversing changes made to 64a3d2521c4e29c785e56a38a8f102993da9ad4f. --- res/css/_components.scss | 1 - res/css/structures/_GroupGridView.scss | 130 -------- res/css/structures/_MatrixChat.scss | 3 +- res/css/views/rooms/_MemberList.scss | 4 - res/img/feather-icons/toggle-right-panel.svg | 17 -- res/themes/dark/css/_dark.scss | 4 - res/themes/dharma/css/_dharma.scss | 3 - res/themes/light/css/_base.scss | 4 - src/ActiveRoomObserver.js | 30 +- src/PageTypes.js | 1 - src/UserActivity.js | 1 - src/components/structures/GroupGridView.js | 127 -------- src/components/structures/LoggedInView.js | 13 +- src/components/structures/MainSplit.js | 11 +- src/components/structures/MatrixChat.js | 12 - src/components/structures/RightPanel.js | 2 +- src/components/structures/RoomView.js | 100 +++---- .../views/context_menus/TagTileContextMenu.js | 23 -- .../views/right_panel/HeaderButtons.js | 1 + src/components/views/rooms/MemberInfo.js | 4 +- src/components/views/rooms/MessageComposer.js | 25 +- .../views/rooms/MessageComposerInput.js | 54 ++-- src/components/views/rooms/ReplyPreview.js | 5 +- src/components/views/rooms/RoomHeader.js | 23 +- src/components/views/rooms/RoomTile.js | 7 +- src/dispatcher.js | 36 ++- src/matrix-dispatcher.js | 53 ---- src/settings/Settings.js | 6 - src/stores/OpenRoomsStore.js | 277 ------------------ src/stores/RoomViewStore.js | 52 +++- src/utils/Timer.js | 4 +- 31 files changed, 187 insertions(+), 846 deletions(-) delete mode 100644 res/css/structures/_GroupGridView.scss delete mode 100644 res/img/feather-icons/toggle-right-panel.svg delete mode 100644 src/components/structures/GroupGridView.js delete mode 100644 src/matrix-dispatcher.js delete mode 100644 src/stores/OpenRoomsStore.js diff --git a/res/css/_components.scss b/res/css/_components.scss index 1e2d7ae156..8f6f4d5936 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -5,7 +5,6 @@ @import "./structures/_ContextualMenu.scss"; @import "./structures/_CreateRoom.scss"; @import "./structures/_FilePanel.scss"; -@import "./structures/_GroupGridView.scss"; @import "./structures/_GroupView.scss"; @import "./structures/_HomePage.scss"; @import "./structures/_LeftPanel.scss"; diff --git a/res/css/structures/_GroupGridView.scss b/res/css/structures/_GroupGridView.scss deleted file mode 100644 index 541052175d..0000000000 --- a/res/css/structures/_GroupGridView.scss +++ /dev/null @@ -1,130 +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. -*/ - -.mx_GroupGridView { - display: flex; - flex-direction: column; -} - -.mx_GroupGridView_rooms { - display: grid; - grid-template-columns: repeat(3, calc(100% / 3)); - grid-template-rows: repeat(2, calc(100% / 2)); - flex: 1 1 0; - min-width: 0; -} - -.mx_GroupGridView_rightPanel { - display: flex; - flex-direction: column; - - .mx_GroupGridView_tabs { - flex: 0 0 52px; - border-bottom: 1px solid $primary-hairline-color; - display: flex; - align-items: center; - - > div { - justify-content: flex-end; - width: 100%; - margin-right: 10px; - } - } - - .mx_RightPanel { - flex: 1 0 auto !important; - } -} - - -.mx_GroupGridView > .mx_MainSplit { - flex: 1 1 0; - display: flex; -} - -.mx_GroupGridView_emptyTile { - display: block; - margin-top: 100px; - text-align: center; - user-select: none; -} - -.mx_GroupGridView_tile { - border-right: 1px solid $panel-divider-color; - border-bottom: 1px solid $panel-divider-color; -} - -.mx_GroupGridView_activeTile { - position: relative; -} - -.mx_GroupGridView_activeTile:before, -.mx_GroupGridView_activeTile:after { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - content: ""; - pointer-events: none; - z-index: 3500; -} - -.mx_GroupGridView_activeTile:before { - border-radius: 14px; - border: 8px solid $gridview-focus-border-glow-color; - margin: -8px; -} - -.mx_GroupGridView_activeTile:after { - border-radius: 8px; - border: 2px solid $gridview-focus-border-color; - margin: -2px; -} - -.mx_GroupGridView_tile > .mx_RoomView { - height: 100%; -} - -.mx_GroupGridView_rooms > *:nth-child(1) { - grid-column: 1; - grid-row: 1; -} - -.mx_GroupGridView_rooms > *:nth-child(2) { - grid-column: 2; - grid-row: 1; -} - -.mx_GroupGridView_rooms > *:nth-child(3) { - grid-column: 3; - grid-row: 1; -} - -.mx_GroupGridView_rooms > *:nth-child(4) { - grid-column: 1; - grid-row: 2; -} - -.mx_GroupGridView_rooms > *:nth-child(5) { - grid-column: 2; - grid-row: 2; -} - -.mx_GroupGridView_rooms > *:nth-child(6) { - grid-column: 3; - grid-row: 2; -} diff --git a/res/css/structures/_MatrixChat.scss b/res/css/structures/_MatrixChat.scss index 6d8b79ecb2..f2ce7e1d5c 100644 --- a/res/css/structures/_MatrixChat.scss +++ b/res/css/structures/_MatrixChat.scss @@ -81,8 +81,7 @@ limitations under the License. Empirically this stops the MessagePanel's width exploding outwards when gemini is in 'prevented' mode */ - // disabling this for now as it clips the active room rect on the grid view - // overflow-x: auto; + overflow-x: auto; /* To fix https://github.com/vector-im/riot-web/issues/3298 where Safari needed height 100% all the way down to the HomePage. Height does not diff --git a/res/css/views/rooms/_MemberList.scss b/res/css/views/rooms/_MemberList.scss index 567727fb64..6f9491b22f 100644 --- a/res/css/views/rooms/_MemberList.scss +++ b/res/css/views/rooms/_MemberList.scss @@ -53,10 +53,6 @@ limitations under the License. .mx_MemberList_query, .mx_GroupMemberList_query, .mx_GroupRoomList_query { - flex: 0 0 auto; -} - -.mx_MemberList .gm-scrollbar-container { flex: 1 1 0; } diff --git a/res/img/feather-icons/toggle-right-panel.svg b/res/img/feather-icons/toggle-right-panel.svg deleted file mode 100644 index 4cadf89564..0000000000 --- a/res/img/feather-icons/toggle-right-panel.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - Group 2 - Created with Sketch. - - - - - - - - - - - - \ No newline at end of file diff --git a/res/themes/dark/css/_dark.scss b/res/themes/dark/css/_dark.scss index 257b723ccf..997a74e6aa 100644 --- a/res/themes/dark/css/_dark.scss +++ b/res/themes/dark/css/_dark.scss @@ -162,10 +162,6 @@ $lightbox-bg-color: #454545; $lightbox-fg-color: #ffffff; $lightbox-border-color: #ffffff; -/*** GroupGridView ***/ -$gridview-focus-border-glow-color: rgba(134, 193, 165, 0.5); -$gridview-focus-border-color: rgba(134, 193, 165, 1); - $imagebody-giflabel: rgba(1, 1, 1, 0.7); $imagebody-giflabel-border: rgba(1, 1, 1, 0.2); $imagebody-giflabel-color: rgba(0, 0, 0, 1); diff --git a/res/themes/dharma/css/_dharma.scss b/res/themes/dharma/css/_dharma.scss index 73dc0a71e4..c70d7f020a 100644 --- a/res/themes/dharma/css/_dharma.scss +++ b/res/themes/dharma/css/_dharma.scss @@ -184,9 +184,6 @@ $lightbox-bg-color: #454545; $lightbox-fg-color: #ffffff; $lightbox-border-color: #ffffff; -/*** GroupGridView ***/ -$gridview-focus-border-glow-color: rgba(134, 193, 165, 0.5); -$gridview-focus-border-color: rgba(134, 193, 165, 1); // unused? $progressbar-color: #000; diff --git a/res/themes/light/css/_base.scss b/res/themes/light/css/_base.scss index cf539bd1f2..96c179f6f5 100644 --- a/res/themes/light/css/_base.scss +++ b/res/themes/light/css/_base.scss @@ -175,10 +175,6 @@ $lightbox-bg-color: #454545; $lightbox-fg-color: #ffffff; $lightbox-border-color: #ffffff; -/*** GroupGridView ***/ -$gridview-focus-border-glow-color: rgba(134, 193, 165, 0.5); -$gridview-focus-border-color: rgba(134, 193, 165, 1); - $imagebody-giflabel: rgba(0, 0, 0, 0.7); $imagebody-giflabel-border: rgba(0, 0, 0, 0.2); $imagebody-giflabel-color: rgba(255, 255, 255, 1); diff --git a/src/ActiveRoomObserver.js b/src/ActiveRoomObserver.js index c276cccb5d..d6fbb460b5 100644 --- a/src/ActiveRoomObserver.js +++ b/src/ActiveRoomObserver.js @@ -14,10 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -import OpenRoomsStore from './stores/OpenRoomsStore'; +import RoomViewStore from './stores/RoomViewStore'; /** - * Consumes changes from the OpenRoomsStore and notifies specific things + * Consumes changes from the RoomViewStore and notifies specific things * about when the active room changes. Unlike listening for RoomViewStore * changes, you can subscribe to only changes relevant to a particular * room. @@ -28,15 +28,11 @@ import OpenRoomsStore from './stores/OpenRoomsStore'; class ActiveRoomObserver { constructor() { this._listeners = {}; - const roomStore = OpenRoomsStore.getActiveRoomStore(); - this._activeRoomId = roomStore && roomStore.getRoomId(); + + this._activeRoomId = RoomViewStore.getRoomId(); // TODO: We could self-destruct when the last listener goes away, or at least // stop listening. - this._roomStoreToken = OpenRoomsStore.addListener(this._onOpenRoomsStoreUpdate.bind(this)); - } - - getActiveRoomId() { - return this._activeRoomId; + this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate.bind(this)); } addListener(roomId, listener) { @@ -55,23 +51,23 @@ class ActiveRoomObserver { } } - _emit(roomId, newActiveRoomId) { + _emit(roomId) { if (!this._listeners[roomId]) return; for (const l of this._listeners[roomId]) { - l.call(l, newActiveRoomId); + l.call(); } } - _onOpenRoomsStoreUpdate() { - const activeRoomStore = OpenRoomsStore.getActiveRoomStore(); - const newActiveRoomId = activeRoomStore && activeRoomStore.getRoomId(); + _onRoomViewStoreUpdate() { // emit for the old room ID - if (this._activeRoomId) this._emit(this._activeRoomId, newActiveRoomId); + if (this._activeRoomId) this._emit(this._activeRoomId); + // update our cache - this._activeRoomId = newActiveRoomId; + this._activeRoomId = RoomViewStore.getRoomId(); + // and emit for the new one - if (this._activeRoomId) this._emit(this._activeRoomId, this._activeRoomId); + if (this._activeRoomId) this._emit(this._activeRoomId); } } diff --git a/src/PageTypes.js b/src/PageTypes.js index e4e1916c8b..60111723fb 100644 --- a/src/PageTypes.js +++ b/src/PageTypes.js @@ -19,7 +19,6 @@ limitations under the License. export default { HomePage: "home_page", RoomView: "room_view", - GroupGridView: "group_grid_view", UserSettings: "user_settings", RoomDirectory: "room_directory", UserView: "user_view", diff --git a/src/UserActivity.js b/src/UserActivity.js index 145b23e36e..4e3667274c 100644 --- a/src/UserActivity.js +++ b/src/UserActivity.js @@ -44,7 +44,6 @@ class UserActivity { * Can be called multiple times with the same already running timer, which is a NO-OP. * Can be called before the user becomes active, in which case it is only started * later on when the user does become active. - * @param {Timer} timer the timer to use */ timeWhileActive(timer) { // important this happens first diff --git a/src/components/structures/GroupGridView.js b/src/components/structures/GroupGridView.js deleted file mode 100644 index a1a9e1b183..0000000000 --- a/src/components/structures/GroupGridView.js +++ /dev/null @@ -1,127 +0,0 @@ -/* -Copyright 2017 Vector Creations Ltd. -Copyright 2017, 2018 New Vector Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import React from 'react'; -import OpenRoomsStore from '../../stores/OpenRoomsStore'; -import dis from '../../dispatcher'; -import {_t} from '../../languageHandler'; -import RoomView from './RoomView'; -import classNames from 'classnames'; -import MainSplit from './MainSplit'; -import RightPanel from './RightPanel'; -import RoomHeaderButtons from '../views/right_panel/RoomHeaderButtons'; - -export default class RoomGridView extends React.Component { - constructor(props) { - super(props); - this.state = { - roomStores: OpenRoomsStore.getRoomStores(), - activeRoomStore: OpenRoomsStore.getActiveRoomStore(), - }; - this.onRoomsChanged = this.onRoomsChanged.bind(this); - } - - componentDidUpdate(_, prevState) { - const store = this.state.activeRoomStore; - if (store) { - store.getDispatcher().dispatch({action: 'focus_composer'}); - } - } - - componentDidMount() { - this.componentDidUpdate(); - } - - componentWillMount() { - this._unmounted = false; - this._openRoomsStoreRegistration = OpenRoomsStore.addListener(this.onRoomsChanged); - } - - componentWillUnmount() { - this._unmounted = true; - if (this._openRoomsStoreRegistration) { - this._openRoomsStoreRegistration.remove(); - } - } - - onRoomsChanged() { - if (this._unmounted) return; - this.setState({ - roomStores: OpenRoomsStore.getRoomStores(), - activeRoomStore: OpenRoomsStore.getActiveRoomStore(), - }); - } - - _setActive(i) { - const store = OpenRoomsStore.getRoomStoreAt(i); - if (store !== this.state.activeRoomStore) { - dis.dispatch({ - action: 'group_grid_set_active', - room_id: store.getRoomId(), - }); - } - } - - render() { - let roomStores = this.state.roomStores.slice(0, 6); - const emptyCount = 6 - roomStores.length; - if (emptyCount) { - const emptyTiles = Array.from({length: emptyCount}, () => null); - roomStores = roomStores.concat(emptyTiles); - } - const activeRoomId = this.state.activeRoomStore && this.state.activeRoomStore.getRoomId(); - let rightPanel; - if (activeRoomId) { - rightPanel = ( -
-
- -
- ); - } - - return (
- -
- { roomStores.map((roomStore, i) => { - if (roomStore) { - const isActive = roomStore === this.state.activeRoomStore; - const tileClasses = classNames({ - "mx_GroupGridView_tile": true, - "mx_GroupGridView_activeTile": isActive, - }); - return (
{this._setActive(i);}} - key={roomStore.getRoomId()} - className={tileClasses} - > - -
); - } else { - return (
{_t("No room in this tile yet.")}
); - } - }) } -
-
-
); - } -} diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index 67d7d41701..0433ce25b3 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -31,7 +31,6 @@ import sessionStore from '../../stores/SessionStore'; import MatrixClientPeg from '../../MatrixClientPeg'; import SettingsStore from "../../settings/SettingsStore"; import RoomListStore from "../../stores/RoomListStore"; -import OpenRoomsStore from "../../stores/OpenRoomsStore"; import TagOrderActions from '../../actions/TagOrderActions'; import RoomListActions from '../../actions/RoomListActions'; @@ -417,7 +416,6 @@ const LoggedInView = React.createClass({ const RoomDirectory = sdk.getComponent('structures.RoomDirectory'); const HomePage = sdk.getComponent('structures.HomePage'); const GroupView = sdk.getComponent('structures.GroupView'); - const GroupGridView = sdk.getComponent('structures.GroupGridView'); const MyGroups = sdk.getComponent('structures.MyGroups'); const MatrixToolbar = sdk.getComponent('globals.MatrixToolbar'); const CookieBar = sdk.getComponent('globals.CookieBar'); @@ -430,14 +428,7 @@ const LoggedInView = React.createClass({ switch (this.props.page_type) { case PageTypes.RoomView: - if (!OpenRoomsStore.getActiveRoomStore()) { - console.warn(`LoggedInView: getCurrentRoomStore not set!`); - } - else if (OpenRoomsStore.getActiveRoomStore().getRoomId() !== this.props.currentRoomId) { - console.warn(`LoggedInView: room id in store not the same as in props: ${OpenRoomsStore.getActiveRoomStore().getRoomId()} & ${this.props.currentRoomId}`); - } page_element = ; break; - case PageTypes.GroupGridView: - page_element = ; - break; + case PageTypes.UserSettings: page_element = ; } else if (this.state.phase === RightPanel.Phase.RoomMemberInfo) { - panel = ; + panel = ; } else if (this.state.phase === RightPanel.Phase.GroupMemberInfo) { panel = { - this.props.roomViewStore.getDispatcher().dispatch({action: 'start_registration'}); + dis.dispatch({action: 'start_registration'}); close(); }, onLoginClick: (ev) => { - this.props.roomViewStore.getDispatcher().dispatch({action: 'start_login'}); + dis.dispatch({action: 'start_login'}); close(); }, }).close; @@ -921,7 +922,7 @@ module.exports = React.createClass({ Promise.resolve().then(() => { const signUrl = this.props.thirdPartyInvite ? this.props.thirdPartyInvite.inviteSignUrl : undefined; - this.props.roomViewStore.getDispatcher().dispatch({ + dis.dispatch({ action: 'join_room', opts: { inviteSignUrl: signUrl, viaServers: this.props.viaServers }, }); @@ -986,10 +987,10 @@ module.exports = React.createClass({ }, uploadFile: async function(file) { - this.props.roomViewStore.getDispatcher().dispatch({action: 'focus_composer'}); + dis.dispatch({action: 'focus_composer'}); if (MatrixClientPeg.get().isGuest()) { - this.props.roomViewStore.getDispatcher().dispatch({action: 'require_registration'}); + dis.dispatch({action: 'require_registration'}); return; } @@ -1013,14 +1014,14 @@ module.exports = React.createClass({ } // Send message_sent callback, for things like _checkIfAlone because after all a file is still a message. - this.props.roomViewStore.getDispatcher().dispatch({ + dis.dispatch({ action: 'message_sent', }); }, injectSticker: function(url, info, text) { if (MatrixClientPeg.get().isGuest()) { - this.props.roomViewStore.getDispatcher().dispatch({action: 'require_registration'}); + dis.dispatch({action: 'require_registration'}); return; } @@ -1221,7 +1222,7 @@ module.exports = React.createClass({ }, onSettingsClick: function() { - this.props.roomViewStore.getDispatcher().dispatch({ action: 'open_room_settings' }); + dis.dispatch({ action: 'open_room_settings' }); }, onSettingsSaveClick: function() { @@ -1254,31 +1255,31 @@ module.exports = React.createClass({ }); // still editing room settings } else { - this.props.roomViewStore.getDispatcher().dispatch({ action: 'close_settings' }); + dis.dispatch({ action: 'close_settings' }); } }).finally(() => { this.setState({ uploadingRoomSettings: false, }); - this.props.roomViewStore.getDispatcher().dispatch({ action: 'close_settings' }); + dis.dispatch({ action: 'close_settings' }); }).done(); }, onCancelClick: function() { console.log("updateTint from onCancelClick"); this.updateTint(); - this.props.roomViewStore.getDispatcher().dispatch({ action: 'close_settings' }); + dis.dispatch({ action: 'close_settings' }); if (this.state.forwardingEvent) { - this.props.roomViewStore.getDispatcher().dispatch({ + dis.dispatch({ action: 'forward_event', event: null, }); } - this.props.roomViewStore.getDispatcher().dispatch({action: 'focus_composer'}); + dis.dispatch({action: 'focus_composer'}); }, onLeaveClick: function() { - this.props.roomViewStore.getDispatcher().dispatch({ + dis.dispatch({ action: 'leave_room', room_id: this.state.room.roomId, }); @@ -1286,7 +1287,7 @@ module.exports = React.createClass({ onForgetClick: function() { MatrixClientPeg.get().forget(this.state.room.roomId).done(function() { - this.props.roomViewStore.getDispatcher().dispatch({ action: 'view_next_room' }); + dis.dispatch({ action: 'view_next_room' }); }, function(err) { const errCode = err.errcode || _t("unknown error code"); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); @@ -1303,7 +1304,7 @@ module.exports = React.createClass({ rejecting: true, }); MatrixClientPeg.get().leave(this.state.roomId).done(function() { - this.props.roomViewStore.getDispatcher().dispatch({ action: 'view_next_room' }); + dis.dispatch({ action: 'view_next_room' }); self.setState({ rejecting: false, }); @@ -1329,7 +1330,7 @@ module.exports = React.createClass({ // using /leave rather than /join. In the short term though, we // just ignore them. // https://github.com/vector-im/vector-web/issues/1134 - this.props.roomViewStore.getDispatcher().dispatch({ + dis.dispatch({ action: 'view_room_directory', }); }, @@ -1348,7 +1349,7 @@ module.exports = React.createClass({ // jump down to the bottom of this room, where new events are arriving jumpToLiveTimeline: function() { this.refs.messagePanel.jumpToLiveTimeline(); - this.props.roomViewStore.getDispatcher().dispatch({action: 'focus_composer'}); + dis.dispatch({action: 'focus_composer'}); }, // jump up to wherever our read marker is @@ -1438,7 +1439,7 @@ module.exports = React.createClass({ }, onFullscreenClick: function() { - this.props.roomViewStore.getDispatcher().dispatch({ + dis.dispatch({ action: 'video_fullscreen', fullscreen: true, }, true); @@ -1563,7 +1564,6 @@ module.exports = React.createClass({
@@ -1610,7 +1610,6 @@ module.exports = React.createClass({
@@ -1752,9 +1751,7 @@ module.exports = React.createClass({ if (canSpeak) { messageComposer = : - undefined; + const rightPanel = this.state.room ? : undefined; return (
- - { _t('View as Grid') } -
); - } return
{ _t('View Community') }
- { gridViewOption }
diff --git a/src/components/views/right_panel/HeaderButtons.js b/src/components/views/right_panel/HeaderButtons.js index 3f5f58121d..f0479eb8be 100644 --- a/src/components/views/right_panel/HeaderButtons.js +++ b/src/components/views/right_panel/HeaderButtons.js @@ -78,6 +78,7 @@ export default class HeaderButtons extends React.Component { // till show_right_panel, just without the fromHeader flag // as that would hide the right panel again dis.dispatch(Object.assign({}, payload, {fromHeader: false})); + } this.setState({ phase: payload.phase, diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 2b50ff5e48..6a796bc160 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -39,6 +39,7 @@ import Unread from '../../../Unread'; import { findReadReceiptFromUserId } from '../../../utils/Receipt'; import withMatrixClient from '../../../wrappers/withMatrixClient'; import AccessibleButton from '../elements/AccessibleButton'; +import RoomViewStore from '../../../stores/RoomViewStore'; import SdkConfig from '../../../SdkConfig'; import MultiInviter from "../../../utils/MultiInviter"; import SettingsStore from "../../../settings/SettingsStore"; @@ -49,7 +50,6 @@ module.exports = withMatrixClient(React.createClass({ propTypes: { matrixClient: PropTypes.object.isRequired, member: PropTypes.object.isRequired, - roomId: PropTypes.string, }, getInitialState: function() { @@ -713,7 +713,7 @@ module.exports = withMatrixClient(React.createClass({ } if (!member || !member.membership || member.membership === 'leave') { - const roomId = member && member.roomId ? member.roomId : this.props.roomId; + const roomId = member && member.roomId ? member.roomId : RoomViewStore.getRoomId(); const onInviteUserButton = async () => { try { // We use a MultiInviter to re-use the invite logic, even though diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index c648ca615b..91ef549185 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -22,6 +22,7 @@ import MatrixClientPeg from '../../../MatrixClientPeg'; import Modal from '../../../Modal'; import sdk from '../../../index'; import dis from '../../../dispatcher'; +import RoomViewStore from '../../../stores/RoomViewStore'; import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; import Stickerpicker from './Stickerpicker'; import { makeRoomPermalink } from '../../../matrix-to'; @@ -62,7 +63,7 @@ export default class MessageComposer extends React.Component { isRichTextEnabled: SettingsStore.getValue('MessageComposerInput.isRichTextEnabled'), }, showFormatting: SettingsStore.getValue('MessageComposer.showFormatting'), - isQuoting: Boolean(this.props.roomViewStore.getQuotingEvent()), + isQuoting: Boolean(RoomViewStore.getQuotingEvent()), tombstone: this._getRoomTombstone(), }; } @@ -74,7 +75,7 @@ export default class MessageComposer extends React.Component { // XXX: fragile as all hell - fixme somehow, perhaps with a dedicated Room.encryption event or something. MatrixClientPeg.get().on("event", this.onEvent); MatrixClientPeg.get().on("RoomState.events", this._onRoomStateEvents); - this._roomStoreToken = this.props.roomViewStore.addListener(this._onRoomViewStoreUpdate); + this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate); this._waitForOwnMember(); } @@ -123,14 +124,14 @@ export default class MessageComposer extends React.Component { } _onRoomViewStoreUpdate() { - const isQuoting = Boolean(this.props.roomViewStore.getQuotingEvent()); + const isQuoting = Boolean(RoomViewStore.getQuotingEvent()); if (this.state.isQuoting === isQuoting) return; this.setState({ isQuoting }); } onUploadClick(ev) { if (MatrixClientPeg.get().isGuest()) { - this.props.roomViewStore.getDispatcher().dispatch({action: 'require_registration'}); + dis.dispatch({action: 'require_registration'}); return; } @@ -164,7 +165,7 @@ export default class MessageComposer extends React.Component { } } - const isQuoting = Boolean(this.props.roomViewStore.getQuotingEvent()); + const isQuoting = Boolean(RoomViewStore.getQuotingEvent()); let replyToWarning = null; if (isQuoting) { replyToWarning =

{ @@ -228,7 +229,7 @@ export default class MessageComposer extends React.Component { if (!call) { return; } - this.props.roomViewStore.getDispatcher().dispatch({ + dis.dispatch({ action: 'hangup', // hangup the call for this room, which may not be the room in props // (e.g. conferences which will hangup the 1:1 room instead) @@ -237,7 +238,7 @@ export default class MessageComposer extends React.Component { } onCallClick(ev) { - this.props.roomViewStore.getDispatcher().dispatch({ + dis.dispatch({ action: 'place_call', type: ev.shiftKey ? "screensharing" : "video", room_id: this.props.room.roomId, @@ -245,7 +246,7 @@ export default class MessageComposer extends React.Component { } onVoiceCallClick(ev) { - this.props.roomViewStore.getDispatcher().dispatch({ + dis.dispatch({ action: 'place_call', type: "voice", room_id: this.props.room.roomId, @@ -287,8 +288,7 @@ export default class MessageComposer extends React.Component { const createEvent = replacementRoom.currentState.getStateEvents('m.room.create', ''); if (createEvent && createEvent.getId()) createEventId = createEvent.getId(); } - - this.props.roomViewStore.getDispatcher().dispatch({ + dis.dispatch({ action: 'view_room', highlighted: true, event_id: createEventId, @@ -432,10 +432,8 @@ export default class MessageComposer extends React.Component { controls.push( this.messageComposerInput = c} key="controls_input" - isGrid={this.props.isGrid} onResize={this.props.onResize} room={this.props.room} placeholder={placeholderText} @@ -542,6 +540,5 @@ MessageComposer.propTypes = { uploadAllowed: PropTypes.func.isRequired, // string representing the current room app drawer state - showApps: PropTypes.bool, - roomViewStore: PropTypes.object.isRequired, + showApps: PropTypes.bool }; diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 4c800ad8d2..ff7cfcbd6d 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -38,6 +38,8 @@ import sdk from '../../../index'; import { _t } from '../../../languageHandler'; import Analytics from '../../../Analytics'; +import dis from '../../../dispatcher'; + import * as RichText from '../../../RichText'; import * as HtmlUtils from '../../../HtmlUtils'; import Autocomplete from './Autocomplete'; @@ -55,6 +57,7 @@ import { import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; import {makeUserPermalink} from "../../../matrix-to"; import ReplyPreview from "./ReplyPreview"; +import RoomViewStore from '../../../stores/RoomViewStore'; import ReplyThread from "../elements/ReplyThread"; import {ContentHelpers} from 'matrix-js-sdk'; @@ -108,6 +111,15 @@ const SLATE_SCHEMA = { }, }; +function onSendMessageFailed(err, room) { + // XXX: temporary logging to try to diagnose + // https://github.com/vector-im/riot-web/issues/3148 + console.log('MessageComposer got send failure: ' + err.name + '('+err+')'); + dis.dispatch({ + action: 'message_send_failed', + }); +} + function rangeEquals(a: Range, b: Range): boolean { return (a.anchor.key === b.anchor.key && a.anchor.offset === b.anchorOffset @@ -117,18 +129,6 @@ function rangeEquals(a: Range, b: Range): boolean { && a.isBackward === b.isBackward); } -class NoopHistoryManager { - getItem() {} - save() {} - - get currentIndex() { return 0; } - set currentIndex(_) {} - - get history() { return []; } - set history(_) {} -} - - /* * The textInput part of the MessageComposer */ @@ -144,7 +144,6 @@ export default class MessageComposerInput extends React.Component { onFilesPasted: PropTypes.func, onInputStateChanged: PropTypes.func, - roomViewStore: PropTypes.object.isRequired, }; client: MatrixClient; @@ -339,31 +338,18 @@ export default class MessageComposerInput extends React.Component { } componentWillMount() { - this.dispatcherRef = this.props.roomViewStore.getDispatcher().register(this.onAction); - if (this.props.isGrid) { - this.historyManager = new NoopHistoryManager(); - } else { - this.historyManager = new ComposerHistoryManager(this.props.room.roomId, 'mx_slate_composer_history_'); - } + this.dispatcherRef = dis.register(this.onAction); + this.historyManager = new ComposerHistoryManager(this.props.room.roomId, 'mx_slate_composer_history_'); } componentWillUnmount() { - this.props.roomViewStore.getDispatcher().unregister(this.dispatcherRef); + dis.unregister(this.dispatcherRef); } _collectEditor = (e) => { this._editor = e; } - onSendMessageFailed = (err, room) => { - // XXX: temporary logging to try to diagnose - // https://github.com/vector-im/riot-web/issues/3148 - console.log('MessageComposer got send failure: ' + err.name + '('+err+')'); - this.props.roomViewStore.getDispatcher().dispatch({ - action: 'message_send_failed', - }); - } - onAction = (payload) => { const editorState = this.state.editorState; @@ -1129,7 +1115,7 @@ export default class MessageComposerInput extends React.Component { return true; } - const replyingToEv = this.props.roomViewStore.getQuotingEvent(); + const replyingToEv = RoomViewStore.getQuotingEvent(); const mustSendHTML = Boolean(replyingToEv); if (this.state.isRichTextEnabled) { @@ -1217,18 +1203,18 @@ export default class MessageComposerInput extends React.Component { // Clear reply_to_event as we put the message into the queue // if the send fails, retry will handle resending. - this.props.roomViewStore.getDispatcher().dispatch({ + dis.dispatch({ action: 'reply_to_event', event: null, }); } this.client.sendMessage(this.props.room.roomId, content).then((res) => { - this.props.roomViewStore.getDispatcher().dispatch({ + dis.dispatch({ action: 'message_sent', }); }).catch((e) => { - this.onSendMessageFailed(e, this.props.room); + onSendMessageFailed(e, this.props.room); }); this.setState({ @@ -1599,7 +1585,7 @@ export default class MessageComposerInput extends React.Component { return (

- + this.autocomplete = e} room={this.props.room} diff --git a/src/components/views/rooms/ReplyPreview.js b/src/components/views/rooms/ReplyPreview.js index 04ff9d0778..46e2826634 100644 --- a/src/components/views/rooms/ReplyPreview.js +++ b/src/components/views/rooms/ReplyPreview.js @@ -18,6 +18,7 @@ import React from 'react'; import dis from '../../../dispatcher'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import RoomViewStore from '../../../stores/RoomViewStore'; import SettingsStore from "../../../settings/SettingsStore"; function cancelQuoting() { @@ -37,7 +38,7 @@ export default class ReplyPreview extends React.Component { this._onRoomViewStoreUpdate = this._onRoomViewStoreUpdate.bind(this); - this._roomStoreToken = this.props.roomViewStore.addListener(this._onRoomViewStoreUpdate); + this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate); this._onRoomViewStoreUpdate(); } @@ -49,7 +50,7 @@ export default class ReplyPreview extends React.Component { } _onRoomViewStoreUpdate() { - const event = this.props.roomViewStore.getQuotingEvent(); + const event = RoomViewStore.getQuotingEvent(); if (this.state.event !== event) { this.setState({ event }); } diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index 91ca73dd59..4292fa6a4d 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -24,7 +24,6 @@ import { _t } from '../../../languageHandler'; import MatrixClientPeg from '../../../MatrixClientPeg'; import Modal from "../../../Modal"; import RateLimitedFunc from '../../../ratelimitedfunc'; -import dis from '../../../dispatcher'; import * as linkify from 'linkifyjs'; import linkifyElement from 'linkifyjs/element'; @@ -153,14 +152,6 @@ module.exports = React.createClass({ }); }, - onToggleRightPanelClick: function(ev) { - if (this.props.collapsedRhs) { - dis.dispatch({action: "show_right_panel"}); - } else { - dis.dispatch({action: "hide_right_panel"}); - } - }, - _hasUnreadPins: function() { const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", ''); if (!currentPinEvent) return false; @@ -418,17 +409,6 @@ module.exports = React.createClass({
; } - let toggleRightPanelButton; - if (this.props.isGrid) { - toggleRightPanelButton = - - - ; - } - return (
@@ -439,8 +419,7 @@ module.exports = React.createClass({ { saveButton } { cancelButton } { rightRow } - { !this.props.isGrid ? : undefined } - { toggleRightPanelButton } +
); diff --git a/src/components/views/rooms/RoomTile.js b/src/components/views/rooms/RoomTile.js index 1f9c0c1523..1a17fcf5ea 100644 --- a/src/components/views/rooms/RoomTile.js +++ b/src/components/views/rooms/RoomTile.js @@ -29,6 +29,7 @@ import * as RoomNotifs from '../../../RoomNotifs'; import * as FormattingUtils from '../../../utils/FormattingUtils'; import AccessibleButton from '../elements/AccessibleButton'; import ActiveRoomObserver from '../../../ActiveRoomObserver'; +import RoomViewStore from '../../../stores/RoomViewStore'; import SettingsStore from "../../../settings/SettingsStore"; module.exports = React.createClass({ @@ -61,7 +62,7 @@ module.exports = React.createClass({ roomName: this.props.room.name, notifState: RoomNotifs.getRoomNotifsState(this.props.room.roomId), notificationCount: this.props.room.getUnreadNotificationCount(), - selected: this.props.room.roomId === ActiveRoomObserver.getActiveRoomId(), + selected: this.props.room.roomId === RoomViewStore.getRoomId(), statusMessage: this._getStatusMessage(), }); }, @@ -150,9 +151,9 @@ module.exports = React.createClass({ } }, - _onActiveRoomChange: function(activeRoomId) { + _onActiveRoomChange: function() { this.setState({ - selected: this.props.room.roomId === activeRoomId, + selected: this.props.room.roomId === RoomViewStore.getRoomId(), }); }, diff --git a/src/dispatcher.js b/src/dispatcher.js index 4dc6e1e37d..48c8dc86e9 100644 --- a/src/dispatcher.js +++ b/src/dispatcher.js @@ -17,10 +17,42 @@ limitations under the License. 'use strict'; -import MatrixDispatcher from "./matrix-dispatcher"; +const flux = require("flux"); + +class MatrixDispatcher extends flux.Dispatcher { + /** + * @param {Object|function} payload Required. The payload to dispatch. + * If an Object, must contain at least an 'action' key. + * If a function, must have the signature (dispatch) => {...}. + * @param {boolean=} sync Optional. Pass true to dispatch + * synchronously. This is useful for anything triggering + * an operation that the browser requires user interaction + * for. + */ + dispatch(payload, sync) { + // Allow for asynchronous dispatching by accepting payloads that have the + // type `function (dispatch) {...}` + if (typeof payload === 'function') { + payload((action) => { + this.dispatch(action, sync); + }); + return; + } + + if (sync) { + super.dispatch(payload); + } else { + // Unless the caller explicitly asked for us to dispatch synchronously, + // we always set a timeout to do this: The flux dispatcher complains + // if you dispatch from within a dispatch, so rather than action + // handlers having to worry about not calling anything that might + // then dispatch, we just do dispatches asynchronously. + setTimeout(super.dispatch.bind(this, payload), 0); + } + } +} if (global.mxDispatcher === undefined) { global.mxDispatcher = new MatrixDispatcher(); } - module.exports = global.mxDispatcher; diff --git a/src/matrix-dispatcher.js b/src/matrix-dispatcher.js deleted file mode 100644 index fb81ed837f..0000000000 --- a/src/matrix-dispatcher.js +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket Ltd -Copyright 2017 New Vector Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -'use strict'; - -const flux = require("flux"); - -export default class MatrixDispatcher extends flux.Dispatcher { - /** - * @param {Object|function} payload Required. The payload to dispatch. - * If an Object, must contain at least an 'action' key. - * If a function, must have the signature (dispatch) => {...}. - * @param {boolean=} sync Optional. Pass true to dispatch - * synchronously. This is useful for anything triggering - * an operation that the browser requires user interaction - * for. - */ - dispatch(payload, sync) { - // Allow for asynchronous dispatching by accepting payloads that have the - // type `function (dispatch) {...}` - if (typeof payload === 'function') { - payload((action) => { - this.dispatch(action, sync); - }); - return; - } - - if (sync) { - super.dispatch(payload); - } else { - // Unless the caller explicitly asked for us to dispatch synchronously, - // we always set a timeout to do this: The flux dispatcher complains - // if you dispatch from within a dispatch, so rather than action - // handlers having to worry about not calling anything that might - // then dispatch, we just do dispatches asynchronously. - setTimeout(super.dispatch.bind(this, payload), 0); - } - } -} diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 836e906b6e..66353c67a6 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -110,12 +110,6 @@ export const SETTINGS = { supportedLevels: LEVELS_FEATURE, default: false, }, - "feature_gridview": { - isFeature: true, - displayName: _td("Allow up to 6 rooms in a community to be shown simultaneously in a grid via the context menu"), - supportedLevels: LEVELS_FEATURE, - default: false, - }, "MessageComposerInput.dontSuggestEmoji": { supportedLevels: LEVELS_ACCOUNT_SETTINGS, displayName: _td('Disable Emoji suggestions while typing'), diff --git a/src/stores/OpenRoomsStore.js b/src/stores/OpenRoomsStore.js deleted file mode 100644 index 21f02fe28d..0000000000 --- a/src/stores/OpenRoomsStore.js +++ /dev/null @@ -1,277 +0,0 @@ -/* -Copyright 2018 New Vector Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -import MatrixDispatcher from '../matrix-dispatcher'; -import dis from '../dispatcher'; -import {RoomViewStore} from './RoomViewStore'; -import GroupStore from './GroupStore'; -import {Store} from 'flux/utils'; -import MatrixClientPeg from '../MatrixClientPeg'; - - -function matchesRoom(payload, roomStore) { - if (!roomStore) { - return false; - } - if (payload.room_alias) { - return payload.room_alias === roomStore.getRoomAlias(); - } - return payload.room_id === roomStore.getRoomId(); -} - -/** - * A class for keeping track of the RoomViewStores of the rooms shown on the screen. - * Routes the dispatcher actions to the store of currently active room. - */ -class OpenRoomsStore extends Store { - constructor() { - super(dis); - - // Initialise state - this._state = { - rooms: [], - currentIndex: null, - group_id: null, - }; - - this._forwardingEvent = null; - } - - getRoomStores() { - return this._state.rooms.map((r) => r.store); - } - - getActiveRoomStore() { - const openRoom = this._getActiveOpenRoom(); - if (openRoom) { - return openRoom.store; - } - } - - getRoomStoreAt(index) { - if (index >= 0 && index < this._state.rooms.length) { - return this._state.rooms[index].store; - } - } - - _getActiveOpenRoom() { - const index = this._state.currentIndex; - if (index !== null && index < this._state.rooms.length) { - return this._state.rooms[index]; - } - } - - _setState(newState) { - this._state = Object.assign(this._state, newState); - this.__emitChange(); - } - - _hasRoom(payload) { - return this._roomIndex(payload) !== -1; - } - - _roomIndex(payload) { - return this._state.rooms.findIndex((r) => matchesRoom(payload, r.store)); - } - - _cleanupOpenRooms() { - this._state.rooms.forEach((room) => { - room.dispatcher.unregister(room.dispatcherRef); - room.dispatcher.unregister(room.store.getDispatchToken()); - }); - this._setState({ - rooms: [], - group_id: null, - currentIndex: null, - }); - } - - _createOpenRoom(roomId, roomAlias) { - const dispatcher = new MatrixDispatcher(); - // forward all actions coming from the room dispatcher - // to the global one - const dispatcherRef = dispatcher.register((payload) => { - // block a view_room action for the same room because it will switch to - // single room mode in MatrixChat - if (payload.action === 'view_room' && roomId === payload.room_id) { - return; - } - payload.grid_src_room_id = roomId; - payload.grid_src_room_alias = roomAlias; - this.getDispatcher().dispatch(payload); - }); - const openRoom = { - store: new RoomViewStore(dispatcher), - dispatcher, - dispatcherRef, - }; - - dispatcher.dispatch({ - action: 'view_room', - room_id: roomId, - room_alias: roomAlias, - }, true); - - return openRoom; - } - - _setSingleOpenRoom(payload) { - this._setState({ - rooms: [this._createOpenRoom(payload.room_id, payload.room_alias)], - currentIndex: 0, - }); - } - - _setGroupOpenRooms(groupId) { - this._cleanupOpenRooms(); - // TODO: register to GroupStore updates - const rooms = GroupStore.getGroupRooms(groupId); - const openRooms = rooms.map((room) => { - return this._createOpenRoom(room.roomId); - }); - this._setState({ - rooms: openRooms, - group_id: groupId, - currentIndex: 0, - }); - } - - _forwardAction(payload) { - // don't forward an event to a room dispatcher - // if the event originated from that dispatcher, as this - // would cause the event to be observed twice in that - // dispatcher - if (payload.grid_src_room_id || payload.grid_src_room_alias) { - const srcPayload = { - room_id: payload.grid_src_room_id, - room_alias: payload.grid_src_room_alias, - }; - const srcIndex = this._roomIndex(srcPayload); - if (srcIndex === this._state.currentIndex) { - return; - } - } - const currentRoom = this._getActiveOpenRoom(); - if (currentRoom) { - currentRoom.dispatcher.dispatch(payload, true); - } - } - - async _resolveRoomAlias(payload) { - try { - const result = await MatrixClientPeg.get() - .getRoomIdForAlias(payload.room_alias); - this.getDispatcher().dispatch({ - action: 'view_room', - room_id: result.room_id, - event_id: payload.event_id, - highlighted: payload.highlighted, - room_alias: payload.room_alias, - auto_join: payload.auto_join, - oob_data: payload.oob_data, - }); - } catch (err) { - this._forwardAction({ - action: 'view_room_error', - room_id: null, - room_alias: payload.room_alias, - err: err, - }); - } - } - - _viewRoom(payload) { - console.log("!!! OpenRoomsStore: view_room", payload); - if (!payload.room_id && payload.room_alias) { - this._resolveRoomAlias(payload); - } - const currentStore = this.getActiveRoomStore(); - if (!matchesRoom(payload, currentStore)) { - if (this._hasRoom(payload)) { - const roomIndex = this._roomIndex(payload); - this._setState({currentIndex: roomIndex}); - } else { - this._cleanupOpenRooms(); - } - } - if (!this.getActiveRoomStore()) { - console.log("OpenRoomsStore: _setSingleOpenRoom"); - this._setSingleOpenRoom(payload); - } - console.log("OpenRoomsStore: _forwardAction"); - this._forwardAction(payload); - if (this._forwardingEvent) { - this.getDispatcher().dispatch({ - action: 'send_event', - room_id: payload.room_id, - event: this._forwardingEvent, - }); - this._forwardingEvent = null; - } - } - - __onDispatch(payload) { - let proposedIndex; - switch (payload.action) { - // view_room: - // - room_alias: '#somealias:matrix.org' - // - room_id: '!roomid123:matrix.org' - // - event_id: '$213456782:matrix.org' - // - event_offset: 100 - // - highlighted: true - case 'view_room': - this._viewRoom(payload); - break; - case 'view_my_groups': - case 'view_group': - this._forwardAction(payload); - this._cleanupOpenRooms(); - break; - case 'will_join': - case 'cancel_join': - case 'join_room': - case 'join_room_error': - case 'on_logged_out': - case 'reply_to_event': - case 'open_room_settings': - case 'close_settings': - case 'focus_composer': - this._forwardAction(payload); - break; - case 'forward_event': - this._forwardingEvent = payload.event; - break; - case 'group_grid_set_active': - proposedIndex = this._roomIndex(payload); - if (proposedIndex !== -1) { - this._setState({ - currentIndex: proposedIndex, - }); - } - break; - case 'group_grid_view': - if (payload.group_id !== this._state.group_id) { - this._setGroupOpenRooms(payload.group_id); - } - break; - } - } -} - -let singletonOpenRoomsStore = null; -if (!singletonOpenRoomsStore) { - singletonOpenRoomsStore = new OpenRoomsStore(); -} -module.exports = singletonOpenRoomsStore; diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index a0b831ad17..9e048e5d8e 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -14,6 +14,7 @@ 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 dis from '../dispatcher'; import {Store} from 'flux/utils'; import MatrixClientPeg from '../MatrixClientPeg'; import sdk from '../index'; @@ -52,12 +53,12 @@ const INITIAL_STATE = { * with a subset of the js-sdk. * ``` */ -export class RoomViewStore extends Store { - constructor(dispatcher) { - super(dispatcher); +class RoomViewStore extends Store { + constructor() { + super(dis); // Initialise state - this._state = Object.assign({}, INITIAL_STATE); + this._state = INITIAL_STATE; } _setState(newState) { @@ -84,8 +85,6 @@ export class RoomViewStore extends Store { }); break; case 'view_room_error': - // should not go over dispatcher anymore - // but be internal to RoomViewStore this._viewRoomError(payload); break; case 'will_join': @@ -151,11 +150,22 @@ export class RoomViewStore extends Store { // pull the user out of Room Settings isEditingSettings: false, }; + + if (this._state.forwardingEvent) { + dis.dispatch({ + action: 'send_event', + room_id: newState.roomId, + event: this._state.forwardingEvent, + }); + } + this._setState(newState); + if (payload.auto_join) { this._joinRoom(payload); } } else if (payload.room_alias) { + // Resolve the alias and then do a second dispatch with the room ID acquired this._setState({ roomId: null, initialEventId: null, @@ -165,6 +175,25 @@ export class RoomViewStore extends Store { roomLoading: true, roomLoadError: null, }); + MatrixClientPeg.get().getRoomIdForAlias(payload.room_alias).done( + (result) => { + dis.dispatch({ + action: 'view_room', + room_id: result.room_id, + event_id: payload.event_id, + highlighted: payload.highlighted, + room_alias: payload.room_alias, + auto_join: payload.auto_join, + oob_data: payload.oob_data, + }); + }, (err) => { + dis.dispatch({ + action: 'view_room_error', + room_id: null, + room_alias: payload.room_alias, + err: err, + }); + }); } } @@ -190,7 +219,7 @@ export class RoomViewStore extends Store { // stream yet, and that's the point at which we'd consider // the user joined to the room. }, (err) => { - this.getDispatcher().dispatch({ + dis.dispatch({ action: 'join_room_error', err: err, }); @@ -306,7 +335,8 @@ export class RoomViewStore extends Store { } } -const MatrixDispatcher = require("../matrix-dispatcher"); -const backwardsCompatInstance = new RoomViewStore(new MatrixDispatcher()); - -export default backwardsCompatInstance; +let singletonRoomViewStore = null; +if (!singletonRoomViewStore) { + singletonRoomViewStore = new RoomViewStore(); +} +module.exports = singletonRoomViewStore; diff --git a/src/utils/Timer.js b/src/utils/Timer.js index ca06237fbf..aeac0887c9 100644 --- a/src/utils/Timer.js +++ b/src/utils/Timer.js @@ -26,6 +26,7 @@ Once a timer is finished or aborted, it can't be started again a new one through `clone()` or `cloneIfRun()`. */ export default class Timer { + constructor(timeout) { this._timeout = timeout; this._onTimeout = this._onTimeout.bind(this); @@ -69,7 +70,6 @@ export default class Timer { /** * if not started before, starts the timer. - * @returns {Timer} the same timer */ start() { if (!this.isRunning()) { @@ -81,7 +81,6 @@ export default class Timer { /** * (re)start the timer. If it's running, reset the timeout. If not, start it. - * @returns {Timer} the same timer */ restart() { if (this.isRunning()) { @@ -99,7 +98,6 @@ export default class Timer { /** * if the timer is running, abort it, * and reject the promise for this timer. - * @returns {Timer} the same timer */ abort() { if (this.isRunning()) {