Fix header carousel desync (#1696)
This commit is contained in:
parent
d05a27a6c3
commit
61fb1c445f
|
@ -0,0 +1,46 @@
|
|||
import { createContext, useCallback, useContext, useEffect, useState } from 'react'
|
||||
|
||||
const STORAGE_KEY = 'asSats'
|
||||
const DEFAULT_SELECTION = 'fiat'
|
||||
|
||||
const carousel = [
|
||||
'fiat',
|
||||
'yep',
|
||||
'1btc',
|
||||
'blockHeight',
|
||||
'chainFee',
|
||||
'halving'
|
||||
]
|
||||
|
||||
export const CarouselContext = createContext({
|
||||
selection: undefined,
|
||||
handleClick: () => {}
|
||||
})
|
||||
|
||||
export function CarouselProvider ({ children }) {
|
||||
const [selection, setSelection] = useState(undefined)
|
||||
const [pos, setPos] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
const selection = window.localStorage.getItem(STORAGE_KEY) ?? DEFAULT_SELECTION
|
||||
setSelection(selection)
|
||||
setPos(carousel.findIndex((item) => item === selection))
|
||||
}, [])
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
const nextPos = (pos + 1) % carousel.length
|
||||
window.localStorage.setItem(STORAGE_KEY, carousel[nextPos])
|
||||
setSelection(carousel[nextPos])
|
||||
setPos(nextPos)
|
||||
}, [pos])
|
||||
|
||||
return (
|
||||
<CarouselContext.Provider value={[selection, handleClick]}>
|
||||
{children}
|
||||
</CarouselContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useCarousel () {
|
||||
return useContext(CarouselContext)
|
||||
}
|
|
@ -2,6 +2,7 @@ import { useRouter } from 'next/router'
|
|||
import DesktopHeader from './desktop/header'
|
||||
import MobileHeader from './mobile/header'
|
||||
import StickyBar from './sticky-bar'
|
||||
import { CarouselProvider } from './carousel'
|
||||
|
||||
export default function Navigation ({ sub }) {
|
||||
const router = useRouter()
|
||||
|
@ -16,10 +17,10 @@ export default function Navigation ({ sub }) {
|
|||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<CarouselProvider>
|
||||
<DesktopHeader {...props} />
|
||||
<MobileHeader {...props} />
|
||||
<StickyBar {...props} />
|
||||
</>
|
||||
</CarouselProvider>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useContext, useEffect, useMemo, useState } from 'react'
|
||||
import React, { useContext, useMemo } from 'react'
|
||||
import { useQuery } from '@apollo/client'
|
||||
import { fixedDecimal } from '@/lib/format'
|
||||
import { useMe } from './me'
|
||||
|
@ -8,6 +8,7 @@ import { NORMAL_POLL_INTERVAL, SSR } from '@/lib/constants'
|
|||
import { useBlockHeight } from './block-height'
|
||||
import { useChainFee } from './chain-fee'
|
||||
import { CompactLongCountdown } from './countdown'
|
||||
import { useCarousel } from './nav/carousel'
|
||||
|
||||
export const PriceContext = React.createContext({
|
||||
price: null,
|
||||
|
@ -43,43 +44,16 @@ export function PriceProvider ({ price, 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 [selection, handleClick] = useCarousel()
|
||||
|
||||
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 (selection === 'yep') {
|
||||
if (!price || price < 0) return null
|
||||
return (
|
||||
<div className={compClassName} onClick={handleClick} variant='link'>
|
||||
|
@ -88,7 +62,7 @@ export default function Price ({ className }) {
|
|||
)
|
||||
}
|
||||
|
||||
if (asSats === '1btc') {
|
||||
if (selection === '1btc') {
|
||||
return (
|
||||
<div className={compClassName} onClick={handleClick} variant='link'>
|
||||
1sat=1sat
|
||||
|
@ -96,7 +70,7 @@ export default function Price ({ className }) {
|
|||
)
|
||||
}
|
||||
|
||||
if (asSats === 'blockHeight') {
|
||||
if (selection === 'blockHeight') {
|
||||
if (blockHeight <= 0) return null
|
||||
return (
|
||||
<div className={compClassName} onClick={handleClick} variant='link'>
|
||||
|
@ -105,7 +79,7 @@ export default function Price ({ className }) {
|
|||
)
|
||||
}
|
||||
|
||||
if (asSats === 'halving') {
|
||||
if (selection === 'halving') {
|
||||
if (!halving) return null
|
||||
return (
|
||||
<div className={compClassName} onClick={handleClick} variant='link'>
|
||||
|
@ -114,7 +88,7 @@ export default function Price ({ className }) {
|
|||
)
|
||||
}
|
||||
|
||||
if (asSats === 'chainFee') {
|
||||
if (selection === 'chainFee') {
|
||||
if (chainFee <= 0) return null
|
||||
return (
|
||||
<div className={compClassName} onClick={handleClick} variant='link'>
|
||||
|
@ -123,7 +97,7 @@ export default function Price ({ className }) {
|
|||
)
|
||||
}
|
||||
|
||||
if (asSats === 'fiat') {
|
||||
if (selection === 'fiat') {
|
||||
if (!price || price < 0) return null
|
||||
return (
|
||||
<div className={compClassName} onClick={handleClick} variant='link'>
|
||||
|
|
Loading…
Reference in New Issue