refactor reload badge showing logic

This commit is contained in:
Bekbolsun 2024-02-20 10:20:37 +06:00
parent 05bd08e86d
commit f55ba7e6f2
7 changed files with 70 additions and 26 deletions

23
package-lock.json generated
View File

@ -41,6 +41,7 @@
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"typescript": "^5.3.2", "typescript": "^5.3.2",
"use-debounce": "^10.0.0", "use-debounce": "^10.0.0",
"usehooks-ts": "^2.14.0",
"web-vitals": "^2.1.4", "web-vitals": "^2.1.4",
"workbox-background-sync": "^6.6.0", "workbox-background-sync": "^6.6.0",
"workbox-broadcast-update": "^6.6.0", "workbox-broadcast-update": "^6.6.0",
@ -17214,6 +17215,20 @@
"react": "^16.8.0 || ^17.0.0 || ^18.0.0" "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
} }
}, },
"node_modules/usehooks-ts": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/usehooks-ts/-/usehooks-ts-2.14.0.tgz",
"integrity": "sha512-jnhrjTRJoJS7cFxz63tRYc5mzTKf/h+Ii8P0PDHymT9qDe4ZA2/gzDRmDR4WGausg5X8wMIdghwi3BBCN9JKow==",
"dependencies": {
"lodash.debounce": "^4.0.8"
},
"engines": {
"node": ">=16.15.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17 || ^18"
}
},
"node_modules/utf-8-validate": { "node_modules/utf-8-validate": {
"version": "5.0.10", "version": "5.0.10",
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz",
@ -30591,6 +30606,14 @@
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
"requires": {} "requires": {}
}, },
"usehooks-ts": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/usehooks-ts/-/usehooks-ts-2.14.0.tgz",
"integrity": "sha512-jnhrjTRJoJS7cFxz63tRYc5mzTKf/h+Ii8P0PDHymT9qDe4ZA2/gzDRmDR4WGausg5X8wMIdghwi3BBCN9JKow==",
"requires": {
"lodash.debounce": "^4.0.8"
}
},
"utf-8-validate": { "utf-8-validate": {
"version": "5.0.10", "version": "5.0.10",
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz",

View File

@ -36,6 +36,7 @@
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"typescript": "^5.3.2", "typescript": "^5.3.2",
"use-debounce": "^10.0.0", "use-debounce": "^10.0.0",
"usehooks-ts": "^2.14.0",
"web-vitals": "^2.1.4", "web-vitals": "^2.1.4",
"workbox-background-sync": "^6.6.0", "workbox-background-sync": "^6.6.0",
"workbox-broadcast-update": "^6.6.0", "workbox-broadcast-update": "^6.6.0",

View File

@ -9,12 +9,15 @@ import { ModalInitial } from './components/Modal/ModalInitial/ModalInitial'
import { ModalImportKeys } from './components/Modal/ModalImportKeys/ModalImportKeys' import { ModalImportKeys } from './components/Modal/ModalImportKeys/ModalImportKeys'
import { ModalSignUp } from './components/Modal/ModalSignUp/ModalSignUp' import { ModalSignUp } from './components/Modal/ModalSignUp/ModalSignUp'
import { ModalLogin } from './components/Modal/ModalLogin/ModalLogin' import { ModalLogin } from './components/Modal/ModalLogin/ModalLogin'
import { useSearchParams } from 'react-router-dom' import { useSessionStorage } from 'usehooks-ts'
import { RELOAD_STORAGE_KEY } from './utils/consts'
function App() { function App() {
const [render, setRender] = useState(0) const [render, setRender] = useState(0)
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const [searchParams, setSearchParams] = useSearchParams()
// eslint-disable-next-line
const [_, setNeedReload] = useSessionStorage(RELOAD_STORAGE_KEY, false)
const [isConnected, setIsConnected] = useState(false) const [isConnected, setIsConnected] = useState(false)
@ -80,14 +83,24 @@ function App() {
// subscribe to service worker updates // subscribe to service worker updates
swicOnReload(() => { swicOnReload(() => {
console.log('reload') console.log('reload')
searchParams.set('reload', 'true') setNeedReload(true)
setSearchParams(searchParams)
}) })
useEffect(() => {
const handleBeforeUnload = () => {
setNeedReload(false)
}
window.addEventListener('beforeunload', handleBeforeUnload)
return () => {
window.removeEventListener('beforeunload', handleBeforeUnload)
}
// eslint-disable-next-line
}, [])
return ( return (
<> <>
<AppRoutes /> <AppRoutes />
<ModalInitial /> <ModalInitial />
<ModalImportKeys /> <ModalImportKeys />
<ModalSignUp /> <ModalSignUp />

View File

@ -1,16 +1,14 @@
import { FC } from 'react' import { FC, memo, useCallback } from 'react'
import { Collapse, Stack, Typography } from '@mui/material' import { Collapse, Stack, Typography } from '@mui/material'
import { useSearchParams } from 'react-router-dom'
import { StyledAlert, StyledReloadButton } from './styled' import { StyledAlert, StyledReloadButton } from './styled'
import { useSessionStorage } from 'usehooks-ts'
import { RELOAD_STORAGE_KEY } from '@/utils/consts'
const ReloadBadgeContent: FC = () => { type ReloadBadgeContentProps = {
const [searchParams, setSearchParams] = useSearchParams() onReload: () => void
}
const handleReload = () => { const ReloadBadgeContent: FC<ReloadBadgeContentProps> = memo(({ onReload }) => {
searchParams.delete('reload')
setSearchParams(searchParams)
window.location.reload()
}
return ( return (
<Collapse in> <Collapse in>
<StyledAlert> <StyledAlert>
@ -18,16 +16,20 @@ const ReloadBadgeContent: FC = () => {
<Typography flex={1} className="title"> <Typography flex={1} className="title">
New version available! New version available!
</Typography> </Typography>
<StyledReloadButton onClick={handleReload}>Reload</StyledReloadButton> <StyledReloadButton onClick={onReload}>Reload</StyledReloadButton>
</Stack> </Stack>
</StyledAlert> </StyledAlert>
</Collapse> </Collapse>
) )
} })
export const ReloadBadge = () => { export const ReloadBadge = () => {
const [searchParams] = useSearchParams() const [needReload, setNeedReload] = useSessionStorage(RELOAD_STORAGE_KEY, false)
const open = searchParams.get('reload') === 'true'
return <>{open && <ReloadBadgeContent />}</> const handleReload = useCallback(() => {
setNeedReload(false)
window.location.reload()
}, [setNeedReload])
return <>{needReload && <ReloadBadgeContent onReload={handleReload} />}</>
} }

View File

@ -1,20 +1,21 @@
import { Avatar, Stack, Toolbar, Typography, Divider, DividerProps, styled } from '@mui/material' import { Avatar, Stack, Toolbar, Typography, Divider, DividerProps, styled } from '@mui/material'
import { StyledAppBar, StyledAppLogo, StyledAppName, StyledProfileContainer, StyledThemeButton } from './styled' import { StyledAppBar, StyledAppLogo, StyledAppName, StyledProfileContainer, StyledThemeButton } from './styled'
import { Menu } from './components/Menu' import { Menu } from './components/Menu'
import { useNavigate, useParams, useSearchParams } from 'react-router-dom' import { useNavigate, useParams } from 'react-router-dom'
import { ProfileMenu } from './components/ProfileMenu' import { ProfileMenu } from './components/ProfileMenu'
import { useProfile } from '@/hooks/useProfile' import { useProfile } from '@/hooks/useProfile'
import DarkModeIcon from '@mui/icons-material/DarkMode' import DarkModeIcon from '@mui/icons-material/DarkMode'
import LightModeIcon from '@mui/icons-material/LightMode' import LightModeIcon from '@mui/icons-material/LightMode'
import { useAppDispatch, useAppSelector } from '@/store/hooks/redux' import { useAppDispatch, useAppSelector } from '@/store/hooks/redux'
import { setThemeMode } from '@/store/reducers/ui.slice' import { setThemeMode } from '@/store/reducers/ui.slice'
import { useSessionStorage } from 'usehooks-ts'
import { RELOAD_STORAGE_KEY } from '@/utils/consts'
export const Header = () => { export const Header = () => {
const themeMode = useAppSelector((state) => state.ui.themeMode) const themeMode = useAppSelector((state) => state.ui.themeMode)
const navigate = useNavigate() const navigate = useNavigate()
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const [searchParams] = useSearchParams() const [needReload] = useSessionStorage(RELOAD_STORAGE_KEY, false)
const needReload = searchParams.get('reload') === 'true'
const { npub = '' } = useParams<{ npub: string }>() const { npub = '' } = useParams<{ npub: string }>()
const { userName, userAvatar, avatarTitle } = useProfile(npub) const { userName, userAvatar, avatarTitle } = useProfile(npub)

View File

@ -1,15 +1,17 @@
import { FC } from 'react' import { FC } from 'react'
import { Outlet, useSearchParams } from 'react-router-dom' import { Outlet } from 'react-router-dom'
import { Header } from './Header/Header' import { Header } from './Header/Header'
import { Container, ContainerProps, styled } from '@mui/material' import { Container, ContainerProps, styled } from '@mui/material'
import { ReloadBadge } from '@/components/ReloadBadge/ReloadBadge' import { ReloadBadge } from '@/components/ReloadBadge/ReloadBadge'
import { useSessionStorage } from 'usehooks-ts'
import { RELOAD_STORAGE_KEY } from '@/utils/consts'
export const Layout: FC = () => { export const Layout: FC = () => {
const [searchParams] = useSearchParams() const [needReload] = useSessionStorage(RELOAD_STORAGE_KEY, false)
const needReload = searchParams.get('reload') === 'true' const containerClassName = needReload ? 'reload' : ''
return ( return (
<StyledContainer maxWidth="md" className={needReload ? 'reload' : ''}> <StyledContainer maxWidth="md" className={containerClassName}>
<ReloadBadge /> <ReloadBadge />
<Header /> <Header />
<main> <main>

View File

@ -9,6 +9,8 @@ export const MAX_POW = 19
export const KIND_RPC = 24133 export const KIND_RPC = 24133
export const RELOAD_STORAGE_KEY = 'reload'
export enum ACTION_TYPE { export enum ACTION_TYPE {
BASIC = 'basic', BASIC = 'basic',
ADVANCED = 'advanced', ADVANCED = 'advanced',