/* * Copyright 2025 New Vector Ltd. * * 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, { type ComponentProps, forwardRef, type JSX, useState } from "react"; import { IconButton, Menu, MenuItem, Separator, ToggleMenuItem, Tooltip } from "@vector-im/compound-web"; import MarkAsReadIcon from "@vector-im/compound-design-tokens/assets/web/icons/mark-as-read"; import MarkAsUnreadIcon from "@vector-im/compound-design-tokens/assets/web/icons/mark-as-unread"; import FavouriteIcon from "@vector-im/compound-design-tokens/assets/web/icons/favourite"; import ArrowDownIcon from "@vector-im/compound-design-tokens/assets/web/icons/arrow-down"; import UserAddIcon from "@vector-im/compound-design-tokens/assets/web/icons/user-add"; import LinkIcon from "@vector-im/compound-design-tokens/assets/web/icons/link"; import LeaveIcon from "@vector-im/compound-design-tokens/assets/web/icons/leave"; import OverflowIcon from "@vector-im/compound-design-tokens/assets/web/icons/overflow-horizontal"; import NotificationIcon from "@vector-im/compound-design-tokens/assets/web/icons/notifications-solid"; import NotificationOffIcon from "@vector-im/compound-design-tokens/assets/web/icons/notifications-off-solid"; import CheckIcon from "@vector-im/compound-design-tokens/assets/web/icons/check"; import { type Room } from "matrix-js-sdk/src/matrix"; import { _t } from "../../../../languageHandler"; import { Flex } from "../../../utils/Flex"; import { type RoomListItemMenuViewState, useRoomListItemMenuViewModel, } from "../../../viewmodels/roomlist/RoomListItemMenuViewModel"; import { RoomNotifState } from "../../../../RoomNotifs"; interface RoomListItemMenuViewProps { /** * The room to display the menu for. */ room: Room; /** * Set the menu open state. * @param isOpen */ setMenuOpen: (isOpen: boolean) => void; } /** * A view for the room list item menu. */ export function RoomListItemMenuView({ room, setMenuOpen }: RoomListItemMenuViewProps): JSX.Element { const vm = useRoomListItemMenuViewModel(room); return ( {vm.showMoreOptionsMenu && } {vm.showNotificationMenu && } ); } interface MoreOptionsMenuProps { /** * The view model state for the menu. */ vm: RoomListItemMenuViewState; /** * Set the menu open state. * @param isOpen */ setMenuOpen: (isOpen: boolean) => void; } /** * The more options menu for the room list item. */ function MoreOptionsMenu({ vm, setMenuOpen }: MoreOptionsMenuProps): JSX.Element { const [open, setOpen] = useState(false); return ( { setOpen(isOpen); setMenuOpen(isOpen); }} title={_t("room_list|room|more_options")} showTitle={false} align="start" trigger={} > {vm.canMarkAsRead && ( evt.stopPropagation()} /> )} {vm.canMarkAsUnread && ( evt.stopPropagation()} /> )} evt.stopPropagation()} /> evt.stopPropagation()} /> {vm.canInvite && ( evt.stopPropagation()} /> )} {vm.canCopyRoomLink && ( evt.stopPropagation()} /> )} evt.stopPropagation()} /> ); } interface MoreOptionsButtonProps extends ComponentProps {} /** * A button to trigger the more options menu. */ export const MoreOptionsButton = forwardRef( function MoreOptionsButton(props, ref) { return ( ); }, ); interface NotificationMenuProps { /** * The view model state for the menu. */ vm: RoomListItemMenuViewState; /** * Set the menu open state. * @param isOpen */ setMenuOpen: (isOpen: boolean) => void; } function NotificationMenu({ vm, setMenuOpen }: NotificationMenuProps): JSX.Element { const [open, setOpen] = useState(false); return ( { setOpen(isOpen); setMenuOpen(isOpen); }} title={_t("room_list|notification_options")} showTitle={false} align="start" trigger={} > vm.setRoomNotifState(RoomNotifState.AllMessages)} onClick={(evt) => evt.stopPropagation()} > {vm.isNotificationAllMessage && } vm.setRoomNotifState(RoomNotifState.AllMessagesLoud)} onClick={(evt) => evt.stopPropagation()} > {vm.isNotificationAllMessageLoud && } vm.setRoomNotifState(RoomNotifState.MentionsOnly)} onClick={(evt) => evt.stopPropagation()} > {vm.isNotificationMentionOnly && } vm.setRoomNotifState(RoomNotifState.Mute)} onClick={(evt) => evt.stopPropagation()} > {vm.isNotificationMute && } ); } interface NotificationButtonProps extends ComponentProps { /** * Whether the room is muted. */ isRoomMuted: boolean; } /** * A button to trigger the notification menu. */ export const NotificationButton = forwardRef(function MoreOptionsButton( { isRoomMuted, ...props }, ref, ) { return ( {isRoomMuted ? : } ); });