Fix header carousel desync (#1696)

This commit is contained in:
ekzyis 2024-12-09 23:09:26 +01:00 committed by GitHub
parent d05a27a6c3
commit 61fb1c445f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 58 additions and 37 deletions

View File

@ -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)
}

View File

@ -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>
)
}

View File

@ -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'>