diff --git a/src/components/Modal/ModalEditName/ModalEditName.tsx b/src/components/Modal/ModalEditName/ModalEditName.tsx index 136fea9..6dbc0ae 100644 --- a/src/components/Modal/ModalEditName/ModalEditName.tsx +++ b/src/components/Modal/ModalEditName/ModalEditName.tsx @@ -20,7 +20,7 @@ export const ModalEditName = () => { const keys = useAppSelector(selectKeys) const notify = useEnqueueSnackbar() - const [searchParams] = useSearchParams() + const [searchParams, setSearchParams] = useSearchParams() const name = searchParams.get('name') || '' const npub = searchParams.get('npub') || '' @@ -28,16 +28,24 @@ export const ModalEditName = () => { const { getModalOpened, createHandleCloseReplace } = useModalSearchParams() const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.EDIT_NAME) - const handleCloseModal = createHandleCloseReplace(MODAL_PARAMS_KEYS.EDIT_NAME) + const handleCloseModal = createHandleCloseReplace(MODAL_PARAMS_KEYS.EDIT_NAME, { + onClose: (search) => { + search.delete('name') + search.delete('npub') + }, + }) const [enteredName, setEnteredName] = useState('') const [debouncedName] = useDebounce(enteredName, 300) const isNameEqual = debouncedName === name + const [receiverNpub, setReceiverNpub] = useState('') + const [isAvailable, setIsAvailable] = useState(true) const [isChecking, setIsChecking] = useState(false) const [isLoading, setIsLoading] = useState(false) + const [isTransferLoading, setIsTransferLoading] = useState(false) const checkIsUsernameAvailable = useCallback(async () => { if (!debouncedName.trim().length) return undefined @@ -66,6 +74,8 @@ export const ModalEditName = () => { const handleNameChange = (e: ChangeEvent) => setEnteredName(e.target.value) + const handleReceiverNpubChange = (e: ChangeEvent) => setReceiverNpub(e.target.value) + const getInputHelperText = () => { if (!debouncedName.trim().length || isNameEqual) return '' if (isChecking) return 'Loading...' @@ -90,17 +100,34 @@ export const ModalEditName = () => { return null } - const isEditButtonDisabled = isNameEqual || isChecking || isLoading || !enteredName.trim().length + const isEditButtonDisabled = isNameEqual || !isAvailable || isChecking || isLoading || !enteredName.trim().length + const isTransferButtonDisabled = !enteredName.trim().length || !receiverNpub.trim().length || isTransferLoading const handleEditName = async () => { + if (isEditButtonDisabled) return try { setIsLoading(true) - await swicCall('editName', npub, debouncedName) + await swicCall('editName', npub, enteredName) notify('Username successfully editted!', 'success') - setEnteredName(debouncedName) setIsLoading(false) - } catch (error) { + searchParams.set('name', enteredName) + setSearchParams(searchParams) + } catch (error: any) { setIsLoading(false) + notify(error?.message || 'Failed to edit username!', 'error') + } + } + + const handleTransferName = async () => { + if (isTransferButtonDisabled) return + try { + setIsTransferLoading(true) + await swicCall('transferName', npub, enteredName, receiverNpub) + notify('Npub successfully transfered!', 'success') + setIsTransferLoading(false) + } catch (error: any) { + setIsTransferLoading(false) + notify(error?.message || 'Failed to transfer npub!', 'error') } } @@ -129,8 +156,16 @@ export const ModalEditName = () => { - - + + diff --git a/src/modules/backend.ts b/src/modules/backend.ts index 626dd64..3a03fdc 100644 --- a/src/modules/backend.ts +++ b/src/modules/backend.ts @@ -192,7 +192,7 @@ class Nip46Backend extends NDKNip46Backend { // } // } -// FIXME why do we need it? Just to print +// FIXME why do we need it? Just to print // class EventHandlingStrategyWrapper implements IEventHandlingStrategy { // readonly backend: NDKNip46Backend // readonly method: string @@ -525,13 +525,11 @@ export class NoauthBackend { }) } - private async sendTransferNameToServer( - npub: string, name: string, newNpub: string - ) { + private async sendTransferNameToServer(npub: string, name: string, newNpub: string) { const body = JSON.stringify({ npub, name, - newNpub + newNpub, }) const method = 'PUT' @@ -803,7 +801,7 @@ export class NoauthBackend { return // noop case DECISION.ALLOW: case DECISION.DISALLOW: - // fall through + // fall through } const allow = decision === DECISION.ALLOW @@ -1154,8 +1152,8 @@ export class NoauthBackend { } private async editName(npub: string, name: string) { - const key = this.enckeys.find(k => k.npub == npub) - if (!key) throw new Error("Npub not found"); + const key = this.enckeys.find((k) => k.npub == npub) + if (!key) throw new Error('Npub not found') if (key.name) { await this.sendDeleteNameToServer(npub, key.name) } @@ -1168,10 +1166,10 @@ export class NoauthBackend { } private async transferName(npub: string, name: string, newNpub: string) { - const key = this.enckeys.find(k => k.npub == npub) - if (!key) throw new Error("Npub not found") - if (!name) throw new Error("Empty name") - if (key.name !== name) throw new Error("Name changed, please reload") + const key = this.enckeys.find((k) => k.npub == npub) + if (!key) throw new Error('Npub not found') + if (!name) throw new Error('Empty name') + if (key.name !== name) throw new Error('Name changed, please reload') await this.sendTransferNameToServer(npub, key.name, newNpub) await dbi.editName(npub, '') key.name = ''