import React, { MouseEventHandler, useCallback, useEffect, useState } from 'react';
import FocusTrap from 'focus-trap-react';
import {
Box,
IconButton,
Icon,
Icons,
PopOut,
Menu,
MenuItem,
Text,
RectCords,
config,
Line,
Spinner,
toRem,
} from 'folds';
import { HierarchyItem } from '../../hooks/useSpaceHierarchy';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { MSpaceChildContent, StateEvent } from '../../../types/matrix/room';
import { openInviteUser } from '../../../client/action/navigation';
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
import { UseStateProvider } from '../../components/UseStateProvider';
import { LeaveSpacePrompt } from '../../components/leave-space-prompt';
import { LeaveRoomPrompt } from '../../components/leave-room-prompt';
import { stopPropagation } from '../../utils/keyboard';
import { useOpenRoomSettings } from '../../state/hooks/roomSettings';
import { useSpaceOptionally } from '../../hooks/useSpace';
import { useOpenSpaceSettings } from '../../state/hooks/spaceSettings';
type HierarchyItemWithParent = HierarchyItem & {
parentId: string;
};
function SuggestMenuItem({
item,
requestClose,
}: {
item: HierarchyItemWithParent;
requestClose: () => void;
}) {
const mx = useMatrixClient();
const { roomId, parentId, content } = item;
const [toggleState, handleToggleSuggested] = useAsyncCallback(
useCallback(() => {
const newContent: MSpaceChildContent = { ...content, suggested: !content.suggested };
return mx.sendStateEvent(parentId, StateEvent.SpaceChild, newContent, roomId);
}, [mx, parentId, roomId, content])
);
useEffect(() => {
if (toggleState.status === AsyncStatus.Success) {
requestClose();
}
}, [requestClose, toggleState]);
return (
}
disabled={toggleState.status === AsyncStatus.Loading}
>
{content.suggested ? 'Unset Suggested' : 'Set Suggested'}
);
}
function RemoveMenuItem({
item,
requestClose,
}: {
item: HierarchyItemWithParent;
requestClose: () => void;
}) {
const mx = useMatrixClient();
const { roomId, parentId } = item;
const [removeState, handleRemove] = useAsyncCallback(
useCallback(
() => mx.sendStateEvent(parentId, StateEvent.SpaceChild, {}, roomId),
[mx, parentId, roomId]
)
);
useEffect(() => {
if (removeState.status === AsyncStatus.Success) {
requestClose();
}
}, [requestClose, removeState]);
return (
)
}
disabled={removeState.status === AsyncStatus.Loading}
>
Remove
);
}
function InviteMenuItem({
item,
requestClose,
disabled,
}: {
item: HierarchyItemWithParent;
requestClose: () => void;
disabled?: boolean;
}) {
const handleInvite = () => {
openInviteUser(item.roomId);
requestClose();
};
return (
);
}
function SettingsMenuItem({
item,
requestClose,
disabled,
}: {
item: HierarchyItemWithParent;
requestClose: () => void;
disabled?: boolean;
}) {
const openRoomSettings = useOpenRoomSettings();
const openSpaceSettings = useOpenSpaceSettings();
const space = useSpaceOptionally();
const handleSettings = () => {
if ('space' in item) {
openSpaceSettings(item.roomId, item.parentId);
} else {
openRoomSettings(item.roomId, space?.roomId);
}
requestClose();
};
return (
);
}
type HierarchyItemMenuProps = {
item: HierarchyItem & {
parentId: string;
};
joined: boolean;
canInvite: boolean;
canEditChild: boolean;
pinned?: boolean;
onTogglePin?: (roomId: string) => void;
};
export function HierarchyItemMenu({
item,
joined,
canInvite,
canEditChild,
pinned,
onTogglePin,
}: HierarchyItemMenuProps) {
const [menuAnchor, setMenuAnchor] = useState();
const handleOpenMenu: MouseEventHandler = (evt) => {
setMenuAnchor(evt.currentTarget.getBoundingClientRect());
};
const handleRequestClose = useCallback(() => setMenuAnchor(undefined), []);
if (!joined && !canEditChild) {
return null;
}
return (
{menuAnchor && (
setMenuAnchor(undefined),
clickOutsideDeactivates: true,
isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown',
isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp',
escapeDeactivates: stopPropagation,
}}
>
}
/>
)}
);
}