import React, { MouseEventHandler, useCallback, useMemo, useState } from 'react'; import { config, Box, MenuItem, Text, Icon, Icons, IconSrc, RectCords, PopOut, Menu, Button, Spinner, } from 'folds'; import { JoinRule } from 'matrix-js-sdk'; import FocusTrap from 'focus-trap-react'; import { stopPropagation } from '../utils/keyboard'; import { getRoomIconSrc } from '../utils/room'; export type ExtraJoinRules = 'knock_restricted'; export type ExtendedJoinRules = JoinRule | ExtraJoinRules; type JoinRuleIcons = Record; export const useJoinRuleIcons = (roomType?: string): JoinRuleIcons => useMemo( () => ({ [JoinRule.Invite]: getRoomIconSrc(Icons, roomType, JoinRule.Invite), [JoinRule.Knock]: getRoomIconSrc(Icons, roomType, JoinRule.Knock), knock_restricted: getRoomIconSrc(Icons, roomType, JoinRule.Restricted), [JoinRule.Restricted]: getRoomIconSrc(Icons, roomType, JoinRule.Restricted), [JoinRule.Public]: getRoomIconSrc(Icons, roomType, JoinRule.Public), [JoinRule.Private]: getRoomIconSrc(Icons, roomType, JoinRule.Private), }), [roomType], ); type JoinRuleLabels = Record; export const useRoomJoinRuleLabel = (): JoinRuleLabels => useMemo( () => ({ [JoinRule.Invite]: 'Invite Only', [JoinRule.Knock]: 'Knock & Invite', knock_restricted: 'Space Members or Knock', [JoinRule.Restricted]: 'Space Members', [JoinRule.Public]: 'Public', [JoinRule.Private]: 'Invite Only', }), [], ); type JoinRulesSwitcherProps = { icons: JoinRuleIcons; labels: JoinRuleLabels; rules: T; value: T[number]; onChange: (value: T[number]) => void; disabled?: boolean; changing?: boolean; }; export function JoinRulesSwitcher({ icons, labels, rules, value, onChange, disabled, changing, }: JoinRulesSwitcherProps) { const [cords, setCords] = useState(); const handleOpenMenu: MouseEventHandler = (evt) => { setCords(evt.currentTarget.getBoundingClientRect()); }; const handleChange = useCallback( (selectedRule: ExtendedJoinRules) => { setCords(undefined); onChange(selectedRule); }, [onChange], ); return ( setCords(undefined), clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', escapeDeactivates: stopPropagation, }} > {rules.map((rule) => ( handleChange(rule)} before={} disabled={disabled} > {labels[rule]} ))} } > ); }