Merge pull request #6057 from matrix-org/t3chguy/fix/17350

Support filtering by alias in add existing to space dialog
pull/21833/head
Michael Telatynski 2021-05-19 12:29:00 +01:00 committed by GitHub
commit f985918859
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 24 deletions

View File

@ -21,7 +21,7 @@ import {removeHiddenChars} from "matrix-js-sdk/src/utils";
interface IOptions<T extends {}> { interface IOptions<T extends {}> {
keys: Array<string | keyof T>; keys: Array<string | keyof T>;
funcs?: Array<(T) => string>; funcs?: Array<(T) => string | string[]>;
shouldMatchWordsOnly?: boolean; shouldMatchWordsOnly?: boolean;
// whether to apply unhomoglyph and strip diacritics to fuzz up the search. Defaults to true // whether to apply unhomoglyph and strip diacritics to fuzz up the search. Defaults to true
fuzzy?: boolean; fuzzy?: boolean;
@ -69,7 +69,12 @@ export default class QueryMatcher<T extends Object> {
if (this._options.funcs) { if (this._options.funcs) {
for (const f of this._options.funcs) { for (const f of this._options.funcs) {
keyValues.push(f(object)); const v = f(object);
if (Array.isArray(v)) {
keyValues.push(...v);
} else {
keyValues.push(v);
}
} }
} }

View File

@ -38,6 +38,7 @@ import {sortRooms} from "../../../stores/room-list/algorithms/tag-sorting/Recent
import ProgressBar from "../elements/ProgressBar"; import ProgressBar from "../elements/ProgressBar";
import {SpaceFeedbackPrompt} from "../../structures/SpaceRoomView"; import {SpaceFeedbackPrompt} from "../../structures/SpaceRoomView";
import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar"; import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar";
import QueryMatcher from "../../../autocomplete/QueryMatcher";
interface IProps extends IDialogProps { interface IProps extends IDialogProps {
matrixClient: MatrixClient; matrixClient: MatrixClient;
@ -74,37 +75,47 @@ export const AddExistingToSpace: React.FC<IAddExistingToSpaceProps> = ({
onFinished, onFinished,
}) => { }) => {
const cli = useContext(MatrixClientContext); const cli = useContext(MatrixClientContext);
const visibleRooms = useMemo(() => sortRooms(cli.getVisibleRooms()), [cli]); const visibleRooms = useMemo(() => cli.getVisibleRooms().filter(r => r.getMyMembership() === "join"), [cli]);
const [selectedToAdd, setSelectedToAdd] = useState(new Set<Room>()); const [selectedToAdd, setSelectedToAdd] = useState(new Set<Room>());
const [progress, setProgress] = useState<number>(null); const [progress, setProgress] = useState<number>(null);
const [error, setError] = useState<Error>(null); const [error, setError] = useState<Error>(null);
const [query, setQuery] = useState(""); const [query, setQuery] = useState("");
const lcQuery = query.toLowerCase(); const lcQuery = query.toLowerCase().trim();
const existingSubspaces = SpaceStore.instance.getChildSpaces(space.roomId); const existingSubspacesSet = useMemo(() => new Set(SpaceStore.instance.getChildSpaces(space.roomId)), [space]);
const existingSubspacesSet = new Set(existingSubspaces); const existingRoomsSet = useMemo(() => new Set(SpaceStore.instance.getChildRooms(space.roomId)), [space]);
const existingRoomsSet = new Set(SpaceStore.instance.getChildRooms(space.roomId));
const joinRule = space.getJoinRule(); const [spaces, rooms, dms] = useMemo(() => {
const [spaces, rooms, dms] = visibleRooms.reduce((arr, room) => { let rooms = visibleRooms;
if (room.getMyMembership() !== "join") return arr;
if (!room.name.toLowerCase().includes(lcQuery)) return arr;
if (room.isSpaceRoom()) { if (lcQuery) {
if (room !== space && !existingSubspacesSet.has(room)) { const matcher = new QueryMatcher<Room>(visibleRooms, {
arr[0].push(room); keys: ["name"],
} funcs: [r => [r.getCanonicalAlias(), ...r.getAltAliases()].filter(Boolean)],
} else if (!existingRoomsSet.has(room)) { shouldMatchWordsOnly: false,
if (!DMRoomMap.shared().getUserIdForRoomId(room.roomId)) { });
arr[1].push(room);
} else if (joinRule !== "public") { rooms = matcher.match(lcQuery);
// Only show DMs for non-public spaces as they make very little sense in spaces other than "Just Me" ones.
arr[2].push(room);
}
} }
return arr;
}, [[], [], []]); const joinRule = space.getJoinRule();
return sortRooms(rooms).reduce((arr, room) => {
if (room.isSpaceRoom()) {
if (room !== space && !existingSubspacesSet.has(room)) {
arr[0].push(room);
}
} else if (!existingRoomsSet.has(room)) {
if (!DMRoomMap.shared().getUserIdForRoomId(room.roomId)) {
arr[1].push(room);
} else if (joinRule !== "public") {
// Only show DMs for non-public spaces as they make very little sense in spaces other than "Just Me" ones.
arr[2].push(room);
}
}
return arr;
}, [[], [], []]);
}, [visibleRooms, space, lcQuery, existingRoomsSet, existingSubspacesSet]);
const addRooms = async () => { const addRooms = async () => {
setError(null); setError(null);