Skip to content

Commit 61fb1c4

Browse files
authored
Fix header carousel desync (#1696)
1 parent d05a27a commit 61fb1c4

File tree

3 files changed

+58
-37
lines changed

3 files changed

+58
-37
lines changed

components/nav/carousel.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { createContext, useCallback, useContext, useEffect, useState } from 'react'
2+
3+
const STORAGE_KEY = 'asSats'
4+
const DEFAULT_SELECTION = 'fiat'
5+
6+
const carousel = [
7+
'fiat',
8+
'yep',
9+
'1btc',
10+
'blockHeight',
11+
'chainFee',
12+
'halving'
13+
]
14+
15+
export const CarouselContext = createContext({
16+
selection: undefined,
17+
handleClick: () => {}
18+
})
19+
20+
export function CarouselProvider ({ children }) {
21+
const [selection, setSelection] = useState(undefined)
22+
const [pos, setPos] = useState(0)
23+
24+
useEffect(() => {
25+
const selection = window.localStorage.getItem(STORAGE_KEY) ?? DEFAULT_SELECTION
26+
setSelection(selection)
27+
setPos(carousel.findIndex((item) => item === selection))
28+
}, [])
29+
30+
const handleClick = useCallback(() => {
31+
const nextPos = (pos + 1) % carousel.length
32+
window.localStorage.setItem(STORAGE_KEY, carousel[nextPos])
33+
setSelection(carousel[nextPos])
34+
setPos(nextPos)
35+
}, [pos])
36+
37+
return (
38+
<CarouselContext.Provider value={[selection, handleClick]}>
39+
{children}
40+
</CarouselContext.Provider>
41+
)
42+
}
43+
44+
export function useCarousel () {
45+
return useContext(CarouselContext)
46+
}

components/nav/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useRouter } from 'next/router'
22
import DesktopHeader from './desktop/header'
33
import MobileHeader from './mobile/header'
44
import StickyBar from './sticky-bar'
5+
import { CarouselProvider } from './carousel'
56

67
export default function Navigation ({ sub }) {
78
const router = useRouter()
@@ -16,10 +17,10 @@ export default function Navigation ({ sub }) {
1617
}
1718

1819
return (
19-
<>
20+
<CarouselProvider>
2021
<DesktopHeader {...props} />
2122
<MobileHeader {...props} />
2223
<StickyBar {...props} />
23-
</>
24+
</CarouselProvider>
2425
)
2526
}

components/price.js

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useContext, useEffect, useMemo, useState } from 'react'
1+
import React, { useContext, useMemo } from 'react'
22
import { useQuery } from '@apollo/client'
33
import { fixedDecimal } from '@/lib/format'
44
import { useMe } from './me'
@@ -8,6 +8,7 @@ import { NORMAL_POLL_INTERVAL, SSR } from '@/lib/constants'
88
import { useBlockHeight } from './block-height'
99
import { useChainFee } from './chain-fee'
1010
import { CompactLongCountdown } from './countdown'
11+
import { useCarousel } from './nav/carousel'
1112

1213
export const PriceContext = React.createContext({
1314
price: null,
@@ -43,43 +44,16 @@ export function PriceProvider ({ price, children }) {
4344
)
4445
}
4546

46-
const STORAGE_KEY = 'asSats'
47-
const DEFAULT_SELECTION = 'fiat'
48-
49-
const carousel = [
50-
'fiat',
51-
'yep',
52-
'1btc',
53-
'blockHeight',
54-
'chainFee',
55-
'halving'
56-
]
57-
5847
export default function Price ({ className }) {
59-
const [asSats, setAsSats] = useState(undefined)
60-
const [pos, setPos] = useState(0)
61-
62-
useEffect(() => {
63-
const selection = window.localStorage.getItem(STORAGE_KEY) ?? DEFAULT_SELECTION
64-
setAsSats(selection)
65-
setPos(carousel.findIndex((item) => item === selection))
66-
}, [])
48+
const [selection, handleClick] = useCarousel()
6749

6850
const { price, fiatSymbol } = usePrice()
6951
const { height: blockHeight, halving } = useBlockHeight()
7052
const { fee: chainFee } = useChainFee()
7153

72-
const handleClick = () => {
73-
const nextPos = (pos + 1) % carousel.length
74-
75-
window.localStorage.setItem(STORAGE_KEY, carousel[nextPos])
76-
setAsSats(carousel[nextPos])
77-
setPos(nextPos)
78-
}
79-
8054
const compClassName = (className || '') + ' text-reset pointer'
8155

82-
if (asSats === 'yep') {
56+
if (selection === 'yep') {
8357
if (!price || price < 0) return null
8458
return (
8559
<div className={compClassName} onClick={handleClick} variant='link'>
@@ -88,15 +62,15 @@ export default function Price ({ className }) {
8862
)
8963
}
9064

91-
if (asSats === '1btc') {
65+
if (selection === '1btc') {
9266
return (
9367
<div className={compClassName} onClick={handleClick} variant='link'>
9468
1sat=1sat
9569
</div>
9670
)
9771
}
9872

99-
if (asSats === 'blockHeight') {
73+
if (selection === 'blockHeight') {
10074
if (blockHeight <= 0) return null
10175
return (
10276
<div className={compClassName} onClick={handleClick} variant='link'>
@@ -105,7 +79,7 @@ export default function Price ({ className }) {
10579
)
10680
}
10781

108-
if (asSats === 'halving') {
82+
if (selection === 'halving') {
10983
if (!halving) return null
11084
return (
11185
<div className={compClassName} onClick={handleClick} variant='link'>
@@ -114,7 +88,7 @@ export default function Price ({ className }) {
11488
)
11589
}
11690

117-
if (asSats === 'chainFee') {
91+
if (selection === 'chainFee') {
11892
if (chainFee <= 0) return null
11993
return (
12094
<div className={compClassName} onClick={handleClick} variant='link'>
@@ -123,7 +97,7 @@ export default function Price ({ className }) {
12397
)
12498
}
12599

126-
if (asSats === 'fiat') {
100+
if (selection === 'fiat') {
127101
if (!price || price < 0) return null
128102
return (
129103
<div className={compClassName} onClick={handleClick} variant='link'>

0 commit comments

Comments
 (0)