import React, { useContext, useEffect, useMemo, useState } from 'react' import { useQuery } from '@apollo/client' import { fixedDecimal } from '@/lib/format' import { useMe } from './me' import { PRICE } from '@/fragments/price' import { CURRENCY_SYMBOLS } from '@/lib/currency' import { NORMAL_POLL_INTERVAL, SSR } from '@/lib/constants' import { useBlockHeight } from './block-height' import { useChainFee } from './chain-fee' import { CompactLongCountdown } from './countdown' export const PriceContext = React.createContext({ price: null, fiatSymbol: null }) export function usePrice () { return useContext(PriceContext) } export function PriceProvider ({ price, children }) { const me = useMe() const fiatCurrency = me?.privates?.fiatCurrency const { data } = useQuery(PRICE, { variables: { fiatCurrency }, ...(SSR ? {} : { pollInterval: NORMAL_POLL_INTERVAL, nextFetchPolicy: 'cache-and-network' }) }) const contextValue = useMemo(() => ({ price: data?.price || price, fiatSymbol: CURRENCY_SYMBOLS[fiatCurrency] || '$' }), [data?.price, price, me?.privates?.fiatCurrency]) return ( {children} ) } const STORAGE_KEY = 'asSats' const DEFAULT_SELECTION = 'fiat' const carousel = [ 'fiat', 'yep', '1btc', 'blockHeight', 'chainFee', 'halving' ] export default function Price ({ className }) { const [asSats, setAsSats] = useState(undefined) const [pos, setPos] = useState(0) useEffect(() => { const selection = window.localStorage.getItem(STORAGE_KEY) ?? DEFAULT_SELECTION setAsSats(selection) setPos(carousel.findIndex((item) => item === selection)) }, []) const { price, fiatSymbol } = usePrice() const { height: blockHeight, halving } = useBlockHeight() const { fee: chainFee } = useChainFee() const handleClick = () => { const nextPos = (pos + 1) % carousel.length window.localStorage.setItem(STORAGE_KEY, carousel[nextPos]) setAsSats(carousel[nextPos]) setPos(nextPos) } const compClassName = (className || '') + ' text-reset pointer' if (asSats === 'yep') { if (!price || price < 0) return null return (
{fixedDecimal(100000000 / price, 0) + ` sats/${fiatSymbol}`}
) } if (asSats === '1btc') { return (
1sat=1sat
) } if (asSats === 'blockHeight') { if (blockHeight <= 0) return null return (
{blockHeight}
) } if (asSats === 'halving') { if (!halving) return null return (
) } if (asSats === 'chainFee') { if (chainFee <= 0) return null return (
{chainFee} sat/vB
) } if (asSats === 'fiat') { if (!price || price < 0) return null return (
{fiatSymbol + fixedDecimal(price, 0)}
) } }