import {
init as initNostrLogin,
launch as launchNostrLoginDialog
} from 'nostr-login'
import React, { useCallback, useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { toast } from 'react-toastify'
import { Banner } from '../components/Banner'
import { LoadingSpinner } from '../components/LoadingSpinner'
import { ZapButtons, ZapPresets, ZapQR } from '../components/Zap'
import { MetadataController, ZapController } from '../controllers'
import { useAppDispatch, useAppSelector } from '../hooks'
import { appRoutes } from '../routes'
import { setIsAuth, setUser } from '../store/reducers/user'
import mainStyles from '../styles//main.module.scss'
import navStyles from '../styles/nav.module.scss'
import '../styles/popup.css'
import { PaymentRequest } from '../types'
import { formatNumber, npubToHex, unformatNumber } from '../utils'
export const Header = () => {
const dispatch = useAppDispatch()
const userState = useAppSelector((state) => state.user)
useEffect(() => {
initNostrLogin({
darkMode: true,
localSignup: true,
noBanner: true,
onAuth: (npub, opts) => {
if (opts.type === 'logout') {
dispatch(setIsAuth(false))
dispatch(setUser(null))
} else {
dispatch(setIsAuth(true))
dispatch(
setUser({
npub,
pubkey: npubToHex(npub)!
})
)
MetadataController.getInstance().then((metadataController) => {
metadataController.findMetadata(npub).then((userProfile) => {
if (userProfile) {
dispatch(
setUser({
npub,
pubkey: npubToHex(npub)!,
...userProfile
})
)
}
})
})
}
}
})
}, [dispatch])
const handleLogin = () => {
launchNostrLoginDialog()
}
return (
Submit Mod
Write
Settings
{!userState.isAuth && (
Login
)}
{userState.isAuth && userState.user && (
{userState.user.image && (
![Profile Avatar]({userState.user.image})
)}
{userState.user.name ||
userState.user.displayName ||
userState.user.npub}
)}
)
}
const TipButtonWithDialog = React.memo(() => {
const [isOpen, setIsOpen] = useState(false)
const [isLoading, setIsLoading] = useState(false)
const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState('')
const [amount, setAmount] = useState(0)
const [message, setMessage] = useState('')
const [paymentRequest, setPaymentRequest] = useState()
const userState = useAppSelector((state) => state.user)
const handleClose = useCallback(() => {
setPaymentRequest(undefined)
setIsLoading(false)
setIsOpen(false)
}, [])
const handleQRExpiry = useCallback(() => {
setPaymentRequest(undefined)
}, [])
const handleAmountChange = (event: React.ChangeEvent) => {
const unformattedValue = unformatNumber(event.target.value)
setAmount(unformattedValue)
}
const generatePaymentRequest =
useCallback(async (): Promise => {
let userHexKey: string
setIsLoading(true)
setLoadingSpinnerDesc('Getting user pubkey')
if (userState.isAuth && userState.user?.pubkey) {
userHexKey = userState.user.pubkey as string
} else {
userHexKey = (await window.nostr?.getPublicKey()) as string
}
if (!userHexKey) {
setIsLoading(false)
toast.error('Could not get pubkey')
return null
}
setLoadingSpinnerDesc('Getting admin metadata')
const metadataController = await MetadataController.getInstance()
const adminMetadata = await metadataController.findAdminMetadata()
if (!adminMetadata?.lud16) {
setIsLoading(false)
toast.error('Lighting address (lud16) is missing in admin metadata!')
return null
}
if (!adminMetadata?.pubkey) {
setIsLoading(false)
toast.error('pubkey is missing in admin metadata!')
return null
}
const zapController = ZapController.getInstance()
setLoadingSpinnerDesc('Creating zap request')
return await zapController
.getLightningPaymentRequest(
adminMetadata.lud16,
amount,
adminMetadata.pubkey as string,
userHexKey,
message
)
.catch((err) => {
toast.error(err.message || err)
return null
})
.finally(() => {
setIsLoading(false)
})
}, [amount, message, userState])
const handleSend = useCallback(async () => {
const pr = await generatePaymentRequest()
if (!pr) return
setIsLoading(true)
setLoadingSpinnerDesc('Sending payment!')
const zapController = ZapController.getInstance()
if (await zapController.isWeblnProviderExists()) {
await zapController
.sendPayment(pr.pr)
.then(() => {
toast.success(`Successfully sent ${amount} sats!`)
handleClose()
})
.catch((err) => {
toast.error(err.message || err)
})
} else {
toast.warn('Webln is not present. Use QR code to send zap.')
setPaymentRequest(pr)
}
setIsLoading(false)
}, [amount, handleClose, generatePaymentRequest])
const handleGenerateQRCode = async () => {
const pr = await generatePaymentRequest()
if (!pr) return
setPaymentRequest(pr)
}
return (
<>
setIsOpen(true)}
>
Tip
{isOpen && (
setMessage(e.target.value)}
/>
{paymentRequest && (
)}
)}
{isLoading && }
>
)
})