diff --git a/src/components/LongString.tsx b/src/components/LongString.tsx new file mode 100644 index 00000000..922e5756 --- /dev/null +++ b/src/components/LongString.tsx @@ -0,0 +1,16 @@ +import { Typography } from '@mui/material' +import React from 'react' +import { displayFirstPartLongString, displaySecondPartLongString } from '../utils/display-utils' +const LongString = ({ value }) => { + const content = + value && value.length < 12 ? ( + {value} + ) : ( + + {displayFirstPartLongString(value)}… + {displaySecondPartLongString(value)} + + ) + return <>{content} +} +export default LongString diff --git a/src/components/Navbar/LoginButton.tsx b/src/components/Navbar/Account.tsx similarity index 62% rename from src/components/Navbar/LoginButton.tsx rename to src/components/Navbar/Account.tsx index 67b91546..49482e22 100644 --- a/src/components/Navbar/LoginButton.tsx +++ b/src/components/Navbar/Account.tsx @@ -1,23 +1,29 @@ -import { mdiCogOutline, mdiLogout } from '@mdi/js' +import { mdiCog, mdiLogout } from '@mdi/js' import Icon from '@mdi/react' -import { Chip, IconButton, MenuItem, MenuList, Select, Typography, useTheme } from '@mui/material' -import { default as React } from 'react' +import { Chip, MenuItem, MenuList, Select, Typography, useTheme } from '@mui/material' +import React, { useEffect } from 'react' import { useNavigate } from 'react-router-dom' import store from 'wallet/store' +import { + getNameOfMultiSigWallet, + getPchainAddress, + isMultiSigWallet, +} from '../../helpers/walletStore' import { useAppDispatch, useAppSelector } from '../../hooks/reduxHooks' import { changeActiveApp, getAccount, updateAccount } from '../../redux/slices/app-config' import { updateAuthStatus } from '../../redux/slices/utils' import MHidden from '../@material-extend/MHidden' import { LoadAccountMenu } from '../LoadAccountMenu' import AliasPicker from './AliasPicker' +import ThemeSwitcher from './ThemeSwitcher' interface LoginIconProps { handleCloseSidebar: () => void } -export default function LoginButton({ handleCloseSidebar }: LoginIconProps) { - const cAddress = useAppSelector(state => state.appConfig.walletStore?.activeWallet?.ethAddress) +export default function Account({ handleCloseSidebar }: LoginIconProps) { const auth = useAppSelector(state => state.appConfig.isAuth) + const [_, setWalletName] = React.useState('') const dispatch = useAppDispatch() const navigate = useNavigate() const account = useAppSelector(getAccount) @@ -35,6 +41,11 @@ export default function LoginButton({ handleCloseSidebar }: LoginIconProps) { navigate('/settings') handleCloseSidebar() } + useEffect(() => { + if (isMultiSigWallet()) { + setWalletName(getNameOfMultiSigWallet() || getPchainAddress()) + } else setWalletName(getPchainAddress()) + }, [auth]) const handleKeyDown = e => { e.stopPropagation() @@ -44,17 +55,20 @@ export default function LoginButton({ handleCloseSidebar }: LoginIconProps) { <> - - - - + + Settings - {auth && ( - - - - )} + {auth && } @@ -67,27 +81,44 @@ export default function LoginButton({ handleCloseSidebar }: LoginIconProps) { position: 'absolute', fontSize: '12px', height: '16px', - top: 0, - right: { xs: '0.3rem', sm: 0 }, + top: '5px', + width: '50px', + left: 'calc(100% - 55px)', }} label="beta" /> - - - - - logout + + + Logout <> - {cAddress && ( + {auth && ( )} diff --git a/src/components/Navbar/AliasPicker.tsx b/src/components/Navbar/AliasPicker.tsx index 9e74e5d0..52a4aee8 100644 --- a/src/components/Navbar/AliasPicker.tsx +++ b/src/components/Navbar/AliasPicker.tsx @@ -1,13 +1,20 @@ -import { mdiClose } from '@mdi/js' +import { mdiClose, mdiOpenInNew } from '@mdi/js' import Icon from '@mdi/react' -import { Box, DialogContent, DialogTitle, Divider, Typography, IconButton } from '@mui/material' +import { + Box, + DialogContent, + DialogTitle, + Divider, + IconButton, + MenuItem, + Typography, +} from '@mui/material' import React, { useEffect, useState } from 'react' import store from 'wallet/store' import { getMultisigAliases } from '../../api' import { useAppSelector } from '../../hooks/reduxHooks' import { getShowButton } from '../../redux/slices/app-config' import DialogAnimate from '../Animate/DialogAnimate' -import MainButton from '../MainButton' import LoadMyKeysComponent from './LoadMyKeysComponent' import LoadSaveKeysComponent from './LoadSaveKeysComponent' @@ -31,14 +38,17 @@ const AliasPicker = () => { }, [showButtonState]) if (!load) return <> return ( - <> - + + Switch Wallet - + @@ -74,7 +84,7 @@ const AliasPicker = () => { - + ) } diff --git a/src/components/Navbar/LoadMyKeysComponent.tsx b/src/components/Navbar/LoadMyKeysComponent.tsx index f5b01f9f..b6828948 100644 --- a/src/components/Navbar/LoadMyKeysComponent.tsx +++ b/src/components/Navbar/LoadMyKeysComponent.tsx @@ -1,10 +1,10 @@ -import React, { useRef } from 'react' +import { Box } from '@mui/material' +import { styled } from '@mui/system' +import React, { useEffect, useRef } from 'react' import { mountKyesComponent } from 'wallet/mountKyesComponent' import { useAppDispatch } from '../../hooks/reduxHooks' -import { updateNotificationStatus } from '../../redux/slices/app-config' import { useEffectOnce } from '../../hooks/useEffectOnce' -import { styled } from '@mui/system' -import { Box } from '@mui/material' +import { updateNotificationStatus, updatePchainAddress } from '../../redux/slices/app-config' const StyledBox = styled(Box)(({ theme }) => ({ display: 'flex', @@ -40,13 +40,16 @@ const StyledBox = styled(Box)(({ theme }) => ({ const LoadMyKeysComponent = () => { const ref = useRef(null) const dispatch = useAppDispatch() - + const [walletSwitched, setWalletSwitched] = React.useState('') const dispatchNotification = ({ message, type }) => dispatch(updateNotificationStatus({ message, severity: type })) useEffectOnce(() => { - mountKyesComponent(ref.current, { dispatchNotification }) + mountKyesComponent(ref.current, { dispatchNotification, setWalletSwitched }) }) // eslint-disable-line react-hooks/exhaustive-deps + useEffect(() => { + dispatch(updatePchainAddress(walletSwitched)) + }, [walletSwitched]) return (
diff --git a/src/components/Navbar/LoggedInAccount.tsx b/src/components/Navbar/LoggedInAccount.tsx new file mode 100644 index 00000000..6834fac1 --- /dev/null +++ b/src/components/Navbar/LoggedInAccount.tsx @@ -0,0 +1,31 @@ +import { mdiWalletOutline } from '@mdi/js' +import Icon from '@mdi/react' +import React, { useEffect, useState } from 'react' +import { + getNameOfMultiSigWallet, + getPchainAddress, + isMultiSigWallet, +} from '../../helpers/walletStore' +import { useAppSelector } from '../../hooks/reduxHooks' +import { getPChainAddress } from '../../redux/slices/app-config' +import { getActiveNetwork } from '../../redux/slices/network' +import LongString from '../LongString' + +const LoggedInAccount = () => { + const [walletName, setWalletName] = useState('') + const pChainAddress = useAppSelector(getPChainAddress) + const activeNetwork = useAppSelector(getActiveNetwork) + + useEffect(() => { + if (isMultiSigWallet()) { + setWalletName(getNameOfMultiSigWallet() || getPchainAddress()[0]) + } else setWalletName(getPchainAddress()[0]) + }, [pChainAddress, activeNetwork]) + return ( + <> + + + + ) +} +export default LoggedInAccount diff --git a/src/components/Navbar/NetworkSwitcher.tsx b/src/components/Navbar/NetworkSwitcher.tsx index 88cbba07..7acd7a91 100644 --- a/src/components/Navbar/NetworkSwitcher.tsx +++ b/src/components/Navbar/NetworkSwitcher.tsx @@ -1,25 +1,24 @@ -import React from 'react' +import { mdiDeleteOutline, mdiPencilOutline, mdiPlus } from '@mdi/js' import Icon from '@mdi/react' import { + Box, Button, - MenuItem, - Typography, - Select, + Chip, DialogTitle, - useTheme, + MenuItem, MenuList, + Select, Stack, - Box, - Chip, - IconButton, + Typography, + useTheme, } from '@mui/material' -import { mdiDeleteOutline, mdiPencilOutline, mdiPlus } from '@mdi/js' +import React from 'react' +import useNetwork from '../../hooks/useNetwork' import { networkStatusColor, networkStatusName } from '../../utils/networkUtils' -import DialogAnimate from '../Animate/DialogAnimate' import MHidden from '../@material-extend/MHidden' +import DialogAnimate from '../Animate/DialogAnimate' import AddNewNetwork from './AddNewNetwork' import SelectedNetwork from './SelectNetwork' -import useNetwork from '../../hooks/useNetwork' interface NetworkSwitcherProps { handleCloseSidebar?: () => void @@ -122,12 +121,12 @@ export default function NetworkSwitcher({ handleCloseSidebar }: NetworkSwitcherP {!network.readonly && network.url !== activeNetwork.url && ( - + - - + + - + )} @@ -160,9 +159,7 @@ export default function NetworkSwitcher({ handleCloseSidebar }: NetworkSwitcherP }} > Add Custom Network - - - + diff --git a/src/components/Navbar/ThemeSwitcher.tsx b/src/components/Navbar/ThemeSwitcher.tsx index a35929ec..335d52d2 100644 --- a/src/components/Navbar/ThemeSwitcher.tsx +++ b/src/components/Navbar/ThemeSwitcher.tsx @@ -1,20 +1,20 @@ -import React from 'react' -import { useAppDispatch, useAppSelector } from '../../hooks/reduxHooks' -import { toggleTheme } from '../../redux/slices/theme' -import { Button, Typography, useTheme } from '@mui/material' -import { mdiWeatherSunny } from '@mdi/js' +import { mdiWhiteBalanceSunny } from '@mdi/js' import Icon from '@mdi/react' -import useWidth from '../../hooks/useWidth' +import { Button, Typography, useTheme } from '@mui/material' import { useStore } from 'Explorer/useStore' -import { getTheme } from '../../redux/slices/theme' +import React from 'react' import store from 'wallet/store' +import { useAppDispatch, useAppSelector } from '../../hooks/reduxHooks' +import useWidth from '../../hooks/useWidth' +import { getTheme, toggleTheme } from '../../redux/slices/theme' export default function ThemeSwitcher() { - const { isDesktop } = useWidth() + const { isDesktop, isMobile } = useWidth() const dispatch = useAppDispatch() const theme = useTheme() const currentTheme = useAppSelector(getTheme) const { changeTheme } = useStore() + const auth = useAppSelector(state => state.appConfig.isAuth) return ( ) } diff --git a/src/components/Navbar/index.tsx b/src/components/Navbar/index.tsx index da081126..ef2c3f65 100644 --- a/src/components/Navbar/index.tsx +++ b/src/components/Navbar/index.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import { mdiClose, mdiMenu, mdiWalletOutline } from '@mdi/js' import Icon from '@mdi/react' import { AppBar, @@ -10,22 +10,22 @@ import { Typography, useTheme, } from '@mui/material' +import React, { useState } from 'react' import { useIdleTimer } from 'react-idle-timer' -import { mdiClose, mdiMenu, mdiWalletOutline } from '@mdi/js' import { useNavigate } from 'react-router-dom' +import store from 'wallet/store' +import { DRAWER_WIDTH, TIMEOUT_DURATION } from '../../constants/apps-consts' import { useAppDispatch, useAppSelector } from '../../hooks/reduxHooks' +import { updateAccount } from '../../redux/slices/app-config' import { getActiveNetwork } from '../../redux/slices/network' +import { updateAuthStatus } from '../../redux/slices/utils' +import MHidden from '../@material-extend/MHidden' +import MIconButton from '../@material-extend/MIconButton' import PlatformSwitcher from '../PlatformSwitcher' +import Account from './Account' +import LoggedInAccount from './LoggedInAccount' import NetworkSwitcher from './NetworkSwitcher' import ThemeSwitcher from './ThemeSwitcher' -import LoginButton from './LoginButton' -import MHidden from '../@material-extend/MHidden' -import MIconButton from '../@material-extend/MIconButton' -import { updateAccount } from '../../redux/slices/app-config' -import store from 'wallet/store' -import { TIMEOUT_DURATION, DRAWER_WIDTH } from '../../constants/apps-consts' -import AliasPicker from './AliasPicker' -import { updateAuthStatus } from '../../redux/slices/utils' export default function Navbar() { const theme = useTheme() @@ -124,7 +124,7 @@ export default function Navbar() { justifyContent="center" sx={{ padding: theme.spacing(2) }} > - + @@ -139,7 +139,7 @@ export default function Navbar() { )} - {auth && } + {auth && } @@ -148,7 +148,7 @@ export default function Navbar() { {/* Desktop */} <> - + {!auth && } {activeNetwork && } {!auth ? ( ) : ( <> - - + + )} diff --git a/src/helpers/walletStore.ts b/src/helpers/walletStore.ts index e86733ee..4d907963 100644 --- a/src/helpers/walletStore.ts +++ b/src/helpers/walletStore.ts @@ -44,3 +44,19 @@ export async function updateAssets() { await updateUTXOs() await updateKycStatus() } + +export function isMultiSigWallet() { + return store.state.activeWallet.type === 'multisig' +} + +export function getEthAddress() { + return store.state.activeWallet.ethAddress +} + +export function getNameOfMultiSigWallet() { + return store.state.activeWallet?.name +} + +export function getPchainAddress() { + return store.getters['staticAddresses']('P') +} diff --git a/src/redux/slices/app-config.ts b/src/redux/slices/app-config.ts index 9b44cec7..67f89d4c 100644 --- a/src/redux/slices/app-config.ts +++ b/src/redux/slices/app-config.ts @@ -17,9 +17,11 @@ interface InitialStateAppConfigType { walletStore: any account: any showButton: boolean + pChainAddress: string } let initialState: InitialStateAppConfigType = { + pChainAddress: '', apps: APPS_CONSTS, activeApp: 0, status: Status.IDLE, @@ -42,6 +44,9 @@ const appConfigSlice = createSlice({ updateValues(state, { payload }) { state.walletStore = payload }, + updatePchainAddress(state, { payload }) { + state.pChainAddress = payload + }, updateAccount(state, { payload }) { state.account = payload }, @@ -116,6 +121,9 @@ export const getNotificationSeverity = (state: RootState) => state.appConfig.not // get selectedAlias export const getShowButton = (state: RootState) => state.appConfig.showButton +// get PChainAddress +export const getPChainAddress = (state: RootState) => state.appConfig.pChainAddress + export const { changeActiveApp, updateValues, @@ -123,5 +131,6 @@ export const { updateAccount, updateNotificationStatus, updateShowButton, + updatePchainAddress, } = appConfigSlice.actions export default appConfigSlice.reducer diff --git a/src/utils/display-utils.ts b/src/utils/display-utils.ts index cbb8498f..4369cfc2 100644 --- a/src/utils/display-utils.ts +++ b/src/utils/display-utils.ts @@ -1,60 +1,60 @@ -import { DateTime, Duration } from 'luxon' -import { Timeframe } from 'types' +// import { DateTime, Duration } from 'luxon' +// import { Timeframe } from 'types' export interface Fund { address: string value?: number } -export function getStartDate(endDate: DateTime, timeframe: string): DateTime { - switch (timeframe) { - case Timeframe.DAYS_7: - return endDate.minus({ weeks: 1 }) - case Timeframe.HOURS_24: - return endDate.minus({ days: 1 }) - case Timeframe.MONTHS_1: - return endDate.minus({ months: 1 }) - } - return endDate.minus({ weeks: 1 }) -} -// Todo: Update the getRelativeTime function -export function getRelativeTime(timestamp: Date | number | string): string { - const time = getTime(timestamp) - if (!Number.isInteger(time)) { - return 'Unknown' - } - const duration = Duration.fromMillis(new Date().getTime() - time, { - locale: 'en-US', - }).shiftTo('seconds') - if (duration.seconds < 1) return '< 1 sec' - else if (duration.seconds >= 1 && duration.seconds < 2) { - return '1 sec' - } else if (duration.seconds < 60) { - return duration.seconds.toFixed(0) + ' secs' - } else if (duration.seconds >= 60 && duration.seconds < 120) { - return '1 min' - } else if (duration.seconds < 3600) { - return duration.shiftTo('minutes').minutes.toFixed(0) + ' mins' - } else if (duration.seconds >= 3600 && duration.seconds < 7200) { - return '1 hr' - } else if (duration.seconds < 86400) { - return duration.shiftTo('hours').hours.toFixed(0) + ' hrs' - } else if (duration.seconds >= 86400 && duration.seconds < 172800) { - return '1 day' - } else { - return duration.shiftTo('days').days.toFixed(0) + ' days' - } -} +// export function getStartDate(endDate: DateTime, timeframe: string): DateTime { +// switch (timeframe) { +// case Timeframe.DAYS_7: +// return endDate.minus({ weeks: 1 }) +// case Timeframe.HOURS_24: +// return endDate.minus({ days: 1 }) +// case Timeframe.MONTHS_1: +// return endDate.minus({ months: 1 }) +// } +// return endDate.minus({ weeks: 1 }) +// } +// // Todo: Update the getRelativeTime function +// export function getRelativeTime(timestamp: Date | number | string): string { +// const time = getTime(timestamp) +// if (!Number.isInteger(time)) { +// return 'Unknown' +// } +// const duration = Duration.fromMillis(new Date().getTime() - time, { +// locale: 'en-US', +// }).shiftTo('seconds') +// if (duration.seconds < 1) return '< 1 sec' +// else if (duration.seconds >= 1 && duration.seconds < 2) { +// return '1 sec' +// } else if (duration.seconds < 60) { +// return duration.seconds.toFixed(0) + ' secs' +// } else if (duration.seconds >= 60 && duration.seconds < 120) { +// return '1 min' +// } else if (duration.seconds < 3600) { +// return duration.shiftTo('minutes').minutes.toFixed(0) + ' mins' +// } else if (duration.seconds >= 3600 && duration.seconds < 7200) { +// return '1 hr' +// } else if (duration.seconds < 86400) { +// return duration.shiftTo('hours').hours.toFixed(0) + ' hrs' +// } else if (duration.seconds >= 86400 && duration.seconds < 172800) { +// return '1 day' +// } else { +// return duration.shiftTo('days').days.toFixed(0) + ' days' +// } +// } -function getTime(timestamp: Date | number | string): number { - if (timestamp instanceof Date) { - return timestamp.getTime() - } - if (typeof timestamp === 'string') { - return new Date(timestamp).getTime() - } - return timestamp -} +// function getTime(timestamp: Date | number | string): number { +// if (timestamp instanceof Date) { +// return timestamp.getTime() +// } +// if (typeof timestamp === 'string') { +// return new Date(timestamp).getTime() +// } +// return timestamp +// } export function displayLongString(val: string, maxLength = 12): string { if (!val) {