Merge pull request #6077 from matrix-org/t3chguy/fix/17414

Fix handling of via servers for suggested rooms
pull/21833/head
Michael Telatynski 2021-05-20 20:24:18 +01:00 committed by GitHub
commit aca29c5577
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 23 deletions

View File

@ -76,7 +76,7 @@ export interface ISpaceSummaryEvent {
order?: string; order?: string;
suggested?: boolean; suggested?: boolean;
auto_join?: boolean; auto_join?: boolean;
via?: string; via?: string[];
}; };
} }
/* eslint-enable camelcase */ /* eslint-enable camelcase */
@ -356,9 +356,9 @@ export const useSpaceSummary = (cli: MatrixClient, space: Room, refreshToken?: a
parentChildRelations.getOrCreate(ev.room_id, new Map()).set(ev.state_key, ev); parentChildRelations.getOrCreate(ev.room_id, new Map()).set(ev.state_key, ev);
childParentRelations.getOrCreate(ev.state_key, new Set()).add(ev.room_id); childParentRelations.getOrCreate(ev.state_key, new Set()).add(ev.room_id);
} }
if (Array.isArray(ev.content["via"])) { if (Array.isArray(ev.content.via)) {
const set = viaMap.getOrCreate(ev.state_key, new Set()); const set = viaMap.getOrCreate(ev.state_key, new Set());
ev.content["via"].forEach(via => set.add(via)); ev.content.via.forEach(via => set.add(via));
} }
}); });

View File

@ -806,7 +806,7 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
let suggestedRooms = SpaceStore.instance.suggestedRooms; let suggestedRooms = SpaceStore.instance.suggestedRooms;
if (SpaceStore.instance.activeSpace !== this.props.space) { if (SpaceStore.instance.activeSpace !== this.props.space) {
// the space store has the suggested rooms loaded for a different space, fetch the right ones // the space store has the suggested rooms loaded for a different space, fetch the right ones
suggestedRooms = (await SpaceStore.instance.fetchSuggestedRooms(this.props.space, 1)).rooms; suggestedRooms = (await SpaceStore.instance.fetchSuggestedRooms(this.props.space, 1));
} }
if (suggestedRooms.length) { if (suggestedRooms.length) {
@ -814,9 +814,11 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
defaultDispatcher.dispatch({ defaultDispatcher.dispatch({
action: "view_room", action: "view_room",
room_id: room.room_id, room_id: room.room_id,
room_alias: room.canonical_alias || room.aliases?.[0],
via_servers: room.viaServers,
oobData: { oobData: {
avatarUrl: room.avatar_url, avatarUrl: room.avatar_url,
name: room.name || room.canonical_alias || room.aliases.pop() || _t("Empty room"), name: room.name || room.canonical_alias || room.aliases?.[0] || _t("Empty room"),
}, },
}); });
return; return;

View File

@ -46,11 +46,10 @@ import { IconizedContextMenuOption, IconizedContextMenuOptionList } from "../con
import AccessibleButton from "../elements/AccessibleButton"; import AccessibleButton from "../elements/AccessibleButton";
import { CommunityPrototypeStore } from "../../../stores/CommunityPrototypeStore"; import { CommunityPrototypeStore } from "../../../stores/CommunityPrototypeStore";
import CallHandler from "../../../CallHandler"; import CallHandler from "../../../CallHandler";
import SpaceStore, {SUGGESTED_ROOMS} from "../../../stores/SpaceStore"; import SpaceStore, {ISuggestedRoom, SUGGESTED_ROOMS} from "../../../stores/SpaceStore";
import {showAddExistingRooms, showCreateNewRoom, showSpaceInvite} from "../../../utils/space"; import {showAddExistingRooms, showCreateNewRoom, showSpaceInvite} from "../../../utils/space";
import {replaceableComponent} from "../../../utils/replaceableComponent"; import {replaceableComponent} from "../../../utils/replaceableComponent";
import RoomAvatar from "../avatars/RoomAvatar"; import RoomAvatar from "../avatars/RoomAvatar";
import { ISpaceSummaryRoom } from "../../structures/SpaceRoomDirectory";
interface IProps { interface IProps {
onKeyDown: (ev: React.KeyboardEvent) => void; onKeyDown: (ev: React.KeyboardEvent) => void;
@ -66,7 +65,7 @@ interface IState {
sublists: ITagMap; sublists: ITagMap;
isNameFiltering: boolean; isNameFiltering: boolean;
currentRoomId?: string; currentRoomId?: string;
suggestedRooms: ISpaceSummaryRoom[]; suggestedRooms: ISuggestedRoom[];
} }
const TAG_ORDER: TagID[] = [ const TAG_ORDER: TagID[] = [
@ -363,7 +362,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
return room; return room;
}; };
private updateSuggestedRooms = (suggestedRooms: ISpaceSummaryRoom[]) => { private updateSuggestedRooms = (suggestedRooms: ISuggestedRoom[]) => {
this.setState({ suggestedRooms }); this.setState({ suggestedRooms });
}; };
@ -443,7 +442,9 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
const viewRoom = () => { const viewRoom = () => {
defaultDispatcher.dispatch({ defaultDispatcher.dispatch({
action: "view_room", action: "view_room",
room_alias: room.canonical_alias || room.aliases?.[0],
room_id: room.room_id, room_id: room.room_id,
via_servers: room.viaServers,
oobData: { oobData: {
avatarUrl: room.avatar_url, avatarUrl: room.avatar_url,
name, name,

View File

@ -45,6 +45,10 @@ export const UPDATE_INVITED_SPACES = Symbol("invited-spaces");
export const UPDATE_SELECTED_SPACE = Symbol("selected-space"); export const UPDATE_SELECTED_SPACE = Symbol("selected-space");
// Space Room ID will be emitted when a Space's children change // Space Room ID will be emitted when a Space's children change
export interface ISuggestedRoom extends ISpaceSummaryRoom {
viaServers: string[];
}
const MAX_SUGGESTED_ROOMS = 20; const MAX_SUGGESTED_ROOMS = 20;
const getSpaceContextKey = (space?: Room) => `mx_space_context_${space?.roomId || "ALL_ROOMS"}`; const getSpaceContextKey = (space?: Room) => `mx_space_context_${space?.roomId || "ALL_ROOMS"}`;
@ -89,7 +93,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
private spaceFilteredRooms = new Map<string, Set<string>>(); private spaceFilteredRooms = new Map<string, Set<string>>();
// The space currently selected in the Space Panel - if null then All Rooms is selected // The space currently selected in the Space Panel - if null then All Rooms is selected
private _activeSpace?: Room = null; private _activeSpace?: Room = null;
private _suggestedRooms: ISpaceSummaryRoom[] = []; private _suggestedRooms: ISuggestedRoom[] = [];
private _invitedSpaces = new Set<Room>(); private _invitedSpaces = new Set<Room>();
public get invitedSpaces(): Room[] { public get invitedSpaces(): Room[] {
@ -104,7 +108,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
return this._activeSpace || null; return this._activeSpace || null;
} }
public get suggestedRooms(): ISpaceSummaryRoom[] { public get suggestedRooms(): ISuggestedRoom[] {
return this._suggestedRooms; return this._suggestedRooms;
} }
@ -158,31 +162,41 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
} }
if (space) { if (space) {
const data = await this.fetchSuggestedRooms(space); const suggestedRooms = await this.fetchSuggestedRooms(space);
if (this._activeSpace === space) { if (this._activeSpace === space) {
this._suggestedRooms = data.rooms.filter(roomInfo => { this._suggestedRooms = suggestedRooms;
return roomInfo.room_type !== RoomType.Space
&& this.matrixClient.getRoom(roomInfo.room_id)?.getMyMembership() !== "join";
});
this.emit(SUGGESTED_ROOMS, this._suggestedRooms); this.emit(SUGGESTED_ROOMS, this._suggestedRooms);
} }
} }
} }
public fetchSuggestedRooms = async (space: Room, limit = MAX_SUGGESTED_ROOMS) => { public fetchSuggestedRooms = async (space: Room, limit = MAX_SUGGESTED_ROOMS): Promise<ISuggestedRoom[]> => {
try { try {
const data: { const data: {
rooms: ISpaceSummaryRoom[]; rooms: ISpaceSummaryRoom[];
events: ISpaceSummaryEvent[]; events: ISpaceSummaryEvent[];
} = await this.matrixClient.getSpaceSummary(space.roomId, 0, true, false, limit); } = await this.matrixClient.getSpaceSummary(space.roomId, 0, true, false, limit);
return data;
const viaMap = new EnhancedMap<string, Set<string>>();
data.events.forEach(ev => {
if (ev.type === EventType.SpaceChild && ev.content.via?.length) {
ev.content.via.forEach(via => {
viaMap.getOrCreate(ev.state_key, new Set()).add(via);
});
}
});
return data.rooms.filter(roomInfo => {
return roomInfo.room_type !== RoomType.Space
&& this.matrixClient.getRoom(roomInfo.room_id)?.getMyMembership() !== "join";
}).map(roomInfo => ({
...roomInfo,
viaServers: Array.from(viaMap.get(roomInfo.room_id) || []),
}));
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }
return { return [];
rooms: [],
events: [],
};
}; };
public addRoomToSpace(space: Room, roomId: string, via: string[], suggested = false, autoJoin = false) { public addRoomToSpace(space: Room, roomId: string, via: string[], suggested = false, autoJoin = false) {
@ -222,7 +236,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
return room?.currentState.getStateEvents(EventType.SpaceParent) return room?.currentState.getStateEvents(EventType.SpaceParent)
.filter(ev => { .filter(ev => {
const content = ev.getContent(); const content = ev.getContent();
if (!content?.via) return false; if (!content?.via?.length) return false;
// TODO apply permissions check to verify that the parent mapping is valid // TODO apply permissions check to verify that the parent mapping is valid
if (canonicalOnly && !content?.canonical) return false; if (canonicalOnly && !content?.canonical) return false;
return true; return true;