refactor reload badge showing logic
This commit is contained in:
parent
05bd08e86d
commit
f55ba7e6f2
23
package-lock.json
generated
23
package-lock.json
generated
@ -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",
|
||||||
|
@ -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",
|
||||||
|
23
src/App.tsx
23
src/App.tsx
@ -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 />
|
||||||
|
@ -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} />}</>
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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>
|
||||||
|
@ -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',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user