import { Box, Button, color, config, Icon, Icons, Input, Spinner, Switch, Text } from 'folds'; import React, { FormEventHandler, useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { ICreateRoomStateEvent, MatrixError, Preset, Visibility } from 'matrix-js-sdk'; import { useNavigate } from 'react-router-dom'; import { SettingTile } from '../../components/setting-tile'; import { SequenceCard } from '../../components/sequence-card'; import { addRoomIdToMDirect, isUserId } from '../../utils/matrix'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; import { ErrorCode } from '../../cs-errorcode'; import { millisecondsToMinutes } from '../../utils/common'; import { createRoomEncryptionState } from '../../components/create-room'; import { useAlive } from '../../hooks/useAlive'; import { getDirectRoomPath } from '../../pages/pathUtils'; type CreateChatProps = { defaultUserId?: string; }; export function CreateChat({ defaultUserId }: CreateChatProps) { const { t } = useTranslation(); const mx = useMatrixClient(); const alive = useAlive(); const navigate = useNavigate(); const [encryption, setEncryption] = useState(false); const [invalidUserId, setInvalidUserId] = useState(false); const [createState, create] = useAsyncCallback( useCallback( async (userId, encrypted) => { const initialState: ICreateRoomStateEvent[] = []; if (encrypted) initialState.push(createRoomEncryptionState()); const result = await mx.createRoom({ is_direct: true, invite: [userId], visibility: Visibility.Private, preset: Preset.TrustedPrivateChat, initial_state: initialState, }); addRoomIdToMDirect(mx, result.room_id, userId); return result.room_id; }, [mx] ) ); const loading = createState.status === AsyncStatus.Loading; const error = createState.status === AsyncStatus.Error ? createState.error : undefined; const disabled = createState.status === AsyncStatus.Loading; const handleSubmit: FormEventHandler = (evt) => { evt.preventDefault(); setInvalidUserId(false); const target = evt.target as HTMLFormElement | undefined; const userIdInput = target?.userIdInput as HTMLInputElement | undefined; const userId = userIdInput?.value.trim(); if (!userIdInput || !userId) return; if (!isUserId(userId)) { setInvalidUserId(true); return; } create(userId, encryption).then((roomId) => { if (alive()) { userIdInput.value = ''; navigate(getDirectRoomPath(roomId)); } }); }; return ( {t('Direct.user_id')} {invalidUserId && ( {t('Direct.invalid_user_id')} )} {t('Direct.options')} } /> {error && ( {error instanceof MatrixError && error.name === ErrorCode.M_LIMIT_EXCEEDED ? t('Direct.rate_limited', { minutes: millisecondsToMinutes( (error.data.retry_after_ms as number | undefined) ?? 0 ), }) : error.message} )} ); }