Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
0f710c19
Commit
0f710c19
authored
Nov 30, 2022
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor scroll direction context
parent
7bc58a3f
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
123 additions
and
123 deletions
+123
-123
scrollDirection.tsx
lib/contexts/scrollDirection.tsx
+23
-6
_app.tsx
pages/_app.tsx
+3
-6
ScrollDirectionContext.tsx
ui/ScrollDirectionContext.tsx
+0
-5
ActionBar.tsx
ui/shared/ActionBar.tsx
+20
-23
Header.tsx
ui/snippets/header/Header.tsx
+44
-47
SearchBarMobile.tsx
ui/snippets/searchBar/SearchBarMobile.tsx
+33
-36
No files found.
lib/
hooks/useScrollDirection.ts
→
lib/
contexts/scrollDirection.tsx
View file @
0f710c19
...
@@ -2,22 +2,27 @@ import clamp from 'lodash/clamp';
...
@@ -2,22 +2,27 @@ import clamp from 'lodash/clamp';
import
throttle
from
'
lodash/throttle
'
;
import
throttle
from
'
lodash/throttle
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
const
ScrollDirectionContext
=
React
.
createContext
<
'
up
'
|
'
down
'
|
null
>
(
null
);
import
isBrowser
from
'
lib/isBrowser
'
;
import
isBrowser
from
'
lib/isBrowser
'
;
const
SCROLL_DIFF_THRESHOLD
=
20
;
const
SCROLL_DIFF_THRESHOLD
=
20
;
type
Directions
=
'
up
'
|
'
down
'
;
type
Directions
=
'
up
'
|
'
down
'
;
export
default
function
useScrollDirection
()
{
interface
Props
{
children
:
React
.
ReactNode
;
}
export
function
ScrollDirectionProvider
({
children
}:
Props
)
{
const
prevScrollPosition
=
React
.
useRef
(
isBrowser
()
?
window
.
pageYOffset
:
0
);
const
prevScrollPosition
=
React
.
useRef
(
isBrowser
()
?
window
.
pageYOffset
:
0
);
const
[
scrollDirection
,
setDirection
]
=
React
.
useState
<
Directions
>
(
);
const
[
scrollDirection
,
setDirection
]
=
React
.
useState
<
Directions
|
null
>
(
null
);
const
handleScroll
=
React
.
useCallback
(()
=>
{
const
handleScroll
=
React
.
useCallback
(()
=>
{
const
currentScrollPosition
=
clamp
(
window
.
pageYOffset
,
0
,
window
.
document
.
body
.
scrollHeight
-
window
.
innerHeight
);
const
currentScrollPosition
=
clamp
(
window
.
pageYOffset
,
0
,
window
.
document
.
body
.
scrollHeight
-
window
.
innerHeight
);
const
scrollDiff
=
currentScrollPosition
-
prevScrollPosition
.
current
;
const
scrollDiff
=
currentScrollPosition
-
prevScrollPosition
.
current
;
if
(
window
.
pageYOffset
===
0
)
{
if
(
window
.
pageYOffset
===
0
)
{
setDirection
(
undefined
);
setDirection
(
null
);
}
else
if
(
Math
.
abs
(
scrollDiff
)
>
SCROLL_DIFF_THRESHOLD
)
{
}
else
if
(
Math
.
abs
(
scrollDiff
)
>
SCROLL_DIFF_THRESHOLD
)
{
setDirection
(
scrollDiff
<
0
?
'
up
'
:
'
down
'
);
setDirection
(
scrollDiff
<
0
?
'
up
'
:
'
down
'
);
}
}
...
@@ -33,9 +38,21 @@ export default function useScrollDirection() {
...
@@ -33,9 +38,21 @@ export default function useScrollDirection() {
return
()
=>
{
return
()
=>
{
window
.
removeEventListener
(
'
scroll
'
,
throttledHandleScroll
);
window
.
removeEventListener
(
'
scroll
'
,
throttledHandleScroll
);
};
};
// replicate componentDidMount
// replicate componentDidMount
// eslint-disable-next-line react-hooks/exhaustive-deps
// eslint-disable-next-line react-hooks/exhaustive-deps
},
[]);
},
[]);
return
scrollDirection
;
return
(
<
ScrollDirectionContext
.
Provider
value=
{
scrollDirection
}
>
{
children
}
</
ScrollDirectionContext
.
Provider
>
);
}
export
function
useScrollDirection
()
{
const
context
=
React
.
useContext
(
ScrollDirectionContext
);
if
(
context
===
undefined
)
{
throw
new
Error
(
'
useScrollDirection must be used within a ScrollDirectionProvider
'
);
}
return
context
;
}
}
pages/_app.tsx
View file @
0f710c19
...
@@ -7,19 +7,16 @@ import React, { useState } from 'react';
...
@@ -7,19 +7,16 @@ import React, { useState } from 'react';
import
appConfig
from
'
configs/app/config
'
;
import
appConfig
from
'
configs/app/config
'
;
import
{
AppContextProvider
}
from
'
lib/appContext
'
;
import
{
AppContextProvider
}
from
'
lib/appContext
'
;
import
{
Chakra
}
from
'
lib/Chakra
'
;
import
{
Chakra
}
from
'
lib/Chakra
'
;
import
{
ScrollDirectionProvider
}
from
'
lib/contexts/scrollDirection
'
;
import
useConfigSentry
from
'
lib/hooks/useConfigSentry
'
;
import
useConfigSentry
from
'
lib/hooks/useConfigSentry
'
;
import
type
{
ErrorType
}
from
'
lib/hooks/useFetch
'
;
import
type
{
ErrorType
}
from
'
lib/hooks/useFetch
'
;
import
useScrollDirection
from
'
lib/hooks/useScrollDirection
'
;
import
{
SocketProvider
}
from
'
lib/socket/context
'
;
import
{
SocketProvider
}
from
'
lib/socket/context
'
;
import
theme
from
'
theme
'
;
import
theme
from
'
theme
'
;
import
ScrollDirectionContext
from
'
ui/ScrollDirectionContext
'
;
import
AppError
from
'
ui/shared/AppError/AppError
'
;
import
AppError
from
'
ui/shared/AppError/AppError
'
;
import
ErrorBoundary
from
'
ui/shared/ErrorBoundary
'
;
import
ErrorBoundary
from
'
ui/shared/ErrorBoundary
'
;
function
MyApp
({
Component
,
pageProps
}:
AppProps
)
{
function
MyApp
({
Component
,
pageProps
}:
AppProps
)
{
useConfigSentry
();
useConfigSentry
();
const
directionContext
=
useScrollDirection
();
const
[
queryClient
]
=
useState
(()
=>
new
QueryClient
({
const
[
queryClient
]
=
useState
(()
=>
new
QueryClient
({
defaultOptions
:
{
defaultOptions
:
{
queries
:
{
queries
:
{
...
@@ -62,11 +59,11 @@ function MyApp({ Component, pageProps }: AppProps) {
...
@@ -62,11 +59,11 @@ function MyApp({ Component, pageProps }: AppProps) {
<
ErrorBoundary
renderErrorScreen=
{
renderErrorScreen
}
onError=
{
handleError
}
>
<
ErrorBoundary
renderErrorScreen=
{
renderErrorScreen
}
onError=
{
handleError
}
>
<
AppContextProvider
pageProps=
{
pageProps
}
>
<
AppContextProvider
pageProps=
{
pageProps
}
>
<
QueryClientProvider
client=
{
queryClient
}
>
<
QueryClientProvider
client=
{
queryClient
}
>
<
ScrollDirection
Context
.
Provider
value=
{
directionContext
}
>
<
ScrollDirection
Provider
>
<
SocketProvider
url=
{
`${ appConfig.api.socket }${ appConfig.api.basePath }/socket/v2`
}
>
<
SocketProvider
url=
{
`${ appConfig.api.socket }${ appConfig.api.basePath }/socket/v2`
}
>
<
Component
{
...
pageProps
}
/>
<
Component
{
...
pageProps
}
/>
</
SocketProvider
>
</
SocketProvider
>
</
ScrollDirection
Context
.
Provider
>
</
ScrollDirectionProvider
>
<
ReactQueryDevtools
/>
<
ReactQueryDevtools
/>
</
QueryClientProvider
>
</
QueryClientProvider
>
</
AppContextProvider
>
</
AppContextProvider
>
...
...
ui/ScrollDirectionContext.tsx
deleted
100644 → 0
View file @
7bc58a3f
import
React
from
'
react
'
;
const
ScrollDirectionContext
=
React
.
createContext
<
'
up
'
|
'
down
'
|
undefined
>
(
undefined
);
export
default
ScrollDirectionContext
;
ui/shared/ActionBar.tsx
View file @
0f710c19
...
@@ -2,7 +2,7 @@ import { Flex, useColorModeValue, chakra } from '@chakra-ui/react';
...
@@ -2,7 +2,7 @@ import { Flex, useColorModeValue, chakra } from '@chakra-ui/react';
import
throttle
from
'
lodash/throttle
'
;
import
throttle
from
'
lodash/throttle
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
ScrollDirectionContext
from
'
ui/ScrollDirectionContext
'
;
import
{
useScrollDirection
}
from
'
lib/contexts/scrollDirection
'
;
type
Props
=
{
type
Props
=
{
children
:
React
.
ReactNode
;
children
:
React
.
ReactNode
;
...
@@ -15,6 +15,7 @@ const TOP_DOWN = 0;
...
@@ -15,6 +15,7 @@ const TOP_DOWN = 0;
const
ActionBar
=
({
children
,
className
}:
Props
)
=>
{
const
ActionBar
=
({
children
,
className
}:
Props
)
=>
{
const
[
isSticky
,
setIsSticky
]
=
React
.
useState
(
false
);
const
[
isSticky
,
setIsSticky
]
=
React
.
useState
(
false
);
const
ref
=
React
.
useRef
<
HTMLDivElement
>
(
null
);
const
ref
=
React
.
useRef
<
HTMLDivElement
>
(
null
);
const
scrollDirection
=
useScrollDirection
();
const
handleScroll
=
React
.
useCallback
(()
=>
{
const
handleScroll
=
React
.
useCallback
(()
=>
{
if
(
if
(
...
@@ -41,28 +42,24 @@ const ActionBar = ({ children, className }: Props) => {
...
@@ -41,28 +42,24 @@ const ActionBar = ({ children, className }: Props) => {
const
bgColor
=
useColorModeValue
(
'
white
'
,
'
black
'
);
const
bgColor
=
useColorModeValue
(
'
white
'
,
'
black
'
);
return
(
return
(
<
ScrollDirectionContext
.
Consumer
>
<
Flex
{
(
scrollDirection
)
=>
(
className=
{
className
}
<
Flex
backgroundColor=
{
bgColor
}
className=
{
className
}
py=
{
6
}
backgroundColor=
{
bgColor
}
mx=
{
{
base
:
-
4
,
lg
:
0
}
}
py=
{
6
}
px=
{
{
base
:
4
,
lg
:
0
}
}
mx=
{
{
base
:
-
4
,
lg
:
0
}
}
justifyContent=
"space-between"
px=
{
{
base
:
4
,
lg
:
0
}
}
width=
{
{
base
:
'
100vw
'
,
lg
:
'
unset
'
}
}
justifyContent=
"space-between"
position=
"sticky"
width=
{
{
base
:
'
100vw
'
,
lg
:
'
unset
'
}
}
top=
{
{
base
:
scrollDirection
===
'
down
'
?
`${ TOP_DOWN }px`
:
`${ TOP_UP }px`
,
lg
:
0
}
}
position=
"sticky"
transitionProperty=
"top,box-shadow,background-color,color"
top=
{
{
base
:
scrollDirection
===
'
down
'
?
`${ TOP_DOWN }px`
:
`${ TOP_UP }px`
,
lg
:
0
}
}
transitionDuration=
"slow"
transitionProperty=
"top,box-shadow,background-color,color"
zIndex=
{
{
base
:
'
sticky2
'
,
lg
:
'
docked
'
}
}
transitionDuration=
"slow"
boxShadow=
{
{
base
:
isSticky
?
'
md
'
:
'
none
'
,
lg
:
'
none
'
}
}
zIndex=
{
{
base
:
'
sticky2
'
,
lg
:
'
docked
'
}
}
ref=
{
ref
}
boxShadow=
{
{
base
:
isSticky
?
'
md
'
:
'
none
'
,
lg
:
'
none
'
}
}
>
ref=
{
ref
}
{
children
}
>
</
Flex
>
{
children
}
</
Flex
>
)
}
</
ScrollDirectionContext
.
Consumer
>
);
);
};
};
...
...
ui/snippets/header/Header.tsx
View file @
0f710c19
import
{
HStack
,
Box
,
Flex
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
HStack
,
Box
,
Flex
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
ScrollDirectionContext
from
'
ui/ScrollDirectionContext
'
;
import
{
useScrollDirection
}
from
'
lib/contexts/scrollDirection
'
;
import
NetworkLogo
from
'
ui/snippets/networkMenu/NetworkLogo
'
;
import
NetworkLogo
from
'
ui/snippets/networkMenu/NetworkLogo
'
;
import
ProfileMenuDesktop
from
'
ui/snippets/profileMenu/ProfileMenuDesktop
'
;
import
ProfileMenuDesktop
from
'
ui/snippets/profileMenu/ProfileMenuDesktop
'
;
import
ProfileMenuMobile
from
'
ui/snippets/profileMenu/ProfileMenuMobile
'
;
import
ProfileMenuMobile
from
'
ui/snippets/profileMenu/ProfileMenuMobile
'
;
...
@@ -17,56 +17,53 @@ type Props = {
...
@@ -17,56 +17,53 @@ type Props = {
const
Header
=
({
hideOnScrollDown
,
isHomePage
}:
Props
)
=>
{
const
Header
=
({
hideOnScrollDown
,
isHomePage
}:
Props
)
=>
{
const
bgColor
=
useColorModeValue
(
'
white
'
,
'
black
'
);
const
bgColor
=
useColorModeValue
(
'
white
'
,
'
black
'
);
const
scrollDirection
=
useScrollDirection
();
return
(
return
(
<
ScrollDirectionContext
.
Consumer
>
<>
{
(
scrollDirection
)
=>
(
<
Box
bgColor=
{
bgColor
}
display=
{
{
base
:
'
block
'
,
lg
:
'
none
'
}
}
>
<>
<
Flex
<
Box
bgColor=
{
bgColor
}
display=
{
{
base
:
'
block
'
,
lg
:
'
none
'
}
}
>
as=
"header"
<
Flex
position=
"fixed"
as=
"header"
top=
{
0
}
position=
"fixed"
left=
{
0
}
top=
{
0
}
paddingX=
{
4
}
left=
{
0
}
paddingY=
{
2
}
paddingX=
{
4
}
bgColor=
{
bgColor
}
paddingY=
{
2
}
width=
"100%"
bgColor=
{
bgColor
}
alignItems=
"center"
width=
"100%"
justifyContent=
"space-between"
alignItems=
"center"
zIndex=
"sticky2"
justifyContent=
"space-between"
transitionProperty=
"box-shadow"
zIndex=
"sticky2"
transitionDuration=
"slow"
transitionProperty=
"box-shadow"
boxShadow=
{
!
hideOnScrollDown
&&
scrollDirection
===
'
down
'
?
'
md
'
:
'
none
'
}
transitionDuration=
"slow"
>
boxShadow=
{
!
hideOnScrollDown
&&
scrollDirection
===
'
down
'
?
'
md
'
:
'
none
'
}
<
Burger
/>
>
<
NetworkLogo
/>
<
Burger
/>
<
ProfileMenuMobile
/>
<
NetworkLogo
/>
</
Flex
>
<
ProfileMenuMobile
/>
{
!
isHomePage
&&
<
SearchBar
withShadow=
{
!
hideOnScrollDown
}
/>
}
</
Flex
>
</
Box
>
{
!
isHomePage
&&
<
SearchBar
withShadow=
{
!
hideOnScrollDown
}
/>
}
{
!
isHomePage
&&
(
<
HStack
as=
"header"
width=
"100%"
alignItems=
"center"
justifyContent=
"center"
gap=
{
12
}
display=
{
{
base
:
'
none
'
,
lg
:
'
flex
'
}
}
paddingX=
{
12
}
paddingTop=
{
9
}
paddingBottom=
"52px"
>
<
Box
width=
"100%"
>
<
SearchBar
/>
</
Box
>
</
Box
>
{
!
isHomePage
&&
(
<
ColorModeToggler
/>
<
HStack
<
ProfileMenuDesktop
/>
as=
"header"
</
HStack
>
width=
"100%"
alignItems=
"center"
justifyContent=
"center"
gap=
{
12
}
display=
{
{
base
:
'
none
'
,
lg
:
'
flex
'
}
}
paddingX=
{
12
}
paddingTop=
{
9
}
paddingBottom=
"52px"
>
<
Box
width=
"100%"
>
<
SearchBar
/>
</
Box
>
<
ColorModeToggler
/>
<
ProfileMenuDesktop
/>
</
HStack
>
)
}
</>
)
}
)
}
</
ScrollDirectionContext
.
Consumer
>
</>
);
);
};
};
...
...
ui/snippets/searchBar/SearchBarMobile.tsx
View file @
0f710c19
...
@@ -4,7 +4,7 @@ import React from 'react';
...
@@ -4,7 +4,7 @@ import React from 'react';
import
type
{
ChangeEvent
,
FormEvent
}
from
'
react
'
;
import
type
{
ChangeEvent
,
FormEvent
}
from
'
react
'
;
import
searchIcon
from
'
icons/search.svg
'
;
import
searchIcon
from
'
icons/search.svg
'
;
import
ScrollDirectionContext
from
'
ui/ScrollDirectionContext
'
;
import
{
useScrollDirection
}
from
'
lib/contexts/scrollDirection
'
;
const
TOP
=
55
;
const
TOP
=
55
;
...
@@ -17,6 +17,7 @@ interface Props {
...
@@ -17,6 +17,7 @@ interface Props {
const
SearchBarMobile
=
({
onChange
,
onSubmit
,
withShadow
}:
Props
)
=>
{
const
SearchBarMobile
=
({
onChange
,
onSubmit
,
withShadow
}:
Props
)
=>
{
const
[
isSticky
,
setIsSticky
]
=
React
.
useState
(
false
);
const
[
isSticky
,
setIsSticky
]
=
React
.
useState
(
false
);
const
scrollDirection
=
useScrollDirection
();
const
handleScroll
=
React
.
useCallback
(()
=>
{
const
handleScroll
=
React
.
useCallback
(()
=>
{
if
(
window
.
pageYOffset
!==
0
)
{
if
(
window
.
pageYOffset
!==
0
)
{
...
@@ -43,41 +44,37 @@ const SearchBarMobile = ({ onChange, onSubmit, withShadow }: Props) => {
...
@@ -43,41 +44,37 @@ const SearchBarMobile = ({ onChange, onSubmit, withShadow }: Props) => {
const
bgColor
=
useColorModeValue
(
'
white
'
,
'
black
'
);
const
bgColor
=
useColorModeValue
(
'
white
'
,
'
black
'
);
return
(
return
(
<
ScrollDirectionContext
.
Consumer
>
<
chakra
.
form
{
(
scrollDirection
)
=>
(
noValidate
<
chakra
.
form
onSubmit=
{
onSubmit
}
noValidate
paddingX=
{
4
}
onSubmit=
{
onSubmit
}
paddingTop=
{
1
}
paddingX=
{
4
}
paddingBottom=
{
2
}
paddingTop=
{
1
}
position=
"fixed"
paddingBottom=
{
2
}
top=
{
`${ TOP }px`
}
position=
"fixed"
left=
"0"
top=
{
`${ TOP }px`
}
zIndex=
"sticky1"
left=
"0"
bgColor=
{
bgColor
}
zIndex=
"sticky1"
transform=
{
scrollDirection
!==
'
down
'
?
'
translateY(0)
'
:
'
translateY(-100%)
'
}
bgColor=
{
bgColor
}
transitionProperty=
"transform,box-shadow"
transform=
{
scrollDirection
!==
'
down
'
?
'
translateY(0)
'
:
'
translateY(-100%)
'
}
transitionDuration=
"slow"
transitionProperty=
"transform,box-shadow"
display=
{
{
base
:
'
block
'
,
lg
:
'
none
'
}
}
transitionDuration=
"slow"
w=
"100%"
display=
{
{
base
:
'
block
'
,
lg
:
'
none
'
}
}
boxShadow=
{
withShadow
&&
scrollDirection
!==
'
down
'
&&
isSticky
?
'
md
'
:
'
none
'
}
w=
"100%"
>
boxShadow=
{
withShadow
&&
scrollDirection
!==
'
down
'
&&
isSticky
?
'
md
'
:
'
none
'
}
<
InputGroup
size=
"sm"
>
>
<
InputLeftElement
>
<
InputGroup
size=
"sm"
>
<
Icon
as=
{
searchIcon
}
boxSize=
{
4
}
color=
{
searchIconColor
}
/>
<
InputLeftElement
>
</
InputLeftElement
>
<
Icon
as=
{
searchIcon
}
boxSize=
{
4
}
color=
{
searchIconColor
}
/>
<
Input
</
InputLeftElement
>
paddingInlineStart=
"38px"
<
Input
placeholder=
"Search by addresses / ... "
paddingInlineStart=
"38px"
ml=
"1px"
placeholder=
"Search by addresses / ... "
onChange=
{
onChange
}
ml=
"1px"
borderColor=
{
inputBorderColor
}
onChange=
{
onChange
}
/>
borderColor=
{
inputBorderColor
}
</
InputGroup
>
/>
</
chakra
.
form
>
</
InputGroup
>
</
chakra
.
form
>
)
}
</
ScrollDirectionContext
.
Consumer
>
);
);
};
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment