Merge branch 'develop' into travis/skinning/pt3-easy-comps

This commit is contained in:
Travis Ralston 2021-03-10 12:30:06 -07:00
commit e5180a472f
39 changed files with 2446 additions and 960 deletions

View file

@ -16,9 +16,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import * as React from "react";
import React, { ReactComponentElement } from "react";
import { Dispatcher } from "flux";
import { Room } from "matrix-js-sdk/src/models/room";
import * as fbEmitter from "fbemitter";
import { _t, _td } from "../../../languageHandler";
import { RovingTabIndexProvider } from "../../../accessibility/RovingTabIndex";
@ -33,7 +34,7 @@ import RoomSublist from "./RoomSublist";
import { ActionPayload } from "../../../dispatcher/payloads";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import GroupAvatar from "../avatars/GroupAvatar";
import TemporaryTile from "./TemporaryTile";
import ExtraTile from "./ExtraTile";
import { StaticNotificationState } from "../../../stores/notifications/StaticNotificationState";
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
import { Action } from "../../../dispatcher/actions";
@ -47,10 +48,12 @@ import { IconizedContextMenuOption, IconizedContextMenuOptionList } from "../con
import AccessibleButton from "../elements/AccessibleButton";
import { CommunityPrototypeStore } from "../../../stores/CommunityPrototypeStore";
import CallHandler from "../../../CallHandler";
import SpaceStore from "../../../stores/SpaceStore";
import SpaceStore, { SUGGESTED_ROOMS } from "../../../stores/SpaceStore";
import { showAddExistingRooms, showCreateNewRoom } from "../../../utils/space";
import { EventType } from "matrix-js-sdk/src/@types/event";
import {replaceableComponent} from "../../../utils/replaceableComponent";
import RoomAvatar from "../avatars/RoomAvatar";
import { ISpaceSummaryRoom } from "../../structures/SpaceRoomDirectory";
interface IProps {
onKeyDown: (ev: React.KeyboardEvent) => void;
@ -64,6 +67,8 @@ interface IProps {
interface IState {
sublists: ITagMap;
isNameFiltering: boolean;
currentRoomId?: string;
suggestedRooms: ISpaceSummaryRoom[];
}
const TAG_ORDER: TagID[] = [
@ -76,6 +81,7 @@ const TAG_ORDER: TagID[] = [
DefaultTagID.LowPriority,
DefaultTagID.ServerNotice,
DefaultTagID.Suggested,
DefaultTagID.Archived,
];
const CUSTOM_TAGS_BEFORE_TAG = DefaultTagID.LowPriority;
@ -243,6 +249,12 @@ const TAG_AESTHETICS: ITagAestheticsMap = {
isInvite: false,
defaultHidden: true,
},
[DefaultTagID.Suggested]: {
sectionLabel: _td("Suggested Rooms"),
isInvite: false,
defaultHidden: false,
},
};
function customTagAesthetics(tagId: TagID): ITagAesthetics {
@ -262,6 +274,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
private dispatcherRef;
private customTagStoreRef;
private tagAesthetics: ITagAestheticsMap;
private roomStoreToken: fbEmitter.EventSubscription;
constructor(props: IProps) {
super(props);
@ -269,6 +282,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
this.state = {
sublists: {},
isNameFiltering: !!RoomListStore.instance.getFirstNameFilterCondition(),
suggestedRooms: SpaceStore.instance.suggestedRooms,
};
// shallow-copy from the template as we need to make modifications to it
@ -276,20 +290,30 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
this.updateDmAddRoomAction();
this.dispatcherRef = defaultDispatcher.register(this.onAction);
this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate);
}
public componentDidMount(): void {
SpaceStore.instance.on(SUGGESTED_ROOMS, this.updateSuggestedRooms);
RoomListStore.instance.on(LISTS_UPDATE_EVENT, this.updateLists);
this.customTagStoreRef = CustomRoomTagStore.addListener(this.updateLists);
this.updateLists(); // trigger the first update
}
public componentWillUnmount() {
SpaceStore.instance.off(SUGGESTED_ROOMS, this.updateSuggestedRooms);
RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.updateLists);
defaultDispatcher.unregister(this.dispatcherRef);
if (this.customTagStoreRef) this.customTagStoreRef.remove();
if (this.roomStoreToken) this.roomStoreToken.remove();
}
private onRoomViewStoreUpdate = () => {
this.setState({
currentRoomId: RoomViewStore.getRoomId(),
});
};
private updateDmAddRoomAction() {
const dmTagAesthetics = objectShallowClone(TAG_AESTHETICS[DefaultTagID.DM]);
if (CallHandler.sharedInstance().getSupportsPstnProtocol()) {
@ -321,7 +345,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
private getRoomDelta = (roomId: string, delta: number, unread = false) => {
const lists = RoomListStore.instance.orderedLists;
const rooms: Room = [];
const rooms: Room[] = [];
TAG_ORDER.forEach(t => {
let listRooms = lists[t];
@ -342,6 +366,10 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
return room;
};
private updateSuggestedRooms = (suggestedRooms: ISpaceSummaryRoom[]) => {
this.setState({ suggestedRooms });
};
private updateLists = () => {
const newLists = RoomListStore.instance.orderedLists;
if (SettingsStore.getValue("advancedRoomListLogging")) {
@ -396,7 +424,44 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
dis.dispatch({ action: Action.ViewRoomDirectory, initialText });
};
private renderCommunityInvites(): TemporaryTile[] {
private renderSuggestedRooms(): ReactComponentElement<typeof ExtraTile>[] {
return this.state.suggestedRooms.map(room => {
const name = room.name || room.canonical_alias || room.aliases.pop() || _t("Empty room");
const avatar = (
<RoomAvatar
oobData={{
name,
avatarUrl: room.avatar_url,
}}
width={32}
height={32}
resizeMethod="crop"
/>
);
const viewRoom = () => {
defaultDispatcher.dispatch({
action: "view_room",
room_id: room.room_id,
oobData: {
avatarUrl: room.avatar_url,
name,
},
});
};
return (
<ExtraTile
isMinimized={this.props.isMinimized}
isSelected={this.state.currentRoomId === room.room_id}
displayName={name}
avatar={avatar}
onClick={viewRoom}
key={`suggestedRoomTile_${room.room_id}`}
/>
);
});
}
private renderCommunityInvites(): ReactComponentElement<typeof ExtraTile>[] {
// TODO: Put community invites in a more sensible place (not in the room list)
// See https://github.com/vector-im/element-web/issues/14456
return MatrixClientPeg.get().getGroups().filter(g => {
@ -417,7 +482,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
});
};
return (
<TemporaryTile
<ExtraTile
isMinimized={this.props.isMinimized}
isSelected={false}
displayName={g.name}
@ -449,7 +514,14 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
for (const orderedTagId of tagOrder) {
const orderedRooms = this.state.sublists[orderedTagId] || [];
const extraTiles = orderedTagId === DefaultTagID.Invite ? this.renderCommunityInvites() : null;
let extraTiles = null;
if (orderedTagId === DefaultTagID.Invite) {
extraTiles = this.renderCommunityInvites();
} else if (orderedTagId === DefaultTagID.Suggested) {
extraTiles = this.renderSuggestedRooms();
}
const totalTiles = orderedRooms.length + (extraTiles ? extraTiles.length : 0);
if (totalTiles === 0 && !ALWAYS_VISIBLE_TAGS.includes(orderedTagId)) {
continue; // skip tag - not needed
@ -472,7 +544,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
isMinimized={this.props.isMinimized}
onResize={this.props.onResize}
showSkeleton={showSkeleton}
extraBadTilesThatShouldntExist={extraTiles}
extraTiles={extraTiles}
/>);
}