Merge pull request #5963 from matrix-org/t3chguy/fix/17119

Update space ordering behaviour to match updates in MSC
pull/21833/head
Michael Telatynski 2021-05-05 22:26:45 +01:00 committed by GitHub
commit 68210b1415
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 10 deletions

View File

@ -39,6 +39,7 @@ import {mediaFromMxc} from "../../customisations/Media";
import InfoTooltip from "../views/elements/InfoTooltip"; import InfoTooltip from "../views/elements/InfoTooltip";
import TextWithTooltip from "../views/elements/TextWithTooltip"; import TextWithTooltip from "../views/elements/TextWithTooltip";
import {useStateToggle} from "../../hooks/useStateToggle"; import {useStateToggle} from "../../hooks/useStateToggle";
import {getOrder} from "../../stores/SpaceStore";
interface IHierarchyProps { interface IHierarchyProps {
space: Room; space: Room;
@ -254,7 +255,11 @@ export const HierarchyLevel = ({
const space = cli.getRoom(spaceId); const space = cli.getRoom(spaceId);
const hasPermissions = space?.currentState.maySendStateEvent(EventType.SpaceChild, cli.getUserId()); const hasPermissions = space?.currentState.maySendStateEvent(EventType.SpaceChild, cli.getUserId());
const sortedChildren = sortBy([...(relations.get(spaceId)?.values() || [])], ev => ev.content.order || null); const children = Array.from(relations.get(spaceId)?.values() || []);
const sortedChildren = sortBy(children, ev => {
// XXX: Space Summary API doesn't give the child origin_server_ts but once it does we should use it for sorting
return getOrder(ev.content.order, null, ev.state_key);
});
const [subspaces, childRooms] = sortedChildren.reduce((result, ev: ISpaceSummaryEvent) => { const [subspaces, childRooms] = sortedChildren.reduce((result, ev: ISpaceSummaryEvent) => {
const roomId = ev.state_key; const roomId = ev.state_key;
if (!rooms.has(roomId)) return result; if (!rooms.has(roomId)) return result;

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import {sortBy, throttle} from "lodash"; import {ListIteratee, Many, sortBy, throttle} from "lodash";
import {EventType, RoomType} from "matrix-js-sdk/src/@types/event"; import {EventType, RoomType} from "matrix-js-sdk/src/@types/event";
import {Room} from "matrix-js-sdk/src/models/room"; import {Room} from "matrix-js-sdk/src/models/room";
import {MatrixEvent} from "matrix-js-sdk/src/models/event"; import {MatrixEvent} from "matrix-js-sdk/src/models/event";
@ -61,15 +61,18 @@ const partitionSpacesAndRooms = (arr: Room[]): [Room[], Room[]] => { // [spaces,
}, [[], []]); }, [[], []]);
}; };
const getOrder = (ev: MatrixEvent): string | null => { // For sorting space children using a validated `order`, `m.room.create`'s `origin_server_ts`, `room_id`
const content = ev.getContent(); export const getOrder = (order: string, creationTs: number, roomId: string): Array<Many<ListIteratee<any>>> => {
if (typeof content.order === "string" && Array.from(content.order).every((c: string) => { let validatedOrder: string = null;
if (typeof order === "string" && Array.from(order).every((c: string) => {
const charCode = c.charCodeAt(0); const charCode = c.charCodeAt(0);
return charCode >= 0x20 && charCode <= 0x7F; return charCode >= 0x20 && charCode <= 0x7F;
})) { })) {
return content.order; validatedOrder = order;
} }
return null;
return [validatedOrder, creationTs, roomId];
} }
const getRoomFn: FetchRoomFn = (room: Room) => { const getRoomFn: FetchRoomFn = (room: Room) => {
@ -200,9 +203,16 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
private getChildren(spaceId: string): Room[] { private getChildren(spaceId: string): Room[] {
const room = this.matrixClient?.getRoom(spaceId); const room = this.matrixClient?.getRoom(spaceId);
const childEvents = room?.currentState.getStateEvents(EventType.SpaceChild).filter(ev => ev.getContent()?.via); const childEvents = room?.currentState.getStateEvents(EventType.SpaceChild).filter(ev => ev.getContent()?.via);
return sortBy(childEvents, getOrder) return sortBy(childEvents, ev => {
.map(ev => this.matrixClient.getRoom(ev.getStateKey())) const roomId = ev.getStateKey();
.filter(room => room?.getMyMembership() === "join" || room?.getMyMembership() === "invite") || []; const childRoom = this.matrixClient?.getRoom(roomId);
const createTs = childRoom?.currentState.getStateEvents(EventType.RoomCreate, "")?.getTs();
return getOrder(ev.getContent().order, createTs, roomId);
}).map(ev => {
return this.matrixClient.getRoom(ev.getStateKey());
}).filter(room => {
return room?.getMyMembership() === "join" || room?.getMyMembership() === "invite";
}) || [];
} }
public getChildRooms(spaceId: string): Room[] { public getChildRooms(spaceId: string): Room[] {