diff --git a/src/layouts/PrimaryPageLayout/index.tsx b/src/layouts/PrimaryPageLayout/index.tsx
index 9136ea10..dd1c2703 100644
--- a/src/layouts/PrimaryPageLayout/index.tsx
+++ b/src/layouts/PrimaryPageLayout/index.tsx
@@ -3,8 +3,9 @@ import ScrollToTopButton from '@/components/ScrollToTopButton'
import { Titlebar } from '@/components/Titlebar'
import { ScrollArea } from '@/components/ui/scroll-area'
import { TPrimaryPageName, usePrimaryPage } from '@/PageManager'
+import { DeepBrowsingProvider } from '@/providers/DeepBrowsingProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
-import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react'
+import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react'
const PrimaryPageLayout = forwardRef(
(
@@ -22,8 +23,6 @@ const PrimaryPageLayout = forwardRef(
ref
) => {
const scrollAreaRef = useRef
(null)
- const [visible, setVisible] = useState(true)
- const [lastScrollTop, setLastScrollTop] = useState(0)
const { isSmallScreen } = useScreenSize()
const { current } = usePrimaryPage()
@@ -44,77 +43,39 @@ const PrimaryPageLayout = forwardRef(
useEffect(() => {
if (isSmallScreen) {
window.scrollTo({ top: 0 })
- setVisible(true)
return
}
}, [current])
- useEffect(() => {
- if (current !== pageName) return
-
- const handleScroll = () => {
- const atBottom = isSmallScreen
- ? window.innerHeight + window.scrollY >= document.body.offsetHeight - 20
- : scrollAreaRef.current
- ? scrollAreaRef.current?.clientHeight + scrollAreaRef.current?.scrollTop >=
- scrollAreaRef.current?.scrollHeight - 20
- : false
- if (atBottom) {
- setVisible(true)
- return
- }
-
- const scrollTop = (isSmallScreen ? window.scrollY : scrollAreaRef.current?.scrollTop) || 0
- const diff = scrollTop - lastScrollTop
- if (scrollTop <= 800) {
- setVisible(true)
- setLastScrollTop(scrollTop)
- return
- }
-
- if (diff > 20) {
- setVisible(false)
- setLastScrollTop(scrollTop)
- } else if (diff < -20) {
- setVisible(true)
- setLastScrollTop(scrollTop)
- }
- }
-
- if (isSmallScreen) {
- window.addEventListener('scroll', handleScroll)
- return () => {
- window.removeEventListener('scroll', handleScroll)
- }
- }
-
- scrollAreaRef.current?.addEventListener('scroll', handleScroll)
- return () => {
- scrollAreaRef.current?.removeEventListener('scroll', handleScroll)
- }
- }, [lastScrollTop, isSmallScreen, current])
+ if (isSmallScreen) {
+ return (
+
+
+ {titlebar &&
{titlebar}}
+ {children}
+ {displayScrollToTopButton &&
}
+
+
+
+ )
+ }
return (
-
- {titlebar && (
- {titlebar}
- )}
- {children}
- {displayScrollToTopButton && (
- 800}
- />
- )}
- {isSmallScreen && }
-
+
+
+ {titlebar && {titlebar}}
+ {children}
+
+ {displayScrollToTopButton && }
+
)
}
)
@@ -125,16 +86,6 @@ export type TPrimaryPageLayoutRef = {
scrollToTop: () => void
}
-function PrimaryPageTitlebar({
- children,
- visible = true
-}: {
- children?: React.ReactNode
- visible?: boolean
-}) {
- return (
-
- {children}
-
- )
+function PrimaryPageTitlebar({ children }: { children?: React.ReactNode }) {
+ return {children}
}
diff --git a/src/layouts/SecondaryPageLayout/index.tsx b/src/layouts/SecondaryPageLayout/index.tsx
index 53325394..59f4ccb0 100644
--- a/src/layouts/SecondaryPageLayout/index.tsx
+++ b/src/layouts/SecondaryPageLayout/index.tsx
@@ -4,8 +4,9 @@ import ScrollToTopButton from '@/components/ScrollToTopButton'
import { Titlebar } from '@/components/Titlebar'
import { ScrollArea } from '@/components/ui/scroll-area'
import { useSecondaryPage } from '@/PageManager'
+import { DeepBrowsingProvider } from '@/providers/DeepBrowsingProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
-import { useEffect, useRef, useState } from 'react'
+import { useEffect, useRef } from 'react'
export default function SecondaryPageLayout({
children,
@@ -23,118 +24,64 @@ export default function SecondaryPageLayout({
displayScrollToTopButton?: boolean
}): JSX.Element {
const scrollAreaRef = useRef(null)
- const [visible, setVisible] = useState(true)
- const [lastScrollTop, setLastScrollTop] = useState(0)
const { isSmallScreen } = useScreenSize()
const { currentIndex } = useSecondaryPage()
useEffect(() => {
if (isSmallScreen) {
window.scrollTo({ top: 0 })
- setVisible(true)
return
}
}, [])
- useEffect(() => {
- if (currentIndex !== index) return
-
- const handleScroll = () => {
- const atBottom = isSmallScreen
- ? window.innerHeight + window.scrollY >= document.body.offsetHeight - 20
- : scrollAreaRef.current
- ? scrollAreaRef.current?.clientHeight + scrollAreaRef.current?.scrollTop >=
- scrollAreaRef.current?.scrollHeight - 20
- : false
- if (atBottom) {
- setVisible(true)
- return
- }
-
- const scrollTop = (isSmallScreen ? window.scrollY : scrollAreaRef.current?.scrollTop) || 0
- const diff = scrollTop - lastScrollTop
- if (scrollTop <= 800) {
- setVisible(true)
- setLastScrollTop(scrollTop)
- return
- }
-
- if (diff > 20) {
- setVisible(false)
- setLastScrollTop(scrollTop)
- } else if (diff < -20) {
- setVisible(true)
- setLastScrollTop(scrollTop)
- }
- }
-
- if (isSmallScreen) {
- window.addEventListener('scroll', handleScroll)
- return () => {
- window.removeEventListener('scroll', handleScroll)
- }
- }
-
- scrollAreaRef.current?.addEventListener('scroll', handleScroll)
- return () => {
- scrollAreaRef.current?.removeEventListener('scroll', handleScroll)
- }
- }, [lastScrollTop, isSmallScreen, currentIndex])
+ if (isSmallScreen) {
+ return (
+
+
+
+
{children}
+ {displayScrollToTopButton &&
}
+
+
+
+ )
+ }
return (
-
-
- {children}
- {displayScrollToTopButton && (
- 800} />
- )}
- {isSmallScreen && }
-
+
+
+
+ {children}
+
+ {displayScrollToTopButton && }
+
)
}
export function SecondaryPageTitlebar({
title,
controls,
- hideBackButton = false,
- visible = true
+ hideBackButton = false
}: {
title?: React.ReactNode
controls?: React.ReactNode
hideBackButton?: boolean
- visible?: boolean
}): JSX.Element {
- const { isSmallScreen } = useScreenSize()
-
- if (isSmallScreen) {
- return (
-
- {title}
- {controls}
-
- )
- }
-
return (
-
-
- {title}
-
+
+ {title}
{controls}
)
diff --git a/src/providers/DeepBrowsingProvider.tsx b/src/providers/DeepBrowsingProvider.tsx
new file mode 100644
index 00000000..8348f233
--- /dev/null
+++ b/src/providers/DeepBrowsingProvider.tsx
@@ -0,0 +1,80 @@
+import { createContext, useContext, useEffect, useState } from 'react'
+
+type TDeepBrowsingContext = {
+ deepBrowsing: boolean
+ lastScrollTop: number
+}
+
+const DeepBrowsingContext = createContext(undefined)
+
+export const useDeepBrowsing = () => {
+ const context = useContext(DeepBrowsingContext)
+ if (!context) {
+ throw new Error('useDeepBrowsing must be used within a DeepBrowsingProvider')
+ }
+ return context
+}
+
+export function DeepBrowsingProvider({
+ children,
+ active,
+ scrollAreaRef
+}: {
+ children: React.ReactNode
+ active: boolean
+ scrollAreaRef?: React.RefObject
+}) {
+ const [deepBrowsing, setDeepBrowsing] = useState(false)
+ const [lastScrollTop, setLastScrollTop] = useState(0)
+
+ useEffect(() => {
+ if (!active) return
+
+ const handleScroll = () => {
+ const atBottom = !scrollAreaRef
+ ? window.innerHeight + window.scrollY >= document.body.offsetHeight - 20
+ : scrollAreaRef.current
+ ? scrollAreaRef.current?.clientHeight + scrollAreaRef.current?.scrollTop >=
+ scrollAreaRef.current?.scrollHeight - 20
+ : false
+ if (atBottom) {
+ setDeepBrowsing(false)
+ return
+ }
+
+ const scrollTop = (!scrollAreaRef ? window.scrollY : scrollAreaRef.current?.scrollTop) || 0
+ const diff = scrollTop - lastScrollTop
+ if (scrollTop <= 800) {
+ setDeepBrowsing(false)
+ setLastScrollTop(scrollTop)
+ return
+ }
+
+ if (diff > 20) {
+ setDeepBrowsing(true)
+ setLastScrollTop(scrollTop)
+ } else if (diff < -20) {
+ setDeepBrowsing(false)
+ setLastScrollTop(scrollTop)
+ }
+ }
+
+ if (!scrollAreaRef) {
+ window.addEventListener('scroll', handleScroll)
+ return () => {
+ window.removeEventListener('scroll', handleScroll)
+ }
+ }
+
+ scrollAreaRef.current?.addEventListener('scroll', handleScroll)
+ return () => {
+ scrollAreaRef.current?.removeEventListener('scroll', handleScroll)
+ }
+ }, [lastScrollTop, active])
+
+ return (
+
+ {children}
+
+ )
+}