2023-03-10 01:10:49 +00:00
|
|
|
import { HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives'
|
2023-02-27 01:49:49 +00:00
|
|
|
import { Button } from '../../elements/Button'
|
2023-03-02 05:24:18 +00:00
|
|
|
import { LogoBox } from '../../elements/LogoBox'
|
2024-02-20 02:44:14 +00:00
|
|
|
import { ReactNode, useEffect, useState } from 'react'
|
2024-02-09 06:02:05 +00:00
|
|
|
import { DEFAULT_HEADER_HEIGHT } from '../homeFeed/HeaderSpacer'
|
2023-03-03 12:46:12 +00:00
|
|
|
import { theme } from '../../tokens/stitches.config'
|
2023-08-01 04:31:12 +00:00
|
|
|
import { ReaderSettingsIcon } from '../../elements/icons/ReaderSettingsIcon'
|
2023-02-25 11:31:06 +00:00
|
|
|
|
2024-02-20 02:44:14 +00:00
|
|
|
function useScrollDirection() {
|
|
|
|
|
const [scrollDirection, setScrollDirection] = useState('up')
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
let lastScrollY = window.pageYOffset
|
|
|
|
|
|
|
|
|
|
const updateScrollDirection = () => {
|
|
|
|
|
const scrollY = window.pageYOffset
|
|
|
|
|
const direction = scrollY > lastScrollY ? 'down' : 'up'
|
|
|
|
|
if (
|
|
|
|
|
direction !== scrollDirection &&
|
|
|
|
|
(scrollY - lastScrollY > 10 || scrollY - lastScrollY < -10)
|
|
|
|
|
) {
|
|
|
|
|
setScrollDirection(direction)
|
|
|
|
|
}
|
|
|
|
|
lastScrollY = scrollY > 0 ? scrollY : 0
|
|
|
|
|
}
|
|
|
|
|
window.addEventListener('scroll', updateScrollDirection) // add event listener
|
|
|
|
|
return () => {
|
|
|
|
|
window.removeEventListener('scroll', updateScrollDirection) // clean up
|
|
|
|
|
}
|
|
|
|
|
}, [scrollDirection])
|
|
|
|
|
|
|
|
|
|
return scrollDirection
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-27 07:37:00 +00:00
|
|
|
type ReaderHeaderProps = {
|
2023-03-06 06:31:39 +00:00
|
|
|
alwaysDisplayToolbar: boolean
|
2023-05-25 07:36:44 +00:00
|
|
|
hideDisplaySettings: boolean
|
2023-02-27 07:37:00 +00:00
|
|
|
showDisplaySettingsModal: (show: boolean) => void
|
2023-03-02 09:04:31 +00:00
|
|
|
children?: ReactNode
|
2023-02-27 07:37:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function ReaderHeader(props: ReaderHeaderProps): JSX.Element {
|
2024-02-20 02:44:14 +00:00
|
|
|
const scrollDirection = useScrollDirection()
|
2023-02-25 11:31:06 +00:00
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<VStack
|
|
|
|
|
alignment="center"
|
|
|
|
|
distribution="start"
|
|
|
|
|
css={{
|
|
|
|
|
top: '0',
|
|
|
|
|
left: '0',
|
2023-03-03 12:52:59 +00:00
|
|
|
zIndex: 1,
|
2023-05-25 04:56:58 +00:00
|
|
|
pt: '0px',
|
2024-02-16 07:34:39 +00:00
|
|
|
pb: '15px',
|
2023-02-25 11:31:06 +00:00
|
|
|
position: 'fixed',
|
|
|
|
|
width: '100%',
|
2024-02-08 11:03:22 +00:00
|
|
|
height: DEFAULT_HEADER_HEIGHT,
|
2023-03-06 06:31:39 +00:00
|
|
|
display: props.alwaysDisplayToolbar ? 'flex' : 'transparent',
|
2023-05-30 08:18:11 +00:00
|
|
|
pointerEvents: props.alwaysDisplayToolbar ? 'unset' : 'none',
|
2023-08-07 07:34:10 +00:00
|
|
|
borderBottom: '1px solid transparent',
|
2023-03-06 01:50:11 +00:00
|
|
|
'@xlgDown': {
|
2023-08-02 05:11:16 +00:00
|
|
|
bg: '$readerBg',
|
2023-05-25 03:07:18 +00:00
|
|
|
pointerEvents: 'unset',
|
2023-02-25 11:31:06 +00:00
|
|
|
},
|
2023-03-09 08:44:45 +00:00
|
|
|
'@mdDown': {
|
2024-02-20 02:44:14 +00:00
|
|
|
top: scrollDirection === 'down' ? '-90px' : '0',
|
2023-03-09 08:44:45 +00:00
|
|
|
bg: '$readerBg',
|
2023-05-25 03:07:18 +00:00
|
|
|
pointerEvents: 'unset',
|
2024-02-20 02:44:14 +00:00
|
|
|
transitionProperty: 'top',
|
|
|
|
|
transitionTimingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
|
|
|
transitionDuration: '200ms',
|
2023-03-09 08:44:45 +00:00
|
|
|
},
|
2023-06-27 10:27:45 +00:00
|
|
|
'@media print': {
|
|
|
|
|
display: 'none',
|
|
|
|
|
},
|
2023-02-25 11:31:06 +00:00
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<HStack
|
|
|
|
|
alignment="center"
|
|
|
|
|
distribution="start"
|
|
|
|
|
css={{
|
|
|
|
|
width: '100%',
|
|
|
|
|
height: '100%',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<LogoBox />
|
2023-03-03 13:55:04 +00:00
|
|
|
<SpanBox
|
|
|
|
|
css={{
|
|
|
|
|
width: '100%',
|
|
|
|
|
px: '25px',
|
2023-03-06 06:31:39 +00:00
|
|
|
'@lg': {
|
|
|
|
|
display: props.alwaysDisplayToolbar ? 'flex' : 'none',
|
|
|
|
|
},
|
2023-03-03 13:55:04 +00:00
|
|
|
'@mdDown': { px: '15px' },
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{props.children}
|
|
|
|
|
</SpanBox>
|
2023-05-25 07:36:44 +00:00
|
|
|
{!props.alwaysDisplayToolbar && !props.hideDisplaySettings && (
|
2023-03-06 06:47:02 +00:00
|
|
|
<SpanBox
|
|
|
|
|
css={{
|
|
|
|
|
width: '100%',
|
|
|
|
|
'@lgDown': {
|
|
|
|
|
display: 'none',
|
|
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<ControlButtonBox {...props} />
|
|
|
|
|
</SpanBox>
|
|
|
|
|
)}
|
2023-02-25 11:31:06 +00:00
|
|
|
</HStack>
|
|
|
|
|
</VStack>
|
|
|
|
|
</>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-27 07:37:00 +00:00
|
|
|
function ControlButtonBox(props: ReaderHeaderProps): JSX.Element {
|
2023-02-25 11:31:06 +00:00
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<HStack
|
|
|
|
|
alignment="center"
|
|
|
|
|
distribution="end"
|
|
|
|
|
css={{
|
|
|
|
|
marginLeft: 'auto',
|
2023-03-06 01:50:11 +00:00
|
|
|
marginRight: '25px',
|
2023-02-25 11:31:06 +00:00
|
|
|
width: '100px',
|
|
|
|
|
height: '100%',
|
|
|
|
|
gap: '20px',
|
|
|
|
|
minWidth: '121px',
|
2023-05-25 12:16:55 +00:00
|
|
|
pointerEvents: 'all',
|
2023-02-25 11:31:06 +00:00
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Button
|
2023-11-01 07:16:05 +00:00
|
|
|
title="Reader preferences (d)"
|
2023-02-25 11:31:06 +00:00
|
|
|
style="articleActionIcon"
|
2023-02-27 07:37:00 +00:00
|
|
|
onClick={() => {
|
|
|
|
|
props.showDisplaySettingsModal(true)
|
|
|
|
|
}}
|
2023-02-25 11:31:06 +00:00
|
|
|
>
|
2023-08-01 09:27:58 +00:00
|
|
|
<ReaderSettingsIcon
|
|
|
|
|
size={25}
|
|
|
|
|
color={theme.colors.thHighContrast.toString()}
|
|
|
|
|
/>
|
2023-02-25 11:31:06 +00:00
|
|
|
</Button>
|
|
|
|
|
</HStack>
|
|
|
|
|
</>
|
|
|
|
|
)
|
|
|
|
|
}
|