Merge branch 'develop' into joriks/room-list-voip

pull/21833/head
Jorik Schellekens 2020-07-07 15:45:45 +01:00 committed by GitHub
commit dad3dce364
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 94 additions and 39 deletions

View File

@ -19,7 +19,6 @@ limitations under the License.
import * as React from 'react';
import * as PropTypes from 'prop-types';
import { MatrixClient } from 'matrix-js-sdk/src/client';
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
import { DragDropContext } from 'react-beautiful-dnd';
import {Key, isOnlyCtrlOrCmdKeyEvent, isOnlyCtrlOrCmdIgnoreShiftKeyEvent} from '../../Keyboard';
@ -54,6 +53,7 @@ import {
import { Action } from "../../dispatcher/actions";
import LeftPanel2 from "./LeftPanel2";
import CallContainer from '../views/voip/CallContainer';
import { ViewRoomDeltaPayload } from "../../dispatcher/payloads/ViewRoomDeltaPayload";
// We need to fetch each pinned message individually (if we don't already have it)
// so each pinned message may trigger a request. Limit the number per room for sanity.
@ -410,20 +410,6 @@ class LoggedInView extends React.Component<IProps, IState> {
};
_onKeyDown = (ev) => {
/*
// Remove this for now as ctrl+alt = alt-gr so this breaks keyboards which rely on alt-gr for numbers
// Will need to find a better meta key if anyone actually cares about using this.
if (ev.altKey && ev.ctrlKey && ev.keyCode > 48 && ev.keyCode < 58) {
dis.dispatch({
action: 'view_indexed_room',
roomIndex: ev.keyCode - 49,
});
ev.stopPropagation();
ev.preventDefault();
return;
}
*/
let handled = false;
const ctrlCmdOnly = isOnlyCtrlOrCmdKeyEvent(ev);
const hasModifier = ev.altKey || ev.ctrlKey || ev.metaKey || ev.shiftKey;
@ -475,8 +461,8 @@ class LoggedInView extends React.Component<IProps, IState> {
case Key.ARROW_UP:
case Key.ARROW_DOWN:
if (ev.altKey && !ev.ctrlKey && !ev.metaKey) {
dis.dispatch({
action: 'view_room_delta',
dis.dispatch<ViewRoomDeltaPayload>({
action: Action.ViewRoomDelta,
delta: ev.key === Key.ARROW_UP ? -1 : 1,
unread: ev.shiftKey,
});

View File

@ -596,15 +596,9 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
break;
}
case 'view_prev_room':
this.viewNextRoom(-1);
break;
case 'view_next_room':
this.viewNextRoom(1);
break;
case 'view_indexed_room':
this.viewIndexedRoom(payload.roomIndex);
break;
case Action.ViewUserSettings: {
const tabPayload = payload as OpenToTabPayload;
const UserSettingsDialog = sdk.getComponent("dialogs.UserSettingsDialog");
@ -812,19 +806,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
});
}
// TODO: Move to RoomViewStore
private viewIndexedRoom(roomIndex: number) {
const allRooms = RoomListSorter.mostRecentActivityFirst(
MatrixClientPeg.get().getRooms(),
);
if (allRooms[roomIndex]) {
dis.dispatch({
action: 'view_room',
room_id: allRooms[roomIndex].roomId,
});
}
}
// switch view to the given room
//
// @param {Object} roomInfo Object containing data about the room to be joined

View File

@ -17,13 +17,16 @@ limitations under the License.
*/
import * as React from "react";
import { Dispatcher } from "flux";
import { Room } from "matrix-js-sdk/src/models/room";
import { _t, _td } from "../../../languageHandler";
import { RovingTabIndexProvider } from "../../../accessibility/RovingTabIndex";
import { ResizeNotifier } from "../../../utils/ResizeNotifier";
import RoomListStore, { LISTS_UPDATE_EVENT, RoomListStore2 } from "../../../stores/room-list/RoomListStore2";
import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore2";
import RoomViewStore from "../../../stores/RoomViewStore";
import { ITagMap } from "../../../stores/room-list/algorithms/models";
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
import { Dispatcher } from "flux";
import dis from "../../../dispatcher/dispatcher";
import defaultDispatcher from "../../../dispatcher/dispatcher";
import RoomSublist2 from "./RoomSublist2";
@ -35,6 +38,9 @@ import GroupAvatar from "../avatars/GroupAvatar";
import TemporaryTile from "./TemporaryTile";
import { StaticNotificationState } from "../../../stores/notifications/StaticNotificationState";
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
import { TagSpecificNotificationState } from "../../../stores/notifications/TagSpecificNotificationState";
import { Action } from "../../../dispatcher/actions";
import { ViewRoomDeltaPayload } from "../../../dispatcher/payloads/ViewRoomDeltaPayload";
// TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14231
// TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231
@ -138,6 +144,7 @@ const TAG_AESTHETICS: {
export default class RoomList2 extends React.Component<IProps, IState> {
private searchFilter: NameFilterCondition = new NameFilterCondition();
private dispatcherRef;
constructor(props: IProps) {
super(props);
@ -146,6 +153,8 @@ export default class RoomList2 extends React.Component<IProps, IState> {
sublists: {},
layouts: new Map<TagID, ListLayout>(),
};
this.dispatcherRef = defaultDispatcher.register(this.onAction);
}
public componentDidUpdate(prevProps: Readonly<IProps>): void {
@ -170,8 +179,50 @@ export default class RoomList2 extends React.Component<IProps, IState> {
public componentWillUnmount() {
RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.updateLists);
defaultDispatcher.unregister(this.dispatcherRef);
}
private onAction = (payload: ActionPayload) => {
if (payload.action === Action.ViewRoomDelta) {
const viewRoomDeltaPayload = payload as ViewRoomDeltaPayload;
const currentRoomId = RoomViewStore.getRoomId();
const room = this.getRoomDelta(currentRoomId, viewRoomDeltaPayload.delta, viewRoomDeltaPayload.unread);
if (room) {
dis.dispatch({
action: 'view_room',
room_id: room.roomId,
show_room_tile: true, // to make sure the room gets scrolled into view
});
}
}
};
private getRoomDelta = (roomId: string, delta: number, unread = false) => {
const lists = RoomListStore.instance.orderedLists;
let rooms: Room = [];
TAG_ORDER.forEach(t => {
let listRooms = lists[t];
if (unread) {
// TODO Be smarter and not spin up a bunch of wasted listeners just to kill them 4 lines later
// https://github.com/vector-im/riot-web/issues/14035
const notificationStates = rooms.map(r => new TagSpecificNotificationState(r, t));
// filter to only notification rooms (and our current active room so we can index properly)
listRooms = notificationStates.filter(state => {
return state.room.roomId === roomId || state.color >= NotificationColor.Bold;
});
notificationStates.forEach(state => state.destroy());
}
rooms.push(...listRooms);
});
const currentIndex = rooms.findIndex(r => r.roomId === roomId);
// use slice to account for looping around the start
const [room] = rooms.slice((currentIndex + delta) % rooms.length);
return room;
};
private updateLists = () => {
const newLists = RoomListStore.instance.orderedLists;
console.log("new lists", newLists);

View File

@ -79,4 +79,9 @@ export enum Action {
* Sets a system font. Should be used with UpdateSystemFontPayload
*/
UpdateSystemFont = "update_system_font",
/**
* Changes room based on room list order and payload parameters. Should be used with ViewRoomDeltaPayload.
*/
ViewRoomDelta = "view_room_delta",
}

View File

@ -0,0 +1,32 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
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 { ActionPayload } from "../payloads";
import { Action } from "../actions";
export interface ViewRoomDeltaPayload extends ActionPayload {
action: Action.ViewRoomDelta;
/**
* The delta index of the room to view.
*/
delta: number;
/**
* Optionally, whether or not to filter to unread (Bold/Grey/Red) rooms only. (Default: false)
*/
unread?: boolean;
}

View File

@ -31,7 +31,7 @@ export class RoomNotificationState extends EventEmitter implements IDestroyable,
private _count: number;
private _color: NotificationColor;
constructor(private room: Room) {
constructor(public readonly room: Room) {
super();
this.room.on("Room.receipt", this.handleReadReceipt);
this.room.on("Room.timeline", this.handleRoomEventUpdate);