Merge pull request #2451 from matrix-org/bwindels/revertgridview
Revert "Tiled room UI"pull/21833/head
commit
e7359ff115
|
@ -5,7 +5,6 @@
|
||||||
@import "./structures/_ContextualMenu.scss";
|
@import "./structures/_ContextualMenu.scss";
|
||||||
@import "./structures/_CreateRoom.scss";
|
@import "./structures/_CreateRoom.scss";
|
||||||
@import "./structures/_FilePanel.scss";
|
@import "./structures/_FilePanel.scss";
|
||||||
@import "./structures/_GroupGridView.scss";
|
|
||||||
@import "./structures/_GroupView.scss";
|
@import "./structures/_GroupView.scss";
|
||||||
@import "./structures/_HomePage.scss";
|
@import "./structures/_HomePage.scss";
|
||||||
@import "./structures/_LeftPanel.scss";
|
@import "./structures/_LeftPanel.scss";
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -81,8 +81,7 @@ limitations under the License.
|
||||||
Empirically this stops the MessagePanel's width exploding outwards when
|
Empirically this stops the MessagePanel's width exploding outwards when
|
||||||
gemini is in 'prevented' mode
|
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
|
/* 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
|
needed height 100% all the way down to the HomePage. Height does not
|
||||||
|
|
|
@ -53,10 +53,6 @@ limitations under the License.
|
||||||
.mx_MemberList_query,
|
.mx_MemberList_query,
|
||||||
.mx_GroupMemberList_query,
|
.mx_GroupMemberList_query,
|
||||||
.mx_GroupRoomList_query {
|
.mx_GroupRoomList_query {
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_MemberList .gm-scrollbar-container {
|
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg width="22px" height="14px" viewBox="0 0 22 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<!-- Generator: Sketch 52.5 (67469) - http://www.bohemiancoding.com/sketch -->
|
|
||||||
<title>Group 2</title>
|
|
||||||
<desc>Created with Sketch.</desc>
|
|
||||||
<g id="Experiments" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
|
|
||||||
<g id="multi-room-test-copy-8" transform="translate(-826.000000, -15.000000)" stroke="#929EB4" stroke-width="1.6">
|
|
||||||
<g id="Group-4" transform="translate(341.000000, 7.000000)">
|
|
||||||
<g id="Group-2" transform="translate(486.000000, 8.000000)">
|
|
||||||
<path d="M20,1 L2.30926389e-14,1" id="Line-10"></path>
|
|
||||||
<path d="M20,7 L3,7" id="Line-10-Copy"></path>
|
|
||||||
<path d="M20,13 L6,13" id="Line-10-Copy-2"></path>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 995 B |
|
@ -162,10 +162,6 @@ $lightbox-bg-color: #454545;
|
||||||
$lightbox-fg-color: #ffffff;
|
$lightbox-fg-color: #ffffff;
|
||||||
$lightbox-border-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: rgba(1, 1, 1, 0.7);
|
||||||
$imagebody-giflabel-border: rgba(1, 1, 1, 0.2);
|
$imagebody-giflabel-border: rgba(1, 1, 1, 0.2);
|
||||||
$imagebody-giflabel-color: rgba(0, 0, 0, 1);
|
$imagebody-giflabel-color: rgba(0, 0, 0, 1);
|
||||||
|
|
|
@ -184,9 +184,6 @@ $lightbox-bg-color: #454545;
|
||||||
$lightbox-fg-color: #ffffff;
|
$lightbox-fg-color: #ffffff;
|
||||||
$lightbox-border-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?
|
// unused?
|
||||||
$progressbar-color: #000;
|
$progressbar-color: #000;
|
||||||
|
|
||||||
|
|
|
@ -175,10 +175,6 @@ $lightbox-bg-color: #454545;
|
||||||
$lightbox-fg-color: #ffffff;
|
$lightbox-fg-color: #ffffff;
|
||||||
$lightbox-border-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: rgba(0, 0, 0, 0.7);
|
||||||
$imagebody-giflabel-border: rgba(0, 0, 0, 0.2);
|
$imagebody-giflabel-border: rgba(0, 0, 0, 0.2);
|
||||||
$imagebody-giflabel-color: rgba(255, 255, 255, 1);
|
$imagebody-giflabel-color: rgba(255, 255, 255, 1);
|
||||||
|
|
|
@ -14,10 +14,10 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
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
|
* about when the active room changes. Unlike listening for RoomViewStore
|
||||||
* changes, you can subscribe to only changes relevant to a particular
|
* changes, you can subscribe to only changes relevant to a particular
|
||||||
* room.
|
* room.
|
||||||
|
@ -28,15 +28,11 @@ import OpenRoomsStore from './stores/OpenRoomsStore';
|
||||||
class ActiveRoomObserver {
|
class ActiveRoomObserver {
|
||||||
constructor() {
|
constructor() {
|
||||||
this._listeners = {};
|
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
|
// TODO: We could self-destruct when the last listener goes away, or at least
|
||||||
// stop listening.
|
// stop listening.
|
||||||
this._roomStoreToken = OpenRoomsStore.addListener(this._onOpenRoomsStoreUpdate.bind(this));
|
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate.bind(this));
|
||||||
}
|
|
||||||
|
|
||||||
getActiveRoomId() {
|
|
||||||
return this._activeRoomId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addListener(roomId, listener) {
|
addListener(roomId, listener) {
|
||||||
|
@ -55,23 +51,23 @@ class ActiveRoomObserver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_emit(roomId, newActiveRoomId) {
|
_emit(roomId) {
|
||||||
if (!this._listeners[roomId]) return;
|
if (!this._listeners[roomId]) return;
|
||||||
|
|
||||||
for (const l of this._listeners[roomId]) {
|
for (const l of this._listeners[roomId]) {
|
||||||
l.call(l, newActiveRoomId);
|
l.call();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onOpenRoomsStoreUpdate() {
|
_onRoomViewStoreUpdate() {
|
||||||
const activeRoomStore = OpenRoomsStore.getActiveRoomStore();
|
|
||||||
const newActiveRoomId = activeRoomStore && activeRoomStore.getRoomId();
|
|
||||||
// emit for the old room ID
|
// emit for the old room ID
|
||||||
if (this._activeRoomId) this._emit(this._activeRoomId, newActiveRoomId);
|
if (this._activeRoomId) this._emit(this._activeRoomId);
|
||||||
|
|
||||||
// update our cache
|
// update our cache
|
||||||
this._activeRoomId = newActiveRoomId;
|
this._activeRoomId = RoomViewStore.getRoomId();
|
||||||
|
|
||||||
// and emit for the new one
|
// and emit for the new one
|
||||||
if (this._activeRoomId) this._emit(this._activeRoomId, this._activeRoomId);
|
if (this._activeRoomId) this._emit(this._activeRoomId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ limitations under the License.
|
||||||
export default {
|
export default {
|
||||||
HomePage: "home_page",
|
HomePage: "home_page",
|
||||||
RoomView: "room_view",
|
RoomView: "room_view",
|
||||||
GroupGridView: "group_grid_view",
|
|
||||||
UserSettings: "user_settings",
|
UserSettings: "user_settings",
|
||||||
RoomDirectory: "room_directory",
|
RoomDirectory: "room_directory",
|
||||||
UserView: "user_view",
|
UserView: "user_view",
|
||||||
|
|
|
@ -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 = (
|
|
||||||
<div className="mx_GroupGridView_rightPanel">
|
|
||||||
<div className="mx_GroupGridView_tabs"><RoomHeaderButtons /></div>
|
|
||||||
<RightPanel roomId={activeRoomId} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (<main className="mx_GroupGridView">
|
|
||||||
<MainSplit panel={rightPanel} collapsedRhs={this.props.collapsedRhs} >
|
|
||||||
<div className="mx_GroupGridView_rooms">
|
|
||||||
{ roomStores.map((roomStore, i) => {
|
|
||||||
if (roomStore) {
|
|
||||||
const isActive = roomStore === this.state.activeRoomStore;
|
|
||||||
const tileClasses = classNames({
|
|
||||||
"mx_GroupGridView_tile": true,
|
|
||||||
"mx_GroupGridView_activeTile": isActive,
|
|
||||||
});
|
|
||||||
return (<section
|
|
||||||
onClick={() => {this._setActive(i);}}
|
|
||||||
key={roomStore.getRoomId()}
|
|
||||||
className={tileClasses}
|
|
||||||
>
|
|
||||||
<RoomView
|
|
||||||
collapsedRhs={this.props.collapsedRhs}
|
|
||||||
isGrid={true}
|
|
||||||
roomViewStore={roomStore}
|
|
||||||
isActive={isActive}
|
|
||||||
/>
|
|
||||||
</section>);
|
|
||||||
} else {
|
|
||||||
return (<section className={"mx_GroupGridView_emptyTile"} key={`empty-${i}`}>{_t("No room in this tile yet.")}</section>);
|
|
||||||
}
|
|
||||||
}) }
|
|
||||||
</div>
|
|
||||||
</MainSplit>
|
|
||||||
</main>);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -31,7 +31,6 @@ import sessionStore from '../../stores/SessionStore';
|
||||||
import MatrixClientPeg from '../../MatrixClientPeg';
|
import MatrixClientPeg from '../../MatrixClientPeg';
|
||||||
import SettingsStore from "../../settings/SettingsStore";
|
import SettingsStore from "../../settings/SettingsStore";
|
||||||
import RoomListStore from "../../stores/RoomListStore";
|
import RoomListStore from "../../stores/RoomListStore";
|
||||||
import OpenRoomsStore from "../../stores/OpenRoomsStore";
|
|
||||||
|
|
||||||
import TagOrderActions from '../../actions/TagOrderActions';
|
import TagOrderActions from '../../actions/TagOrderActions';
|
||||||
import RoomListActions from '../../actions/RoomListActions';
|
import RoomListActions from '../../actions/RoomListActions';
|
||||||
|
@ -417,7 +416,6 @@ const LoggedInView = React.createClass({
|
||||||
const RoomDirectory = sdk.getComponent('structures.RoomDirectory');
|
const RoomDirectory = sdk.getComponent('structures.RoomDirectory');
|
||||||
const HomePage = sdk.getComponent('structures.HomePage');
|
const HomePage = sdk.getComponent('structures.HomePage');
|
||||||
const GroupView = sdk.getComponent('structures.GroupView');
|
const GroupView = sdk.getComponent('structures.GroupView');
|
||||||
const GroupGridView = sdk.getComponent('structures.GroupGridView');
|
|
||||||
const MyGroups = sdk.getComponent('structures.MyGroups');
|
const MyGroups = sdk.getComponent('structures.MyGroups');
|
||||||
const MatrixToolbar = sdk.getComponent('globals.MatrixToolbar');
|
const MatrixToolbar = sdk.getComponent('globals.MatrixToolbar');
|
||||||
const CookieBar = sdk.getComponent('globals.CookieBar');
|
const CookieBar = sdk.getComponent('globals.CookieBar');
|
||||||
|
@ -430,14 +428,7 @@ const LoggedInView = React.createClass({
|
||||||
|
|
||||||
switch (this.props.page_type) {
|
switch (this.props.page_type) {
|
||||||
case PageTypes.RoomView:
|
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 = <RoomView
|
page_element = <RoomView
|
||||||
roomViewStore={OpenRoomsStore.getActiveRoomStore()}
|
|
||||||
ref='roomView'
|
ref='roomView'
|
||||||
autoJoin={this.props.autoJoin}
|
autoJoin={this.props.autoJoin}
|
||||||
onRegistered={this.props.onRegistered}
|
onRegistered={this.props.onRegistered}
|
||||||
|
@ -451,9 +442,7 @@ const LoggedInView = React.createClass({
|
||||||
ConferenceHandler={this.props.ConferenceHandler}
|
ConferenceHandler={this.props.ConferenceHandler}
|
||||||
/>;
|
/>;
|
||||||
break;
|
break;
|
||||||
case PageTypes.GroupGridView:
|
|
||||||
page_element = <GroupGridView collapsedRhs={this.props.collapsedRhs} />;
|
|
||||||
break;
|
|
||||||
case PageTypes.UserSettings:
|
case PageTypes.UserSettings:
|
||||||
page_element = <UserSettings
|
page_element = <UserSettings
|
||||||
onClose={this.props.onCloseAllSettings}
|
onClose={this.props.onCloseAllSettings}
|
||||||
|
|
|
@ -71,13 +71,14 @@ export default class MainSplit extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
const shouldAllowResizing =
|
const wasExpanded = !this.props.collapsedRhs && prevProps.collapsedRhs;
|
||||||
!this.props.collapsedRhs &&
|
const wasCollapsed = this.props.collapsedRhs && !prevProps.collapsedRhs;
|
||||||
this.props.panel;
|
const wasPanelSet = this.props.panel && !prevProps.panel;
|
||||||
|
const wasPanelCleared = !this.props.panel && prevProps.panel;
|
||||||
|
|
||||||
if (shouldAllowResizing && !this.resizer) {
|
if (wasExpanded || wasPanelSet) {
|
||||||
this._createResizer();
|
this._createResizer();
|
||||||
} else if (!shouldAllowResizing && this.resizer) {
|
} else if (wasCollapsed || wasPanelCleared) {
|
||||||
this.resizer.detach();
|
this.resizer.detach();
|
||||||
this.resizer = null;
|
this.resizer = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -651,9 +651,6 @@ export default React.createClass({
|
||||||
case 'view_group':
|
case 'view_group':
|
||||||
this._viewGroup(payload);
|
this._viewGroup(payload);
|
||||||
break;
|
break;
|
||||||
case 'group_grid_view':
|
|
||||||
this._viewGroupGrid(payload);
|
|
||||||
break;
|
|
||||||
case 'view_home_page':
|
case 'view_home_page':
|
||||||
this._viewHome();
|
this._viewHome();
|
||||||
break;
|
break;
|
||||||
|
@ -865,7 +862,6 @@ export default React.createClass({
|
||||||
// room name and avatar from an invite email)
|
// room name and avatar from an invite email)
|
||||||
_viewRoom: function(roomInfo) {
|
_viewRoom: function(roomInfo) {
|
||||||
this.focusComposer = true;
|
this.focusComposer = true;
|
||||||
console.log("!!! MatrixChat._viewRoom", roomInfo);
|
|
||||||
|
|
||||||
const newState = {
|
const newState = {
|
||||||
currentRoomId: roomInfo.room_id || null,
|
currentRoomId: roomInfo.room_id || null,
|
||||||
|
@ -914,9 +910,6 @@ export default React.createClass({
|
||||||
if (roomInfo.event_id && roomInfo.highlighted) {
|
if (roomInfo.event_id && roomInfo.highlighted) {
|
||||||
presentedId += "/" + roomInfo.event_id;
|
presentedId += "/" + roomInfo.event_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: only emit this when we're not in grid mode?
|
|
||||||
this.notifyNewScreen('room/' + presentedId);
|
this.notifyNewScreen('room/' + presentedId);
|
||||||
newState.ready = true;
|
newState.ready = true;
|
||||||
this.setState(newState);
|
this.setState(newState);
|
||||||
|
@ -933,11 +926,6 @@ export default React.createClass({
|
||||||
this.notifyNewScreen('group/' + groupId);
|
this.notifyNewScreen('group/' + groupId);
|
||||||
},
|
},
|
||||||
|
|
||||||
_viewGroupGrid: function(payload) {
|
|
||||||
this._setPage(PageTypes.GroupGridView);
|
|
||||||
// this.notifyNewScreen('grid/' + payload.group_id);
|
|
||||||
},
|
|
||||||
|
|
||||||
_viewHome: function() {
|
_viewHome: function() {
|
||||||
// The home page requires the "logged in" view, so we'll set that.
|
// The home page requires the "logged in" view, so we'll set that.
|
||||||
this.setStateForNewView({
|
this.setStateForNewView({
|
||||||
|
|
|
@ -165,7 +165,7 @@ export default class RightPanel extends React.Component {
|
||||||
} else if (this.state.phase === RightPanel.Phase.GroupRoomList) {
|
} else if (this.state.phase === RightPanel.Phase.GroupRoomList) {
|
||||||
panel = <GroupRoomList groupId={this.props.groupId} key={this.props.groupId} />;
|
panel = <GroupRoomList groupId={this.props.groupId} key={this.props.groupId} />;
|
||||||
} else if (this.state.phase === RightPanel.Phase.RoomMemberInfo) {
|
} else if (this.state.phase === RightPanel.Phase.RoomMemberInfo) {
|
||||||
panel = <MemberInfo roomId={this.props.roomId} member={this.state.member} key={this.props.roomId || this.state.member.userId} />;
|
panel = <MemberInfo member={this.state.member} key={this.props.roomId || this.state.member.userId} />;
|
||||||
} else if (this.state.phase === RightPanel.Phase.GroupMemberInfo) {
|
} else if (this.state.phase === RightPanel.Phase.GroupMemberInfo) {
|
||||||
panel = <GroupMemberInfo
|
panel = <GroupMemberInfo
|
||||||
groupMember={this.state.member}
|
groupMember={this.state.member}
|
||||||
|
|
|
@ -36,6 +36,7 @@ const ContentMessages = require("../../ContentMessages");
|
||||||
const Modal = require("../../Modal");
|
const Modal = require("../../Modal");
|
||||||
const sdk = require('../../index');
|
const sdk = require('../../index');
|
||||||
const CallHandler = require('../../CallHandler');
|
const CallHandler = require('../../CallHandler');
|
||||||
|
const dis = require("../../dispatcher");
|
||||||
const Tinter = require("../../Tinter");
|
const Tinter = require("../../Tinter");
|
||||||
const rate_limited_func = require('../../ratelimitedfunc');
|
const rate_limited_func = require('../../ratelimitedfunc');
|
||||||
const ObjectUtils = require('../../ObjectUtils');
|
const ObjectUtils = require('../../ObjectUtils');
|
||||||
|
@ -45,6 +46,7 @@ import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard';
|
||||||
|
|
||||||
import MainSplit from './MainSplit';
|
import MainSplit from './MainSplit';
|
||||||
import RightPanel from './RightPanel';
|
import RightPanel from './RightPanel';
|
||||||
|
import RoomViewStore from '../../stores/RoomViewStore';
|
||||||
import RoomScrollStateStore from '../../stores/RoomScrollStateStore';
|
import RoomScrollStateStore from '../../stores/RoomScrollStateStore';
|
||||||
import WidgetEchoStore from '../../stores/WidgetEchoStore';
|
import WidgetEchoStore from '../../stores/WidgetEchoStore';
|
||||||
import SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
|
import SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
|
||||||
|
@ -92,8 +94,6 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// Servers the RoomView can use to try and assist joins
|
// Servers the RoomView can use to try and assist joins
|
||||||
viaServers: PropTypes.arrayOf(PropTypes.string),
|
viaServers: PropTypes.arrayOf(PropTypes.string),
|
||||||
// the store for this room view
|
|
||||||
roomViewStore: PropTypes.object.isRequired,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
|
@ -155,7 +155,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
this.dispatcherRef = this.props.roomViewStore.getDispatcher().register(this.onAction);
|
this.dispatcherRef = dis.register(this.onAction);
|
||||||
MatrixClientPeg.get().on("Room", this.onRoom);
|
MatrixClientPeg.get().on("Room", this.onRoom);
|
||||||
MatrixClientPeg.get().on("Room.timeline", this.onRoomTimeline);
|
MatrixClientPeg.get().on("Room.timeline", this.onRoomTimeline);
|
||||||
MatrixClientPeg.get().on("Room.name", this.onRoomName);
|
MatrixClientPeg.get().on("Room.name", this.onRoomName);
|
||||||
|
@ -166,7 +166,7 @@ module.exports = React.createClass({
|
||||||
MatrixClientPeg.get().on("crypto.keyBackupStatus", this.onKeyBackupStatus);
|
MatrixClientPeg.get().on("crypto.keyBackupStatus", this.onKeyBackupStatus);
|
||||||
this._fetchMediaConfig();
|
this._fetchMediaConfig();
|
||||||
// Start listening for RoomViewStore updates
|
// Start listening for RoomViewStore updates
|
||||||
this._roomStoreToken = this.props.roomViewStore.addListener(this._onRoomViewStoreUpdate);
|
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
|
||||||
this._onRoomViewStoreUpdate(true);
|
this._onRoomViewStoreUpdate(true);
|
||||||
|
|
||||||
WidgetEchoStore.on('update', this._onWidgetEchoStoreUpdate);
|
WidgetEchoStore.on('update', this._onWidgetEchoStoreUpdate);
|
||||||
|
@ -197,8 +197,8 @@ module.exports = React.createClass({
|
||||||
if (this.unmounted) {
|
if (this.unmounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const store = this.props.roomViewStore;
|
|
||||||
if (!initial && this.state.roomId !== store.getRoomId()) {
|
if (!initial && this.state.roomId !== RoomViewStore.getRoomId()) {
|
||||||
// RoomView explicitly does not support changing what room
|
// RoomView explicitly does not support changing what room
|
||||||
// is being viewed: instead it should just be re-mounted when
|
// is being viewed: instead it should just be re-mounted when
|
||||||
// switching rooms. Therefore, if the room ID changes, we
|
// switching rooms. Therefore, if the room ID changes, we
|
||||||
|
@ -212,21 +212,22 @@ module.exports = React.createClass({
|
||||||
// it was, it means we're about to be unmounted.
|
// it was, it means we're about to be unmounted.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newState = {
|
const newState = {
|
||||||
roomId: store.getRoomId(),
|
roomId: RoomViewStore.getRoomId(),
|
||||||
roomAlias: store.getRoomAlias(),
|
roomAlias: RoomViewStore.getRoomAlias(),
|
||||||
roomLoading: store.isRoomLoading(),
|
roomLoading: RoomViewStore.isRoomLoading(),
|
||||||
roomLoadError: store.getRoomLoadError(),
|
roomLoadError: RoomViewStore.getRoomLoadError(),
|
||||||
joining: store.isJoining(),
|
joining: RoomViewStore.isJoining(),
|
||||||
initialEventId: store.getInitialEventId(),
|
initialEventId: RoomViewStore.getInitialEventId(),
|
||||||
isInitialEventHighlighted: store.isInitialEventHighlighted(),
|
isInitialEventHighlighted: RoomViewStore.isInitialEventHighlighted(),
|
||||||
forwardingEvent: store.getForwardingEvent(),
|
forwardingEvent: RoomViewStore.getForwardingEvent(),
|
||||||
shouldPeek: store.shouldPeek(),
|
shouldPeek: RoomViewStore.shouldPeek(),
|
||||||
showingPinned: SettingsStore.getValue("PinnedEvents.isOpen", store.getRoomId()),
|
showingPinned: SettingsStore.getValue("PinnedEvents.isOpen", RoomViewStore.getRoomId()),
|
||||||
editingRoomSettings: store.isEditingSettings(),
|
editingRoomSettings: RoomViewStore.isEditingSettings(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.state.editingRoomSettings && !newState.editingRoomSettings) this.props.roomViewStore.getDispatcher().dispatch({action: 'focus_composer'});
|
if (this.state.editingRoomSettings && !newState.editingRoomSettings) dis.dispatch({action: 'focus_composer'});
|
||||||
|
|
||||||
// Temporary logging to diagnose https://github.com/vector-im/riot-web/issues/4307
|
// Temporary logging to diagnose https://github.com/vector-im/riot-web/issues/4307
|
||||||
console.log(
|
console.log(
|
||||||
|
@ -388,7 +389,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// XXX: EVIL HACK to autofocus inviting on empty rooms.
|
// XXX: EVIL HACK to autofocus inviting on empty rooms.
|
||||||
// We use the setTimeout to avoid racing with focus_composer.
|
// We use the setTimeout to avoid racing with focus_composer.
|
||||||
if (this.props.isActive !== false && this.state.room &&
|
if (this.state.room &&
|
||||||
this.state.room.getJoinedMemberCount() == 1 &&
|
this.state.room.getJoinedMemberCount() == 1 &&
|
||||||
this.state.room.getLiveTimeline() &&
|
this.state.room.getLiveTimeline() &&
|
||||||
this.state.room.getLiveTimeline().getEvents() &&
|
this.state.room.getLiveTimeline().getEvents() &&
|
||||||
|
@ -442,7 +443,7 @@ module.exports = React.createClass({
|
||||||
roomView.removeEventListener('dragleave', this.onDragLeaveOrEnd);
|
roomView.removeEventListener('dragleave', this.onDragLeaveOrEnd);
|
||||||
roomView.removeEventListener('dragend', this.onDragLeaveOrEnd);
|
roomView.removeEventListener('dragend', this.onDragLeaveOrEnd);
|
||||||
}
|
}
|
||||||
this.props.roomViewStore.getDispatcher().unregister(this.dispatcherRef);
|
dis.unregister(this.dispatcherRef);
|
||||||
if (MatrixClientPeg.get()) {
|
if (MatrixClientPeg.get()) {
|
||||||
MatrixClientPeg.get().removeListener("Room", this.onRoom);
|
MatrixClientPeg.get().removeListener("Room", this.onRoom);
|
||||||
MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
|
MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
|
||||||
|
@ -834,7 +835,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onSearchResultsResize: function() {
|
onSearchResultsResize: function() {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({ action: 'timeline_resize' }, true);
|
dis.dispatch({ action: 'timeline_resize' }, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
onSearchResultsFillRequest: function(backwards) {
|
onSearchResultsFillRequest: function(backwards) {
|
||||||
|
@ -855,7 +856,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
onInviteButtonClick: function() {
|
onInviteButtonClick: function() {
|
||||||
// call AddressPickerDialog
|
// call AddressPickerDialog
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'view_invite',
|
action: 'view_invite',
|
||||||
roomId: this.state.room.roomId,
|
roomId: this.state.room.roomId,
|
||||||
});
|
});
|
||||||
|
@ -877,7 +878,7 @@ module.exports = React.createClass({
|
||||||
// Join this room once the user has registered and logged in
|
// Join this room once the user has registered and logged in
|
||||||
const signUrl = this.props.thirdPartyInvite ?
|
const signUrl = this.props.thirdPartyInvite ?
|
||||||
this.props.thirdPartyInvite.inviteSignUrl : undefined;
|
this.props.thirdPartyInvite.inviteSignUrl : undefined;
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'do_after_sync_prepared',
|
action: 'do_after_sync_prepared',
|
||||||
deferred_action: {
|
deferred_action: {
|
||||||
action: 'join_room',
|
action: 'join_room',
|
||||||
|
@ -887,7 +888,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// Don't peek whilst registering otherwise getPendingEventList complains
|
// Don't peek whilst registering otherwise getPendingEventList complains
|
||||||
// Do this by indicating our intention to join
|
// Do this by indicating our intention to join
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'will_join',
|
action: 'will_join',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -898,20 +899,20 @@ module.exports = React.createClass({
|
||||||
if (submitted) {
|
if (submitted) {
|
||||||
this.props.onRegistered(credentials);
|
this.props.onRegistered(credentials);
|
||||||
} else {
|
} else {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'cancel_after_sync_prepared',
|
action: 'cancel_after_sync_prepared',
|
||||||
});
|
});
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'cancel_join',
|
action: 'cancel_join',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onDifferentServerClicked: (ev) => {
|
onDifferentServerClicked: (ev) => {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({action: 'start_registration'});
|
dis.dispatch({action: 'start_registration'});
|
||||||
close();
|
close();
|
||||||
},
|
},
|
||||||
onLoginClick: (ev) => {
|
onLoginClick: (ev) => {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({action: 'start_login'});
|
dis.dispatch({action: 'start_login'});
|
||||||
close();
|
close();
|
||||||
},
|
},
|
||||||
}).close;
|
}).close;
|
||||||
|
@ -921,7 +922,7 @@ module.exports = React.createClass({
|
||||||
Promise.resolve().then(() => {
|
Promise.resolve().then(() => {
|
||||||
const signUrl = this.props.thirdPartyInvite ?
|
const signUrl = this.props.thirdPartyInvite ?
|
||||||
this.props.thirdPartyInvite.inviteSignUrl : undefined;
|
this.props.thirdPartyInvite.inviteSignUrl : undefined;
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'join_room',
|
action: 'join_room',
|
||||||
opts: { inviteSignUrl: signUrl, viaServers: this.props.viaServers },
|
opts: { inviteSignUrl: signUrl, viaServers: this.props.viaServers },
|
||||||
});
|
});
|
||||||
|
@ -986,10 +987,10 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
uploadFile: async function(file) {
|
uploadFile: async function(file) {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({action: 'focus_composer'});
|
dis.dispatch({action: 'focus_composer'});
|
||||||
|
|
||||||
if (MatrixClientPeg.get().isGuest()) {
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({action: 'require_registration'});
|
dis.dispatch({action: 'require_registration'});
|
||||||
return;
|
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.
|
// 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',
|
action: 'message_sent',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
injectSticker: function(url, info, text) {
|
injectSticker: function(url, info, text) {
|
||||||
if (MatrixClientPeg.get().isGuest()) {
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({action: 'require_registration'});
|
dis.dispatch({action: 'require_registration'});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1221,7 +1222,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onSettingsClick: function() {
|
onSettingsClick: function() {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({ action: 'open_room_settings' });
|
dis.dispatch({ action: 'open_room_settings' });
|
||||||
},
|
},
|
||||||
|
|
||||||
onSettingsSaveClick: function() {
|
onSettingsSaveClick: function() {
|
||||||
|
@ -1254,31 +1255,31 @@ module.exports = React.createClass({
|
||||||
});
|
});
|
||||||
// still editing room settings
|
// still editing room settings
|
||||||
} else {
|
} else {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({ action: 'close_settings' });
|
dis.dispatch({ action: 'close_settings' });
|
||||||
}
|
}
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.setState({
|
this.setState({
|
||||||
uploadingRoomSettings: false,
|
uploadingRoomSettings: false,
|
||||||
});
|
});
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({ action: 'close_settings' });
|
dis.dispatch({ action: 'close_settings' });
|
||||||
}).done();
|
}).done();
|
||||||
},
|
},
|
||||||
|
|
||||||
onCancelClick: function() {
|
onCancelClick: function() {
|
||||||
console.log("updateTint from onCancelClick");
|
console.log("updateTint from onCancelClick");
|
||||||
this.updateTint();
|
this.updateTint();
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({ action: 'close_settings' });
|
dis.dispatch({ action: 'close_settings' });
|
||||||
if (this.state.forwardingEvent) {
|
if (this.state.forwardingEvent) {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'forward_event',
|
action: 'forward_event',
|
||||||
event: null,
|
event: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({action: 'focus_composer'});
|
dis.dispatch({action: 'focus_composer'});
|
||||||
},
|
},
|
||||||
|
|
||||||
onLeaveClick: function() {
|
onLeaveClick: function() {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'leave_room',
|
action: 'leave_room',
|
||||||
room_id: this.state.room.roomId,
|
room_id: this.state.room.roomId,
|
||||||
});
|
});
|
||||||
|
@ -1286,7 +1287,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
onForgetClick: function() {
|
onForgetClick: function() {
|
||||||
MatrixClientPeg.get().forget(this.state.room.roomId).done(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) {
|
}, function(err) {
|
||||||
const errCode = err.errcode || _t("unknown error code");
|
const errCode = err.errcode || _t("unknown error code");
|
||||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
|
@ -1303,7 +1304,7 @@ module.exports = React.createClass({
|
||||||
rejecting: true,
|
rejecting: true,
|
||||||
});
|
});
|
||||||
MatrixClientPeg.get().leave(this.state.roomId).done(function() {
|
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({
|
self.setState({
|
||||||
rejecting: false,
|
rejecting: false,
|
||||||
});
|
});
|
||||||
|
@ -1329,7 +1330,7 @@ module.exports = React.createClass({
|
||||||
// using /leave rather than /join. In the short term though, we
|
// using /leave rather than /join. In the short term though, we
|
||||||
// just ignore them.
|
// just ignore them.
|
||||||
// https://github.com/vector-im/vector-web/issues/1134
|
// https://github.com/vector-im/vector-web/issues/1134
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'view_room_directory',
|
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
|
// jump down to the bottom of this room, where new events are arriving
|
||||||
jumpToLiveTimeline: function() {
|
jumpToLiveTimeline: function() {
|
||||||
this.refs.messagePanel.jumpToLiveTimeline();
|
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
|
// jump up to wherever our read marker is
|
||||||
|
@ -1438,7 +1439,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onFullscreenClick: function() {
|
onFullscreenClick: function() {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'video_fullscreen',
|
action: 'video_fullscreen',
|
||||||
fullscreen: true,
|
fullscreen: true,
|
||||||
}, true);
|
}, true);
|
||||||
|
@ -1563,7 +1564,6 @@ module.exports = React.createClass({
|
||||||
<RoomHeader ref="header"
|
<RoomHeader ref="header"
|
||||||
room={this.state.room}
|
room={this.state.room}
|
||||||
oobData={this.props.oobData}
|
oobData={this.props.oobData}
|
||||||
isGrid={this.props.isGrid}
|
|
||||||
collapsedRhs={this.props.collapsedRhs}
|
collapsedRhs={this.props.collapsedRhs}
|
||||||
/>
|
/>
|
||||||
<div className="mx_RoomView_body">
|
<div className="mx_RoomView_body">
|
||||||
|
@ -1610,7 +1610,6 @@ module.exports = React.createClass({
|
||||||
<div className="mx_RoomView">
|
<div className="mx_RoomView">
|
||||||
<RoomHeader
|
<RoomHeader
|
||||||
ref="header"
|
ref="header"
|
||||||
isGrid={this.props.isGrid}
|
|
||||||
room={this.state.room}
|
room={this.state.room}
|
||||||
collapsedRhs={this.props.collapsedRhs}
|
collapsedRhs={this.props.collapsedRhs}
|
||||||
/>
|
/>
|
||||||
|
@ -1752,9 +1751,7 @@ module.exports = React.createClass({
|
||||||
if (canSpeak) {
|
if (canSpeak) {
|
||||||
messageComposer =
|
messageComposer =
|
||||||
<MessageComposer
|
<MessageComposer
|
||||||
roomViewStore={this.props.roomViewStore}
|
|
||||||
room={this.state.room}
|
room={this.state.room}
|
||||||
isGrid={this.props.isGrid}
|
|
||||||
onResize={this.onChildResize}
|
onResize={this.onChildResize}
|
||||||
uploadFile={this.uploadFile}
|
uploadFile={this.uploadFile}
|
||||||
callState={this.state.callState}
|
callState={this.state.callState}
|
||||||
|
@ -1881,14 +1878,11 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const rightPanel = this.state.room && !this.props.isGrid ?
|
const rightPanel = this.state.room ? <RightPanel roomId={this.state.room.roomId} /> : undefined;
|
||||||
<RightPanel roomId={this.state.room.roomId} /> :
|
|
||||||
undefined;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className={"mx_RoomView" + (inCall ? " mx_RoomView_inCall" : "")} ref="roomView">
|
<main className={"mx_RoomView" + (inCall ? " mx_RoomView_inCall" : "")} ref="roomView">
|
||||||
<RoomHeader ref="header" room={this.state.room} searchInfo={searchInfo}
|
<RoomHeader ref="header" room={this.state.room} searchInfo={searchInfo}
|
||||||
isGrid={this.props.isGrid}
|
|
||||||
oobData={this.props.oobData}
|
oobData={this.props.oobData}
|
||||||
editing={this.state.editingRoomSettings}
|
editing={this.state.editingRoomSettings}
|
||||||
saving={this.state.uploadingRoomSettings}
|
saving={this.state.uploadingRoomSettings}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import dis from '../../../dispatcher';
|
||||||
import TagOrderActions from '../../../actions/TagOrderActions';
|
import TagOrderActions from '../../../actions/TagOrderActions';
|
||||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
|
||||||
|
|
||||||
export default class TagTileContextMenu extends React.Component {
|
export default class TagTileContextMenu extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
@ -35,7 +34,6 @@ export default class TagTileContextMenu extends React.Component {
|
||||||
|
|
||||||
this._onViewCommunityClick = this._onViewCommunityClick.bind(this);
|
this._onViewCommunityClick = this._onViewCommunityClick.bind(this);
|
||||||
this._onRemoveClick = this._onRemoveClick.bind(this);
|
this._onRemoveClick = this._onRemoveClick.bind(this);
|
||||||
this._onViewAsGridClick = this._onViewAsGridClick.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onViewCommunityClick() {
|
_onViewCommunityClick() {
|
||||||
|
@ -55,28 +53,8 @@ export default class TagTileContextMenu extends React.Component {
|
||||||
this.props.onFinished();
|
this.props.onFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onViewAsGridClick() {
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'group_grid_view',
|
|
||||||
group_id: this.props.tag,
|
|
||||||
});
|
|
||||||
this.props.onFinished();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||||
let gridViewOption;
|
|
||||||
if (SettingsStore.isFeatureEnabled("feature_gridview")) {
|
|
||||||
gridViewOption = (<div className="mx_TagTileContextMenu_item" onClick={this._onViewAsGridClick} >
|
|
||||||
<TintableSvg
|
|
||||||
className="mx_TagTileContextMenu_item_icon"
|
|
||||||
src="img/feather-icons/grid.svg"
|
|
||||||
width="15"
|
|
||||||
height="15"
|
|
||||||
/>
|
|
||||||
{ _t('View as Grid') }
|
|
||||||
</div>);
|
|
||||||
}
|
|
||||||
return <div>
|
return <div>
|
||||||
<div className="mx_TagTileContextMenu_item" onClick={this._onViewCommunityClick} >
|
<div className="mx_TagTileContextMenu_item" onClick={this._onViewCommunityClick} >
|
||||||
<TintableSvg
|
<TintableSvg
|
||||||
|
@ -87,7 +65,6 @@ export default class TagTileContextMenu extends React.Component {
|
||||||
/>
|
/>
|
||||||
{ _t('View Community') }
|
{ _t('View Community') }
|
||||||
</div>
|
</div>
|
||||||
{ gridViewOption }
|
|
||||||
<hr className="mx_TagTileContextMenu_separator" />
|
<hr className="mx_TagTileContextMenu_separator" />
|
||||||
<div className="mx_TagTileContextMenu_item" onClick={this._onRemoveClick} >
|
<div className="mx_TagTileContextMenu_item" onClick={this._onRemoveClick} >
|
||||||
<img className="mx_TagTileContextMenu_item_icon" src="img/icon_context_delete.svg" width="15" height="15" />
|
<img className="mx_TagTileContextMenu_item_icon" src="img/icon_context_delete.svg" width="15" height="15" />
|
||||||
|
|
|
@ -78,6 +78,7 @@ export default class HeaderButtons extends React.Component {
|
||||||
// till show_right_panel, just without the fromHeader flag
|
// till show_right_panel, just without the fromHeader flag
|
||||||
// as that would hide the right panel again
|
// as that would hide the right panel again
|
||||||
dis.dispatch(Object.assign({}, payload, {fromHeader: false}));
|
dis.dispatch(Object.assign({}, payload, {fromHeader: false}));
|
||||||
|
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
phase: payload.phase,
|
phase: payload.phase,
|
||||||
|
|
|
@ -39,6 +39,7 @@ import Unread from '../../../Unread';
|
||||||
import { findReadReceiptFromUserId } from '../../../utils/Receipt';
|
import { findReadReceiptFromUserId } from '../../../utils/Receipt';
|
||||||
import withMatrixClient from '../../../wrappers/withMatrixClient';
|
import withMatrixClient from '../../../wrappers/withMatrixClient';
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
|
import RoomViewStore from '../../../stores/RoomViewStore';
|
||||||
import SdkConfig from '../../../SdkConfig';
|
import SdkConfig from '../../../SdkConfig';
|
||||||
import MultiInviter from "../../../utils/MultiInviter";
|
import MultiInviter from "../../../utils/MultiInviter";
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
|
@ -49,7 +50,6 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
matrixClient: PropTypes.object.isRequired,
|
matrixClient: PropTypes.object.isRequired,
|
||||||
member: PropTypes.object.isRequired,
|
member: PropTypes.object.isRequired,
|
||||||
roomId: PropTypes.string,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
|
@ -713,7 +713,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!member || !member.membership || member.membership === 'leave') {
|
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 () => {
|
const onInviteUserButton = async () => {
|
||||||
try {
|
try {
|
||||||
// We use a MultiInviter to re-use the invite logic, even though
|
// We use a MultiInviter to re-use the invite logic, even though
|
||||||
|
|
|
@ -22,6 +22,7 @@ import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||||
import Modal from '../../../Modal';
|
import Modal from '../../../Modal';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import dis from '../../../dispatcher';
|
import dis from '../../../dispatcher';
|
||||||
|
import RoomViewStore from '../../../stores/RoomViewStore';
|
||||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||||
import Stickerpicker from './Stickerpicker';
|
import Stickerpicker from './Stickerpicker';
|
||||||
import { makeRoomPermalink } from '../../../matrix-to';
|
import { makeRoomPermalink } from '../../../matrix-to';
|
||||||
|
@ -62,7 +63,7 @@ export default class MessageComposer extends React.Component {
|
||||||
isRichTextEnabled: SettingsStore.getValue('MessageComposerInput.isRichTextEnabled'),
|
isRichTextEnabled: SettingsStore.getValue('MessageComposerInput.isRichTextEnabled'),
|
||||||
},
|
},
|
||||||
showFormatting: SettingsStore.getValue('MessageComposer.showFormatting'),
|
showFormatting: SettingsStore.getValue('MessageComposer.showFormatting'),
|
||||||
isQuoting: Boolean(this.props.roomViewStore.getQuotingEvent()),
|
isQuoting: Boolean(RoomViewStore.getQuotingEvent()),
|
||||||
tombstone: this._getRoomTombstone(),
|
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.
|
// 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("event", this.onEvent);
|
||||||
MatrixClientPeg.get().on("RoomState.events", this._onRoomStateEvents);
|
MatrixClientPeg.get().on("RoomState.events", this._onRoomStateEvents);
|
||||||
this._roomStoreToken = this.props.roomViewStore.addListener(this._onRoomViewStoreUpdate);
|
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
|
||||||
this._waitForOwnMember();
|
this._waitForOwnMember();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,14 +124,14 @@ export default class MessageComposer extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
_onRoomViewStoreUpdate() {
|
_onRoomViewStoreUpdate() {
|
||||||
const isQuoting = Boolean(this.props.roomViewStore.getQuotingEvent());
|
const isQuoting = Boolean(RoomViewStore.getQuotingEvent());
|
||||||
if (this.state.isQuoting === isQuoting) return;
|
if (this.state.isQuoting === isQuoting) return;
|
||||||
this.setState({ isQuoting });
|
this.setState({ isQuoting });
|
||||||
}
|
}
|
||||||
|
|
||||||
onUploadClick(ev) {
|
onUploadClick(ev) {
|
||||||
if (MatrixClientPeg.get().isGuest()) {
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({action: 'require_registration'});
|
dis.dispatch({action: 'require_registration'});
|
||||||
return;
|
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;
|
let replyToWarning = null;
|
||||||
if (isQuoting) {
|
if (isQuoting) {
|
||||||
replyToWarning = <p>{
|
replyToWarning = <p>{
|
||||||
|
@ -228,7 +229,7 @@ export default class MessageComposer extends React.Component {
|
||||||
if (!call) {
|
if (!call) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'hangup',
|
action: 'hangup',
|
||||||
// hangup the call for this room, which may not be the room in props
|
// 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)
|
// (e.g. conferences which will hangup the 1:1 room instead)
|
||||||
|
@ -237,7 +238,7 @@ export default class MessageComposer extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
onCallClick(ev) {
|
onCallClick(ev) {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'place_call',
|
action: 'place_call',
|
||||||
type: ev.shiftKey ? "screensharing" : "video",
|
type: ev.shiftKey ? "screensharing" : "video",
|
||||||
room_id: this.props.room.roomId,
|
room_id: this.props.room.roomId,
|
||||||
|
@ -245,7 +246,7 @@ export default class MessageComposer extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
onVoiceCallClick(ev) {
|
onVoiceCallClick(ev) {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'place_call',
|
action: 'place_call',
|
||||||
type: "voice",
|
type: "voice",
|
||||||
room_id: this.props.room.roomId,
|
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', '');
|
const createEvent = replacementRoom.currentState.getStateEvents('m.room.create', '');
|
||||||
if (createEvent && createEvent.getId()) createEventId = createEvent.getId();
|
if (createEvent && createEvent.getId()) createEventId = createEvent.getId();
|
||||||
}
|
}
|
||||||
|
dis.dispatch({
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
|
||||||
action: 'view_room',
|
action: 'view_room',
|
||||||
highlighted: true,
|
highlighted: true,
|
||||||
event_id: createEventId,
|
event_id: createEventId,
|
||||||
|
@ -432,10 +432,8 @@ export default class MessageComposer extends React.Component {
|
||||||
|
|
||||||
controls.push(
|
controls.push(
|
||||||
<MessageComposerInput
|
<MessageComposerInput
|
||||||
roomViewStore={this.props.roomViewStore}
|
|
||||||
ref={(c) => this.messageComposerInput = c}
|
ref={(c) => this.messageComposerInput = c}
|
||||||
key="controls_input"
|
key="controls_input"
|
||||||
isGrid={this.props.isGrid}
|
|
||||||
onResize={this.props.onResize}
|
onResize={this.props.onResize}
|
||||||
room={this.props.room}
|
room={this.props.room}
|
||||||
placeholder={placeholderText}
|
placeholder={placeholderText}
|
||||||
|
@ -542,6 +540,5 @@ MessageComposer.propTypes = {
|
||||||
uploadAllowed: PropTypes.func.isRequired,
|
uploadAllowed: PropTypes.func.isRequired,
|
||||||
|
|
||||||
// string representing the current room app drawer state
|
// string representing the current room app drawer state
|
||||||
showApps: PropTypes.bool,
|
showApps: PropTypes.bool
|
||||||
roomViewStore: PropTypes.object.isRequired,
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,6 +38,8 @@ import sdk from '../../../index';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import Analytics from '../../../Analytics';
|
import Analytics from '../../../Analytics';
|
||||||
|
|
||||||
|
import dis from '../../../dispatcher';
|
||||||
|
|
||||||
import * as RichText from '../../../RichText';
|
import * as RichText from '../../../RichText';
|
||||||
import * as HtmlUtils from '../../../HtmlUtils';
|
import * as HtmlUtils from '../../../HtmlUtils';
|
||||||
import Autocomplete from './Autocomplete';
|
import Autocomplete from './Autocomplete';
|
||||||
|
@ -55,6 +57,7 @@ import {
|
||||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||||
import {makeUserPermalink} from "../../../matrix-to";
|
import {makeUserPermalink} from "../../../matrix-to";
|
||||||
import ReplyPreview from "./ReplyPreview";
|
import ReplyPreview from "./ReplyPreview";
|
||||||
|
import RoomViewStore from '../../../stores/RoomViewStore';
|
||||||
import ReplyThread from "../elements/ReplyThread";
|
import ReplyThread from "../elements/ReplyThread";
|
||||||
import {ContentHelpers} from 'matrix-js-sdk';
|
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 {
|
function rangeEquals(a: Range, b: Range): boolean {
|
||||||
return (a.anchor.key === b.anchor.key
|
return (a.anchor.key === b.anchor.key
|
||||||
&& a.anchor.offset === b.anchorOffset
|
&& a.anchor.offset === b.anchorOffset
|
||||||
|
@ -117,18 +129,6 @@ function rangeEquals(a: Range, b: Range): boolean {
|
||||||
&& a.isBackward === b.isBackward);
|
&& 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
|
* The textInput part of the MessageComposer
|
||||||
*/
|
*/
|
||||||
|
@ -144,7 +144,6 @@ export default class MessageComposerInput extends React.Component {
|
||||||
onFilesPasted: PropTypes.func,
|
onFilesPasted: PropTypes.func,
|
||||||
|
|
||||||
onInputStateChanged: PropTypes.func,
|
onInputStateChanged: PropTypes.func,
|
||||||
roomViewStore: PropTypes.object.isRequired,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
client: MatrixClient;
|
client: MatrixClient;
|
||||||
|
@ -339,31 +338,18 @@ export default class MessageComposerInput extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
this.dispatcherRef = this.props.roomViewStore.getDispatcher().register(this.onAction);
|
this.dispatcherRef = dis.register(this.onAction);
|
||||||
if (this.props.isGrid) {
|
this.historyManager = new ComposerHistoryManager(this.props.room.roomId, 'mx_slate_composer_history_');
|
||||||
this.historyManager = new NoopHistoryManager();
|
|
||||||
} else {
|
|
||||||
this.historyManager = new ComposerHistoryManager(this.props.room.roomId, 'mx_slate_composer_history_');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.props.roomViewStore.getDispatcher().unregister(this.dispatcherRef);
|
dis.unregister(this.dispatcherRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
_collectEditor = (e) => {
|
_collectEditor = (e) => {
|
||||||
this._editor = 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) => {
|
onAction = (payload) => {
|
||||||
const editorState = this.state.editorState;
|
const editorState = this.state.editorState;
|
||||||
|
|
||||||
|
@ -1129,7 +1115,7 @@ export default class MessageComposerInput extends React.Component {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const replyingToEv = this.props.roomViewStore.getQuotingEvent();
|
const replyingToEv = RoomViewStore.getQuotingEvent();
|
||||||
const mustSendHTML = Boolean(replyingToEv);
|
const mustSendHTML = Boolean(replyingToEv);
|
||||||
|
|
||||||
if (this.state.isRichTextEnabled) {
|
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
|
// Clear reply_to_event as we put the message into the queue
|
||||||
// if the send fails, retry will handle resending.
|
// if the send fails, retry will handle resending.
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'reply_to_event',
|
action: 'reply_to_event',
|
||||||
event: null,
|
event: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.client.sendMessage(this.props.room.roomId, content).then((res) => {
|
this.client.sendMessage(this.props.room.roomId, content).then((res) => {
|
||||||
this.props.roomViewStore.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'message_sent',
|
action: 'message_sent',
|
||||||
});
|
});
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
this.onSendMessageFailed(e, this.props.room);
|
onSendMessageFailed(e, this.props.room);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -1599,7 +1585,7 @@ export default class MessageComposerInput extends React.Component {
|
||||||
return (
|
return (
|
||||||
<div className="mx_MessageComposer_input_wrapper" onClick={this.focusComposer}>
|
<div className="mx_MessageComposer_input_wrapper" onClick={this.focusComposer}>
|
||||||
<div className="mx_MessageComposer_autocomplete_wrapper">
|
<div className="mx_MessageComposer_autocomplete_wrapper">
|
||||||
<ReplyPreview roomViewStore={this.props.roomViewStore} />
|
<ReplyPreview />
|
||||||
<Autocomplete
|
<Autocomplete
|
||||||
ref={(e) => this.autocomplete = e}
|
ref={(e) => this.autocomplete = e}
|
||||||
room={this.props.room}
|
room={this.props.room}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import React from 'react';
|
||||||
import dis from '../../../dispatcher';
|
import dis from '../../../dispatcher';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
import RoomViewStore from '../../../stores/RoomViewStore';
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
|
|
||||||
function cancelQuoting() {
|
function cancelQuoting() {
|
||||||
|
@ -37,7 +38,7 @@ export default class ReplyPreview extends React.Component {
|
||||||
|
|
||||||
this._onRoomViewStoreUpdate = this._onRoomViewStoreUpdate.bind(this);
|
this._onRoomViewStoreUpdate = this._onRoomViewStoreUpdate.bind(this);
|
||||||
|
|
||||||
this._roomStoreToken = this.props.roomViewStore.addListener(this._onRoomViewStoreUpdate);
|
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
|
||||||
this._onRoomViewStoreUpdate();
|
this._onRoomViewStoreUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +50,7 @@ export default class ReplyPreview extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
_onRoomViewStoreUpdate() {
|
_onRoomViewStoreUpdate() {
|
||||||
const event = this.props.roomViewStore.getQuotingEvent();
|
const event = RoomViewStore.getQuotingEvent();
|
||||||
if (this.state.event !== event) {
|
if (this.state.event !== event) {
|
||||||
this.setState({ event });
|
this.setState({ event });
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import { _t } from '../../../languageHandler';
|
||||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||||
import Modal from "../../../Modal";
|
import Modal from "../../../Modal";
|
||||||
import RateLimitedFunc from '../../../ratelimitedfunc';
|
import RateLimitedFunc from '../../../ratelimitedfunc';
|
||||||
import dis from '../../../dispatcher';
|
|
||||||
|
|
||||||
import * as linkify from 'linkifyjs';
|
import * as linkify from 'linkifyjs';
|
||||||
import linkifyElement from 'linkifyjs/element';
|
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() {
|
_hasUnreadPins: function() {
|
||||||
const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
|
const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
|
||||||
if (!currentPinEvent) return false;
|
if (!currentPinEvent) return false;
|
||||||
|
@ -418,17 +409,6 @@ module.exports = React.createClass({
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
let toggleRightPanelButton;
|
|
||||||
if (this.props.isGrid) {
|
|
||||||
toggleRightPanelButton =
|
|
||||||
<AccessibleButton
|
|
||||||
className="mx_RoomHeader_button"
|
|
||||||
onClick={this.onToggleRightPanelClick}
|
|
||||||
title={_t('Toggle right panel')}>
|
|
||||||
<TintableSvg src="img/feather-icons/toggle-right-panel.svg" width="20" height="20" />
|
|
||||||
</AccessibleButton>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={"mx_RoomHeader light-panel " + (this.props.editing ? "mx_RoomHeader_editing" : "")}>
|
<div className={"mx_RoomHeader light-panel " + (this.props.editing ? "mx_RoomHeader_editing" : "")}>
|
||||||
<div className="mx_RoomHeader_wrapper">
|
<div className="mx_RoomHeader_wrapper">
|
||||||
|
@ -439,8 +419,7 @@ module.exports = React.createClass({
|
||||||
{ saveButton }
|
{ saveButton }
|
||||||
{ cancelButton }
|
{ cancelButton }
|
||||||
{ rightRow }
|
{ rightRow }
|
||||||
{ !this.props.isGrid ? <RoomHeaderButtons collapsedRhs={this.props.collapsedRhs} /> : undefined }
|
<RoomHeaderButtons collapsedRhs={this.props.collapsedRhs} />
|
||||||
{ toggleRightPanelButton }
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -29,6 +29,7 @@ import * as RoomNotifs from '../../../RoomNotifs';
|
||||||
import * as FormattingUtils from '../../../utils/FormattingUtils';
|
import * as FormattingUtils from '../../../utils/FormattingUtils';
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
import ActiveRoomObserver from '../../../ActiveRoomObserver';
|
import ActiveRoomObserver from '../../../ActiveRoomObserver';
|
||||||
|
import RoomViewStore from '../../../stores/RoomViewStore';
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
|
@ -61,7 +62,7 @@ module.exports = React.createClass({
|
||||||
roomName: this.props.room.name,
|
roomName: this.props.room.name,
|
||||||
notifState: RoomNotifs.getRoomNotifsState(this.props.room.roomId),
|
notifState: RoomNotifs.getRoomNotifsState(this.props.room.roomId),
|
||||||
notificationCount: this.props.room.getUnreadNotificationCount(),
|
notificationCount: this.props.room.getUnreadNotificationCount(),
|
||||||
selected: this.props.room.roomId === ActiveRoomObserver.getActiveRoomId(),
|
selected: this.props.room.roomId === RoomViewStore.getRoomId(),
|
||||||
statusMessage: this._getStatusMessage(),
|
statusMessage: this._getStatusMessage(),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -150,9 +151,9 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_onActiveRoomChange: function(activeRoomId) {
|
_onActiveRoomChange: function() {
|
||||||
this.setState({
|
this.setState({
|
||||||
selected: this.props.room.roomId === activeRoomId,
|
selected: this.props.room.roomId === RoomViewStore.getRoomId(),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,42 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'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) {
|
if (global.mxDispatcher === undefined) {
|
||||||
global.mxDispatcher = new MatrixDispatcher();
|
global.mxDispatcher = new MatrixDispatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = global.mxDispatcher;
|
module.exports = global.mxDispatcher;
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -110,12 +110,6 @@ export const SETTINGS = {
|
||||||
supportedLevels: LEVELS_FEATURE,
|
supportedLevels: LEVELS_FEATURE,
|
||||||
default: false,
|
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": {
|
"MessageComposerInput.dontSuggestEmoji": {
|
||||||
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||||
displayName: _td('Disable Emoji suggestions while typing'),
|
displayName: _td('Disable Emoji suggestions while typing'),
|
||||||
|
|
|
@ -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;
|
|
|
@ -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
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
import dis from '../dispatcher';
|
||||||
import {Store} from 'flux/utils';
|
import {Store} from 'flux/utils';
|
||||||
import MatrixClientPeg from '../MatrixClientPeg';
|
import MatrixClientPeg from '../MatrixClientPeg';
|
||||||
import sdk from '../index';
|
import sdk from '../index';
|
||||||
|
@ -52,12 +53,12 @@ const INITIAL_STATE = {
|
||||||
* with a subset of the js-sdk.
|
* with a subset of the js-sdk.
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export class RoomViewStore extends Store {
|
class RoomViewStore extends Store {
|
||||||
constructor(dispatcher) {
|
constructor() {
|
||||||
super(dispatcher);
|
super(dis);
|
||||||
|
|
||||||
// Initialise state
|
// Initialise state
|
||||||
this._state = Object.assign({}, INITIAL_STATE);
|
this._state = INITIAL_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_setState(newState) {
|
_setState(newState) {
|
||||||
|
@ -84,8 +85,6 @@ export class RoomViewStore extends Store {
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'view_room_error':
|
case 'view_room_error':
|
||||||
// should not go over dispatcher anymore
|
|
||||||
// but be internal to RoomViewStore
|
|
||||||
this._viewRoomError(payload);
|
this._viewRoomError(payload);
|
||||||
break;
|
break;
|
||||||
case 'will_join':
|
case 'will_join':
|
||||||
|
@ -151,11 +150,22 @@ export class RoomViewStore extends Store {
|
||||||
// pull the user out of Room Settings
|
// pull the user out of Room Settings
|
||||||
isEditingSettings: false,
|
isEditingSettings: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (this._state.forwardingEvent) {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'send_event',
|
||||||
|
room_id: newState.roomId,
|
||||||
|
event: this._state.forwardingEvent,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this._setState(newState);
|
this._setState(newState);
|
||||||
|
|
||||||
if (payload.auto_join) {
|
if (payload.auto_join) {
|
||||||
this._joinRoom(payload);
|
this._joinRoom(payload);
|
||||||
}
|
}
|
||||||
} else if (payload.room_alias) {
|
} else if (payload.room_alias) {
|
||||||
|
// Resolve the alias and then do a second dispatch with the room ID acquired
|
||||||
this._setState({
|
this._setState({
|
||||||
roomId: null,
|
roomId: null,
|
||||||
initialEventId: null,
|
initialEventId: null,
|
||||||
|
@ -165,6 +175,25 @@ export class RoomViewStore extends Store {
|
||||||
roomLoading: true,
|
roomLoading: true,
|
||||||
roomLoadError: null,
|
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
|
// stream yet, and that's the point at which we'd consider
|
||||||
// the user joined to the room.
|
// the user joined to the room.
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
this.getDispatcher().dispatch({
|
dis.dispatch({
|
||||||
action: 'join_room_error',
|
action: 'join_room_error',
|
||||||
err: err,
|
err: err,
|
||||||
});
|
});
|
||||||
|
@ -306,7 +335,8 @@ export class RoomViewStore extends Store {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const MatrixDispatcher = require("../matrix-dispatcher");
|
let singletonRoomViewStore = null;
|
||||||
const backwardsCompatInstance = new RoomViewStore(new MatrixDispatcher());
|
if (!singletonRoomViewStore) {
|
||||||
|
singletonRoomViewStore = new RoomViewStore();
|
||||||
export default backwardsCompatInstance;
|
}
|
||||||
|
module.exports = singletonRoomViewStore;
|
||||||
|
|
|
@ -26,6 +26,7 @@ Once a timer is finished or aborted, it can't be started again
|
||||||
a new one through `clone()` or `cloneIfRun()`.
|
a new one through `clone()` or `cloneIfRun()`.
|
||||||
*/
|
*/
|
||||||
export default class Timer {
|
export default class Timer {
|
||||||
|
|
||||||
constructor(timeout) {
|
constructor(timeout) {
|
||||||
this._timeout = timeout;
|
this._timeout = timeout;
|
||||||
this._onTimeout = this._onTimeout.bind(this);
|
this._onTimeout = this._onTimeout.bind(this);
|
||||||
|
|
Loading…
Reference in New Issue