/*
Copyright 2024,2025 New Vector Ltd.
Copyright 2021 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import React, { useMemo, useState } from "react";
import { Room } from "matrix-js-sdk/src/matrix";
import { KnownMembership } from "matrix-js-sdk/src/types";
import { _t } from "../../../languageHandler";
import BaseDialog from "./BaseDialog";
import SearchBox from "../../structures/SearchBox";
import SpaceStore from "../../../stores/spaces/SpaceStore";
import RoomAvatar from "../avatars/RoomAvatar";
import AccessibleButton from "../elements/AccessibleButton";
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
import StyledCheckbox from "../elements/StyledCheckbox";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { filterBoolean } from "../../../utils/arrays";
interface IProps {
room: Room;
selected?: string[];
onFinished(rooms?: string[]): void;
}
const Entry: React.FC<{
room: Room;
checked: boolean;
onChange(value: boolean): void;
}> = ({ room, checked, onChange }) => {
const localRoom = room instanceof Room;
let description;
if (localRoom) {
description = _t("common|n_members", { count: room.getJoinedMemberCount() });
const numChildRooms = SpaceStore.instance.getChildRooms(room.roomId).length;
if (numChildRooms > 0) {
description += " ยท " + _t("common|n_rooms", { count: numChildRooms });
}
}
return (
onChange(e.target.checked) : undefined}
checked={checked}
disabled={!onChange}
description={description}
>
{localRoom ? (
) : (
)}
{room.name}
);
};
const addAllParents = (set: Set, room: Room): void => {
const cli = room.client;
const parents = Array.from(SpaceStore.instance.getKnownParents(room.roomId)).map((parentId) =>
cli.getRoom(parentId),
);
parents.forEach((parent) => {
if (!parent || set.has(parent)) return;
set.add(parent);
addAllParents(set, parent);
});
};
const ManageRestrictedJoinRuleDialog: React.FC = ({ room, selected = [], onFinished }) => {
const cli = room.client;
const [newSelected, setNewSelected] = useState(new Set(selected));
const [query, setQuery] = useState("");
const lcQuery = query.toLowerCase().trim();
const [spacesContainingRoom, otherJoinedSpaces, otherEntries] = useMemo(() => {
const parents = new Set();
addAllParents(parents, room);
return [
Array.from(parents),
SpaceStore.instance.spacePanelSpaces.filter((s) => !parents.has(s)),
filterBoolean(
selected.map((roomId) => {
const room = cli.getRoom(roomId);
if (!room) {
return { roomId, name: roomId } as Room;
}
if (room.getMyMembership() !== KnownMembership.Join || !room.isSpaceRoom()) {
return room;
}
}),
),
];
}, [cli, selected, room]);
const [filteredSpacesContainingRoom, filteredOtherJoinedSpaces, filteredOtherEntries] = useMemo(
() => [
spacesContainingRoom.filter((r) => r.name.toLowerCase().includes(lcQuery)),
otherJoinedSpaces.filter((r) => r.name.toLowerCase().includes(lcQuery)),
otherEntries.filter((r) => r.name.toLowerCase().includes(lcQuery)),
],
[spacesContainingRoom, otherJoinedSpaces, otherEntries, lcQuery],
);
const onChange = (checked: boolean, room: Room): void => {
if (checked) {
newSelected.add(room.roomId);
} else {
newSelected.delete(room.roomId);
}
setNewSelected(new Set(newSelected));
};
let inviteOnlyWarning;
if (newSelected.size < 1) {
inviteOnlyWarning = (
{_t("room_settings|security|join_rule_restricted_dialog_empty_warning")}
);
}
const totalResults =
filteredSpacesContainingRoom.length + filteredOtherJoinedSpaces.length + filteredOtherEntries.length;
return (
{_t(
"room_settings|security|join_rule_restricted_dialog_description",
{},
{
RoomName: () => {room.name},
},
)}
{filteredSpacesContainingRoom.length > 0 ? (
{room.isSpaceRoom()
? _t("room_settings|security|join_rule_restricted_dialog_heading_space")
: _t("room_settings|security|join_rule_restricted_dialog_heading_room")}
{filteredSpacesContainingRoom.map((space) => {
return (
{
onChange(checked, space);
}}
/>
);
})}
) : undefined}
{filteredOtherEntries.length > 0 ? (
{_t("room_settings|security|join_rule_restricted_dialog_heading_other")}
{_t("room_settings|security|join_rule_restricted_dialog_heading_unknown")}
{filteredOtherEntries.map((space) => {
return (
{
onChange(checked, space);
}}
/>
);
})}
) : null}
{filteredOtherJoinedSpaces.length > 0 ? (
{_t("room_settings|security|join_rule_restricted_dialog_heading_known")}
{filteredOtherJoinedSpaces.map((space) => {
return (
{
onChange(checked, space);
}}
/>
);
})}
) : null}
{totalResults < 1 ? (
{_t("common|no_results")}
) : undefined}
{inviteOnlyWarning}
onFinished()}>
{_t("action|cancel")}
onFinished(Array.from(newSelected))}>
{_t("action|confirm")}
);
};
export default ManageRestrictedJoinRuleDialog;