From 61fb1c445fe0a392369050f0ada600489650bcc2 Mon Sep 17 00:00:00 2001 From: ekzyis Date: Mon, 9 Dec 2024 23:09:26 +0100 Subject: [PATCH] Fix header carousel desync (#1696) --- components/nav/carousel.js | 46 ++++++++++++++++++++++++++++++++++++++ components/nav/index.js | 5 +++-- components/price.js | 44 ++++++++---------------------------- 3 files changed, 58 insertions(+), 37 deletions(-) create mode 100644 components/nav/carousel.js diff --git a/components/nav/carousel.js b/components/nav/carousel.js new file mode 100644 index 00000000..293e9c28 --- /dev/null +++ b/components/nav/carousel.js @@ -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 ( + + {children} + + ) +} + +export function useCarousel () { + return useContext(CarouselContext) +} diff --git a/components/nav/index.js b/components/nav/index.js index 9413bbd6..f8906b27 100644 --- a/components/nav/index.js +++ b/components/nav/index.js @@ -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 ( - <> + - + ) } diff --git a/components/price.js b/components/price.js index b104b5df..415c0877 100644 --- a/components/price.js +++ b/components/price.js @@ -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 (
@@ -88,7 +62,7 @@ export default function Price ({ className }) { ) } - if (asSats === '1btc') { + if (selection === '1btc') { return (
1sat=1sat @@ -96,7 +70,7 @@ export default function Price ({ className }) { ) } - if (asSats === 'blockHeight') { + if (selection === 'blockHeight') { if (blockHeight <= 0) return null return (
@@ -105,7 +79,7 @@ export default function Price ({ className }) { ) } - if (asSats === 'halving') { + if (selection === 'halving') { if (!halving) return null return (
@@ -114,7 +88,7 @@ export default function Price ({ className }) { ) } - if (asSats === 'chainFee') { + if (selection === 'chainFee') { if (chainFee <= 0) return null return (
@@ -123,7 +97,7 @@ export default function Price ({ className }) { ) } - if (asSats === 'fiat') { + if (selection === 'fiat') { if (!price || price < 0) return null return (