import React, { useCallback, useContext, useEffect, useState } from 'react'; import { Avatar, Box, Button, ButtonBase, Collapse, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Input, ListItem, ListItemAvatar, ListItemButton, ListItemIcon, ListItemText, List, MenuItem, Popover, Select, TextField, Typography, useTheme, } from '@mui/material'; import { Label } from './Group/AddGroup'; import { Spacer } from '../common/Spacer'; import { LoadingButton } from '@mui/lab'; import { getBaseApiReact, MyContext } from '../App'; import { getFee } from '../background'; import RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked'; import { subscribeToEvent, unsubscribeFromEvent } from '../utils/events'; import { BarSpinner } from '../common/Spinners/BarSpinner/BarSpinner'; import CheckIcon from '@mui/icons-material/Check'; import ErrorIcon from '@mui/icons-material/Error'; enum Availability { NULL = 'null', LOADING = 'loading', AVAILABLE = 'available', NOT_AVAILABLE = 'not-available', } export const RegisterName = ({ setOpenSnack, setInfoSnack, userInfo, show, setTxList, balance, }) => { const [isOpen, setIsOpen] = useState(false); const [registerNameValue, setRegisterNameValue] = useState(''); const [isLoadingRegisterName, setIsLoadingRegisterName] = useState(false); const [isNameAvailable, setIsNameAvailable] = useState( Availability.NULL ); const [nameFee, setNameFee] = useState(null); const theme = useTheme(); const checkIfNameExisits = async (name) => { if (!name?.trim()) { setIsNameAvailable(Availability.NULL); return; } setIsNameAvailable(Availability.LOADING); try { const res = await fetch(`${getBaseApiReact()}/names/` + name); const data = await res.json(); if (data?.message === 'name unknown') { setIsNameAvailable(Availability.AVAILABLE); } else { setIsNameAvailable(Availability.NOT_AVAILABLE); } } catch (error) { console.error(error); } finally { } }; // Debounce logic useEffect(() => { const handler = setTimeout(() => { checkIfNameExisits(registerNameValue); }, 500); // Cleanup timeout if searchValue changes before the timeout completes return () => { clearTimeout(handler); }; }, [registerNameValue]); const openRegisterNameFunc = useCallback( (e) => { setIsOpen(true); }, [setIsOpen] ); useEffect(() => { subscribeToEvent('openRegisterName', openRegisterNameFunc); return () => { unsubscribeFromEvent('openRegisterName', openRegisterNameFunc); }; }, [openRegisterNameFunc]); useEffect(() => { const nameRegistrationFee = async () => { try { const fee = await getFee('REGISTER_NAME'); setNameFee(fee?.fee); } catch (error) { console.error(error); } }; nameRegistrationFee(); }, []); const registerName = async () => { try { if (!userInfo?.address) throw new Error('Your address was not found'); if (!registerNameValue) throw new Error('Enter a name'); const fee = await getFee('REGISTER_NAME'); await show({ message: 'Would you like to register this name?', publishFee: fee.fee + ' QORT', }); setIsLoadingRegisterName(true); new Promise((res, rej) => { window .sendMessage('registerName', { name: registerNameValue, }) .then((response) => { if (!response?.error) { res(response); setIsLoadingRegisterName(false); setInfoSnack({ type: 'success', message: 'Successfully registered. It may take a couple of minutes for the changes to propagate', }); setIsOpen(false); setRegisterNameValue(''); setOpenSnack(true); setTxList((prev) => [ { ...response, type: 'register-name', label: `Registered name: awaiting confirmation. This may take a couple minutes.`, labelDone: `Registered name: success!`, done: false, }, ...prev.filter((item) => !item.done), ]); return; } setInfoSnack({ type: 'error', message: response?.error, }); setOpenSnack(true); rej(response.error); }) .catch((error) => { setInfoSnack({ type: 'error', message: error.message || 'An error occurred', }); setOpenSnack(true); rej(error); }); }); } catch (error) { if (error?.message) { setOpenSnack(true); setInfoSnack({ type: 'error', message: error?.message, }); } } finally { setIsLoadingRegisterName(false); } }; return ( {'Register name'} setRegisterNameValue(e.target.value)} value={registerNameValue} placeholder="Choose a name" /> {(!balance || (nameFee && balance && balance < nameFee)) && ( <> Your balance is {balance ?? 0} QORT. A name registration requires a {nameFee} QORT fee )} {isNameAvailable === Availability.AVAILABLE && ( {registerNameValue} is available )} {isNameAvailable === Availability.NOT_AVAILABLE && ( {registerNameValue} is unavailable )} {isNameAvailable === Availability.LOADING && ( Checking if name already existis )} Benefits of a name ); };