LightningAddressInput.tsx raw

   1  import { Button } from '@/components/ui/button'
   2  import { Input } from '@/components/ui/input'
   3  import { Label } from '@/components/ui/label'
   4  import { createProfileDraftEvent } from '@/lib/draft-event'
   5  import { isEmail } from '@/lib/utils'
   6  import { useNostr } from '@/providers/NostrProvider'
   7  import { Loader } from 'lucide-react'
   8  import { useEffect, useState } from 'react'
   9  import { useTranslation } from 'react-i18next'
  10  import { toast } from 'sonner'
  11  
  12  export default function LightningAddressInput() {
  13    const { t } = useTranslation()
  14    const { profile, profileEvent, publish, updateProfileEvent } = useNostr()
  15    const [lightningAddress, setLightningAddress] = useState('')
  16    const [hasChanged, setHasChanged] = useState(false)
  17    const [saving, setSaving] = useState(false)
  18  
  19    useEffect(() => {
  20      if (profile) {
  21        setLightningAddress(profile.lightningAddress || '')
  22      }
  23    }, [profile])
  24  
  25    if (!profile || !profileEvent) {
  26      return null
  27    }
  28  
  29    const handleSave = async () => {
  30      setSaving(true)
  31      const profileContent = profileEvent ? JSON.parse(profileEvent.content) : {}
  32      if (lightningAddress.startsWith('lnurl')) {
  33        profileContent.lud06 = lightningAddress
  34      } else if (isEmail(lightningAddress)) {
  35        profileContent.lud16 = lightningAddress
  36      } else if (lightningAddress) {
  37        toast.error(t('Invalid Lightning Address. Please enter a valid Lightning Address or LNURL.'))
  38        setSaving(false)
  39        return
  40      } else {
  41        delete profileContent.lud16
  42      }
  43  
  44      const profileDraftEvent = createProfileDraftEvent(
  45        JSON.stringify(profileContent),
  46        profileEvent?.tags
  47      )
  48      const newProfileEvent = await publish(profileDraftEvent)
  49      await updateProfileEvent(newProfileEvent)
  50      setSaving(false)
  51    }
  52  
  53    return (
  54      <div className="w-full space-y-1">
  55        <Label htmlFor="ln-address">{t('Lightning Address (or LNURL)')}</Label>
  56        <div className="flex w-full items-center gap-2">
  57          <Input
  58            id="ln-address"
  59            placeholder="xxxxxxxx@xxx.xxx"
  60            value={lightningAddress}
  61            onChange={(e) => {
  62              setLightningAddress(e.target.value)
  63              setHasChanged(true)
  64            }}
  65          />
  66          <Button onClick={handleSave} disabled={saving || !hasChanged} className="w-20">
  67            {saving ? <Loader className="animate-spin" /> : t('Save')}
  68          </Button>
  69        </div>
  70      </div>
  71    )
  72  }
  73