Mp 2436 settings (#131)

* MP-2436: added Settings menu

* tidy: refactor

* fix: react to server side rendering

* fix: fixed the background animations

* fix: enableAnimations for bg classes

* small merge fix

* fix: fixed the animation less circular progress

---------

Co-authored-by: Linkie Link <linkielink.dev@gmail.com>
This commit is contained in:
Bob van der Helm 2023-03-22 15:32:52 +01:00 committed by GitHub
parent 740e982956
commit c3b1550452
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 107 additions and 13 deletions

View File

@ -63,14 +63,15 @@ export const AccountNavigation = () => {
className='flex flex-1 flex-nowrap'
leftIcon={<Account />}
onClick={() => setShowMenu(!showMenu)}
hasFocus={showMenu}
hasSubmenu
>
<span>{accountSelected ? `Account ${selectedAccount}` : 'Select Account'}</span>
</Button>
<Overlay className='l-0 mt-2 w-[274px]' show={showMenu} setShow={setShowMenu}>
<Overlay className='left-0 mt-2 w-[274px]' show={showMenu} setShow={setShowMenu}>
{accountSelected && (
<div className='flex w-full flex-wrap'>
<Text size='sm' uppercase={true} className='w-full justify-center px-4 pt-4'>
<Text size='sm' uppercase={true} className='w-full px-4 pt-4'>
Manage Account {selectedAccount}
</Text>
<div className='flex w-full justify-between p-4'>
@ -133,7 +134,7 @@ export const AccountNavigation = () => {
)}
{creditAccounts.length > 1 && (
<div className='flex w-full flex-wrap border-t border-t-white/10 p-4'>
<Text size='sm' uppercase={true} className='w-full justify-center pb-2'>
<Text size='sm' uppercase={true} className='w-full pb-2'>
Select Account
</Text>
{creditAccounts.map((account) =>

View File

@ -1,6 +1,12 @@
'use client'
import classNames from 'classnames'
import useStore from 'store'
export default function Background() {
const enableAnimations = useStore((s) => s.enableAnimations)
return (
<div className='background pointer-events-none fixed inset-0 h-full w-full overflow-hidden bg-body'>
<div
@ -12,7 +18,7 @@ export default function Background() {
'top-[-10vw] left-[-10vw]',
'bg-orb-primary blur-orb-primary ',
'translate-x-0 translate-y-0 rounded-full opacity-20',
'animate-[float_120s_ease_in_out_infinite_2s]',
enableAnimations && 'animate-[float_120s_ease-in-out_infinite_2s]',
)}
/>
<div
@ -24,7 +30,7 @@ export default function Background() {
'bottom-[-10vw] right-[-8vw]',
'bg-orb-secondary blur-orb-secondary',
'translate-x-0 translate-y-0 rounded-full opacity-30',
'animate-[float_150s_bounce_out_infinite_1s]',
enableAnimations && 'animate-[float_150s_ease-in-out_infinite_1s]',
)}
/>
<div
@ -36,7 +42,7 @@ export default function Background() {
'top-[-10vw] right-[-4vw]',
'bg-orb-tertiary blur-orb-tertiary ',
'translate-x-0 translate-y-0 rounded-full opacity-20',
'animate-[float_180s_ease_in_infinite]',
enableAnimations && 'animate-[float_180s_ease-in_infinite]',
)}
/>
</div>

View File

@ -20,7 +20,10 @@ export const CircularProgress = ({ color = '#FFFFFF', size = 20, className }: Pr
if (!enableAnimations)
return (
<div className={loaderClasses} style={{ width: `${size}px`, height: `${size}px` }}>
<div
className={classNames('flex items-center', loaderClasses)}
style={{ width: `${size}px`, height: `${size}px` }}
>
<Text className='text-center' uppercase size='lg'>
...
</Text>

View File

@ -0,0 +1,6 @@
<svg viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'>
<path
d='M9.99996 13.5C9.0717 13.5 8.18147 13.1313 7.52509 12.4749C6.86871 11.8185 6.49996 10.9283 6.49996 10C6.49996 9.07174 6.86871 8.18151 7.52509 7.52513C8.18147 6.86875 9.0717 6.5 9.99996 6.5C10.9282 6.5 11.8185 6.86875 12.4748 7.52513C13.1312 8.18151 13.5 9.07174 13.5 10C13.5 10.9283 13.1312 11.8185 12.4748 12.4749C11.8185 13.1313 10.9282 13.5 9.99996 13.5M17.43 10.97C17.47 10.65 17.5 10.33 17.5 10C17.5 9.67 17.47 9.34 17.43 9L19.54 7.37C19.73 7.22 19.78 6.95 19.66 6.73L17.66 3.27C17.54 3.05 17.27 2.96 17.05 3.05L14.56 4.05C14.04 3.66 13.5 3.32 12.87 3.07L12.5 0.420002C12.4796 0.302219 12.4183 0.195429 12.3268 0.118553C12.2353 0.0416778 12.1195 -0.000319774 12 1.83347e-06H7.99996C7.74996 1.83347e-06 7.53996 0.180002 7.49996 0.420002L7.12996 3.07C6.49996 3.32 5.95996 3.66 5.43996 4.05L2.94996 3.05C2.72996 2.96 2.45996 3.05 2.33996 3.27L0.339961 6.73C0.209961 6.95 0.269962 7.22 0.459962 7.37L2.56996 9C2.52996 9.34 2.49996 9.67 2.49996 10C2.49996 10.33 2.52996 10.65 2.56996 10.97L0.459962 12.63C0.269962 12.78 0.209961 13.05 0.339961 13.27L2.33996 16.73C2.45996 16.95 2.72996 17.03 2.94996 16.95L5.43996 15.94C5.95996 16.34 6.49996 16.68 7.12996 16.93L7.49996 19.58C7.53996 19.82 7.74996 20 7.99996 20H12C12.25 20 12.46 19.82 12.5 19.58L12.87 16.93C13.5 16.67 14.04 16.34 14.56 15.94L17.05 16.95C17.27 17.03 17.54 16.95 17.66 16.73L19.66 13.27C19.78 13.05 19.73 12.78 19.54 12.63L17.43 10.97V10.97Z'
fill='currentColor'
/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -25,6 +25,7 @@ export { default as Edit } from 'components/Icons/Edit.svg'
export { default as Ellipsis } from 'components/Icons/Ellipsis.svg'
export { default as ExternalLink } from 'components/Icons/ExternalLink.svg'
export { default as Failed } from 'components/Icons/Failed.svg'
export { default as Gear } from 'components/Icons/Gear.svg'
export { default as Github } from 'components/Icons/Github.svg'
export { default as Heart } from 'components/Icons/Heart.svg'
export { default as Info } from 'components/Icons/Info.svg'

View File

@ -1,13 +1,15 @@
'use client'
import classNames from 'classnames'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import classNames from 'classnames'
import { AccountNavigation } from 'components/Account/AccountNavigation'
import { Logo } from 'components/Icons'
import { NavLink } from 'components/Navigation/NavLink'
import Settings from 'components/Settings'
import Wallet from 'components/Wallet/Wallet'
import { useAnimations } from 'hooks/data/useAnimations'
import { getRoute } from 'utils/route'
export const menuTree: { href: RouteSegment; label: string }[] = [
@ -47,6 +49,7 @@ export default function DesktopNavigation() {
<div className='flex gap-4'>
<AccountNavigation />
<Wallet />
<Settings />
</div>
</div>
</header>

View File

@ -0,0 +1,61 @@
'use client'
import { useState } from 'react'
import { Button } from 'components/Button'
import { Gear } from 'components/Icons'
import { Overlay } from 'components/Overlay/Overlay'
import Switch from 'components/Switch'
import { Text } from 'components/Text'
import { Tooltip } from 'components/Tooltip'
import { ENABLE_ANIMATIONS_KEY } from 'constants/localStore'
import { useAnimations } from 'hooks/data/useAnimations'
import useStore from 'store'
export default function Settings() {
useAnimations()
const [showMenu, setShowMenu] = useState(false)
const enableAnimations = useStore((s) => s.enableAnimations)
function handleReduceMotion(val: boolean) {
useStore.setState({ enableAnimations: !val })
if (typeof window !== 'undefined')
window.localStorage.setItem(ENABLE_ANIMATIONS_KEY, val ? 'false' : 'true')
}
return (
<div className='relative'>
<Button
variant='solid'
color='tertiary'
icon={<Gear />}
onClick={() => setShowMenu(!showMenu)}
hasFocus={showMenu}
/>
<Overlay className='right-0 mt-2 w-[240px]' show={showMenu} setShow={setShowMenu}>
<div className='flex w-full flex-wrap p-4'>
<Text size='sm' uppercase={true} className='w-full pb-4'>
Settings
</Text>
<div className='flex w-full'>
<div className='flex flex-1'>
<Text size='sm' className='mr-2'>
Reduce Motion
</Text>
<Tooltip
content={
<Text size='sm'>
Turns off all animations inside the dApp. Turning animations off can increase
the overall performance on lower-end hardware.
</Text>
}
/>
</div>
<Switch name='reduceMotion' checked={!enableAnimations} onChange={handleReduceMotion} />
</div>
</div>
</Overlay>
</div>
)
}

View File

@ -89,6 +89,7 @@ export default function ConnectedButton() {
onClick={() => {
setShowDetails(!showDetails)
}}
hasFocus={showDetails}
>
<span>{truncate(address, [2, 4])}</span>
<div

View File

@ -0,0 +1,2 @@
export const DISPLAY_CURRENCY_KEY = 'displayCurrency'
export const ENABLE_ANIMATIONS_KEY = 'enableAnimations'

View File

@ -1,23 +1,33 @@
import { useEffect } from 'react'
import { useCallback, useEffect } from 'react'
import { ENABLE_ANIMATIONS_KEY } from 'constants/localStore'
import useStore from 'store'
export const useAnimations = () => {
const enableAnimations = useStore((s) => s.enableAnimations)
const enableAnimationsLocalStorage =
typeof window !== 'undefined' ? window.localStorage.getItem(ENABLE_ANIMATIONS_KEY) : false
const queryChangeHandler = (event: MediaQueryListEvent) => {
useStore.setState({ enableAnimations: !event?.matches ?? true })
}
const queryChangeHandler = useCallback(
(event: MediaQueryListEvent) => {
if (enableAnimationsLocalStorage) return
useStore.setState({ enableAnimations: !event?.matches ?? true })
},
[enableAnimationsLocalStorage],
)
useEffect(() => {
const mediaQuery: MediaQueryList = window.matchMedia('(prefers-reduced-motion: reduce)')
const storeSetting = enableAnimationsLocalStorage === 'true'
useStore.setState({ enableAnimations: storeSetting })
if (mediaQuery) {
if (enableAnimationsLocalStorage) return
useStore.setState({ enableAnimations: !mediaQuery.matches })
mediaQuery.addEventListener('change', queryChangeHandler)
return () => mediaQuery.removeEventListener('change', queryChangeHandler)
}
}, [])
}, [enableAnimations, enableAnimationsLocalStorage, queryChangeHandler])
return enableAnimations
}