import React, { forwardRef } from 'react'; import { Box, Icon, Icons, Line, Menu, MenuItem, Spinner, Text, config, toRem } from 'folds'; import type { Room } from 'matrix-js-sdk'; import { useTranslation } from 'react-i18next'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; import { useRoomUnread } from '../../state/hooks/unread'; import { roomToUnreadAtom } from '../../state/room/roomToUnread'; import { getRoomNotificationMode, getRoomNotificationModeIcon, useRoomsNotificationPreferencesContext, } from '../../hooks/useRoomsNotificationPreferences'; import { RoomNotificationModeSwitcher } from '../../components/RoomNotificationSwitcher'; import { LeaveRoomPrompt } from '../../components/leave-room-prompt'; import { UseStateProvider } from '../../components/UseStateProvider'; import { markAsRead } from '../../utils/notifications'; type AiChatMenuProps = { room: Room; requestClose: () => void; onNewChat: () => void; onOpenHistory: () => void; onOpenPrivacy: () => void; }; // The native AI conversation surface's ⋮ menu. Deliberately NOT BotShellMenu: there is no widget // here, so there is no "Show chat" toggle (it would be meaningless). It carries the conversation // actions (New chat / History / Privacy & data) plus the generic room actions (mark read / // notifications / leave) // that apply to any DM — reusing the same shared switcher / leave-prompt primitives so behaviour // can't drift from the rest of the app. export const AiChatMenu = forwardRef( ({ room, requestClose, onNewChat, onOpenHistory, onOpenPrivacy }, ref) => { const { t } = useTranslation(); const mx = useMatrixClient(); const [hideActivity] = useSetting(settingsAtom, 'hideActivity'); const unread = useRoomUnread(room.roomId, roomToUnreadAtom); const notificationPreferences = useRoomsNotificationPreferencesContext(); const notificationMode = getRoomNotificationMode(notificationPreferences, room.roomId); const handleMarkAsRead = () => { markAsRead(mx, room.roomId, hideActivity); requestClose(); }; return ( { onNewChat(); requestClose(); }} size="300" after={} radii="300" > {t('Bots.conversations.new_chat')} { onOpenHistory(); requestClose(); }} size="300" after={} radii="300" > {t('Bots.conversations.title')} } radii="300" disabled={!unread} > {t('Room.mark_as_read')} {(handleOpen, opened, changing) => ( ) : ( ) } radii="300" aria-pressed={opened} onClick={handleOpen} > {t('Room.notifications')} )} { onOpenPrivacy(); requestClose(); }} size="300" after={} radii="300" > {t('Bots.privacy.menu')} {(promptLeave, setPromptLeave) => ( <> setPromptLeave(true)} variant="Critical" fill="None" size="300" after={} radii="300" aria-pressed={promptLeave} > {t('Room.leave_room')} {promptLeave && ( setPromptLeave(false)} /> )} )} ); } );