import React, { FormEventHandler, KeyboardEventHandler, useCallback, useEffect, useRef, useState, } from 'react'; import { MatrixError } from 'matrix-js-sdk'; import { Box, color, Icon, Icons, Input, Spinner, Text, toRem } from 'folds'; import { isKeyHotkey } from 'is-hotkey'; import { getMxIdServer } from '../../utils/matrix'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { replaceSpaceWithDash } from '../../utils/common'; import { AsyncState, AsyncStatus, useAsync } from '../../hooks/useAsyncCallback'; import { useDebounce } from '../../hooks/useDebounce'; export function CreateRoomAliasInput({ disabled }: { disabled?: boolean }) { const mx = useMatrixClient(); const aliasInputRef = useRef(null); const [aliasAvail, setAliasAvail] = useState>({ status: AsyncStatus.Idle, }); useEffect(() => { if (aliasAvail.status === AsyncStatus.Success && aliasInputRef.current?.value === '') { setAliasAvail({ status: AsyncStatus.Idle }); } }, [aliasAvail]); const checkAliasAvail = useAsync( useCallback( async (aliasLocalPart: string) => { const roomAlias = `#${aliasLocalPart}:${getMxIdServer(mx.getSafeUserId())}`; try { const result = await mx.getRoomIdForAlias(roomAlias); return typeof result.room_id !== 'string'; } catch (e) { if (e instanceof MatrixError && e.httpStatus === 404) { return true; } throw e; } }, [mx] ), setAliasAvail ); const aliasAvailable: boolean | undefined = aliasAvail.status === AsyncStatus.Success ? aliasAvail.data : undefined; const debounceCheckAliasAvail = useDebounce(checkAliasAvail, { wait: 500 }); const handleAliasChange: FormEventHandler = (evt) => { const aliasInput = evt.currentTarget; const aliasLocalPart = replaceSpaceWithDash(aliasInput.value); if (aliasLocalPart) { aliasInput.value = aliasLocalPart; debounceCheckAliasAvail(aliasLocalPart); } else { setAliasAvail({ status: AsyncStatus.Idle }); } }; const handleAliasKeyDown: KeyboardEventHandler = (evt) => { if (isKeyHotkey('enter', evt)) { evt.preventDefault(); const aliasInput = evt.currentTarget; const aliasLocalPart = replaceSpaceWithDash(aliasInput.value); if (aliasLocalPart) { checkAliasAvail(aliasLocalPart); } else { setAliasAvail({ status: AsyncStatus.Idle }); } } }; return ( Address (Optional) Pick an unique address to make it discoverable. ) : ( ) } after={ :{getMxIdServer(mx.getSafeUserId())} } onKeyDown={handleAliasKeyDown} name="aliasInput" size="500" variant={aliasAvailable === true ? 'Success' : 'SurfaceVariant'} radii="400" autoComplete="off" disabled={disabled} /> {aliasAvailable === false && ( This address is already taken. Please select a different one. )} ); }