From 77de8920ac850e0aebaf2e71651a2cbfc982fefb Mon Sep 17 00:00:00 2001 From: mvaivre Date: Fri, 17 Jan 2025 15:33:40 +0100 Subject: [PATCH] Start to clean up AddressDetailsModal + dynamic scroll + many lil things --- .../src/components/AnimatedBackground.tsx | 4 +- apps/desktop-wallet/src/components/Button.tsx | 2 +- .../components/Buttons/ShortcutButtons.tsx | 1 + .../src/components/HashEllipsed.tsx | 26 ++++++----- .../src/components/LabeledWorthOverview.tsx | 12 ++--- .../src/components/Scrollbar.tsx | 13 +++--- .../src/features/assetsLists/TokensTabs.tsx | 4 +- .../src/features/snackbar/SnackbarBox.tsx | 11 ++--- .../AddressDetailsModal.tsx | 11 +++-- .../AddressDetailsModalHeader.tsx | 13 +++--- .../AddressDetailsModal/AddressWorth.tsx | 7 ++- .../SettingsModal/DevToolsSettingsSection.tsx | 4 +- apps/desktop-wallet/src/modals/SideModal.tsx | 45 +++++++++++++++---- 13 files changed, 98 insertions(+), 55 deletions(-) diff --git a/apps/desktop-wallet/src/components/AnimatedBackground.tsx b/apps/desktop-wallet/src/components/AnimatedBackground.tsx index 55057cf98..b6571cb24 100644 --- a/apps/desktop-wallet/src/components/AnimatedBackground.tsx +++ b/apps/desktop-wallet/src/components/AnimatedBackground.tsx @@ -17,7 +17,7 @@ interface AnimatedBackgroundProps { type AnchorPosition = 'top' | 'bottom' -const DARK_COLORS = ['#58a0ff', '#7057ff', '#ff709b', '#ff9b2f', '#1e71ff'] +const DARK_COLORS = ['#58a0ff', '#7057ff', '#272aff', '#ff9b2f', '#1e71ff'] const LIGHT_COLORS = ['#ad6eff', '#ffb47f', '#ffaaaa', '#ffc089', '#ff9bc8'] const AnimatedBackground = ({ @@ -263,6 +263,8 @@ const AnimatedContainer = styled.div` position: absolute; right: 0; left: 0; + z-index: 0; + pointer-events: none; ` const Circle = styled(motion.div)` diff --git a/apps/desktop-wallet/src/components/Button.tsx b/apps/desktop-wallet/src/components/Button.tsx index 09993ab93..45f4c63f9 100644 --- a/apps/desktop-wallet/src/components/Button.tsx +++ b/apps/desktop-wallet/src/components/Button.tsx @@ -227,7 +227,7 @@ export default styled(Button)` justify-content: ${({ Icon, justifyContent, children }) => justifyContent ?? (!Icon || !children ? 'center' : 'flex-start')}; height: ${({ circle, short, tall, tiny }) => - tiny ? '28px' : short ? '34px' : circle ? '34px' : tall ? '44px' : 'var(--inputHeight)'}; + tiny ? '28px' : short ? '34px' : circle ? '34px' : tall ? '46px' : 'var(--inputHeight)'}; width: ${({ circle, short, wide, tiny }) => tiny ? '28px' : circle ? '34px' : short && !wide ? 'auto' : wide ? '100%' : '80%'}; max-width: ${({ wide }) => (wide ? 'auto' : '250px')}; diff --git a/apps/desktop-wallet/src/components/Buttons/ShortcutButtons.tsx b/apps/desktop-wallet/src/components/Buttons/ShortcutButtons.tsx index 4ebe136e3..70f208a97 100644 --- a/apps/desktop-wallet/src/components/Buttons/ShortcutButtons.tsx +++ b/apps/desktop-wallet/src/components/Buttons/ShortcutButtons.tsx @@ -184,4 +184,5 @@ const ButtonsContainer = styled.div` align-items: center; justify-content: center; gap: 12px; + z-index: 1; ` diff --git a/apps/desktop-wallet/src/components/HashEllipsed.tsx b/apps/desktop-wallet/src/components/HashEllipsed.tsx index a0e7b5f19..cd2607b00 100644 --- a/apps/desktop-wallet/src/components/HashEllipsed.tsx +++ b/apps/desktop-wallet/src/components/HashEllipsed.tsx @@ -25,26 +25,28 @@ const HashEllipsed = ({ }: HashEllipsedProps) => { const { t } = useTranslation() - return disableCopy ? ( + return ( - + {disableCopy ? ( + + ) : ( + + + + )} - ) : ( - - - ) } export default HashEllipsed const Container = styled.div` + position: relative; display: flex; align-items: center; overflow: hidden; diff --git a/apps/desktop-wallet/src/components/LabeledWorthOverview.tsx b/apps/desktop-wallet/src/components/LabeledWorthOverview.tsx index 623486240..f68e5ebbe 100644 --- a/apps/desktop-wallet/src/components/LabeledWorthOverview.tsx +++ b/apps/desktop-wallet/src/components/LabeledWorthOverview.tsx @@ -24,7 +24,7 @@ import NetworkSwitch from '@/components/NetworkSwitch' import AddressWorth from '@/modals/AddressDetailsModal/AddressWorth' import WalletWorth from '@/pages/UnlockedWallet/OverviewPage/WalletWorth' -interface WorthOverviewPanelProps { +interface LabeledWorthOverviewProps { addressHash?: string isLoading?: boolean className?: string @@ -32,25 +32,25 @@ interface WorthOverviewPanelProps { children?: ReactNode } -const WorthOverviewPanel = ({ className, addressHash, children }: WorthOverviewPanelProps) => { +const LabeledWorthOverview = ({ className, addressHash, children }: LabeledWorthOverviewProps) => { const { t } = useTranslation() const singleAddress = !!addressHash return ( - + {t(singleAddress ? 'Address worth' : 'Wallet worth')} {singleAddress ? : } - + ) } -export default WorthOverviewPanel +export default LabeledWorthOverview -const WorthOverviewPanelStyled = styled.div` +const LabeledWorthOverviewStyled = styled.div` display: flex; flex-direction: column; align-items: center; diff --git a/apps/desktop-wallet/src/components/Scrollbar.tsx b/apps/desktop-wallet/src/components/Scrollbar.tsx index 83c72f4f0..a9538de3f 100644 --- a/apps/desktop-wallet/src/components/Scrollbar.tsx +++ b/apps/desktop-wallet/src/components/Scrollbar.tsx @@ -1,5 +1,3 @@ -// Used as reference: https://github.com/xobotyi/react-scrollbars-custom/issues/46#issuecomment-897506147 - import { useMotionValue } from 'framer-motion' import { ReactNode, UIEvent, useRef } from 'react' import { CustomScroll } from 'react-custom-scroll' @@ -9,18 +7,21 @@ import { ScrollContextProvider, ScrollContextType } from '@/contexts/scroll' interface ScrollbarCustomProps { children?: ReactNode className?: string + onScroll?: (scrollTop: number) => void } -const ScrollbarCustom = ({ children, className }: ScrollbarCustomProps) => { +const ScrollbarCustom = ({ children, className, onScroll }: ScrollbarCustomProps) => { const scrollY = useMotionValue(0) const contextValueRef = useRef({ scrollY }) const handleScrollUpdate = (e: UIEvent) => { - scrollY.set((e.target as HTMLElement).scrollTop) + const scrollTop = (e.target as HTMLElement).scrollTop + scrollY.set(scrollTop) + if (onScroll) { + onScroll(scrollTop) + } } - // react-scrollbars-custom has a type issue where you can't just spread props - // onto the component. That's why needed props are added as necessary. return ( {children} diff --git a/apps/desktop-wallet/src/features/assetsLists/TokensTabs.tsx b/apps/desktop-wallet/src/features/assetsLists/TokensTabs.tsx index 88839285f..9cef689b2 100644 --- a/apps/desktop-wallet/src/features/assetsLists/TokensTabs.tsx +++ b/apps/desktop-wallet/src/features/assetsLists/TokensTabs.tsx @@ -22,8 +22,8 @@ export const AddressTokensTabs = ({ addressHash }: AddressTokensTabsProps) => { const { tabs, isExpanded, toggleExpansion } = useTokensTabs({ numberOfNSTs: nstIds.length, ftsTabTitle: t('Address tokens'), - nstsTabTitle: t('Address unknown tokens'), - nftsTabTitle: t('Address NFTs') + nftsTabTitle: t('Address NFTs'), + nstsTabTitle: t('Address unknown tokens') }) const [currentTab, setCurrentTab] = useState>(tabs[0]) diff --git a/apps/desktop-wallet/src/features/snackbar/SnackbarBox.tsx b/apps/desktop-wallet/src/features/snackbar/SnackbarBox.tsx index 178079895..9479a9873 100644 --- a/apps/desktop-wallet/src/features/snackbar/SnackbarBox.tsx +++ b/apps/desktop-wallet/src/features/snackbar/SnackbarBox.tsx @@ -21,9 +21,9 @@ const SnackbarBoxContent = styled(motion.div)` word-wrap: break-word; overflow-y: auto; font-weight: var(--fontWeight-semiBold); - z-index: 1; pointer-events: all; margin-top: -10px; + z-index: 1; ` const BlurredBackground = styled.div` @@ -54,7 +54,7 @@ const SnackBarBoxContainer = styled(motion.div)` } &.info { - ${({ theme }) => getSnackbarStyling(colord(theme.global.accent).alpha(0.5).toHex())} + ${({ theme }) => getSnackbarStyling(theme.global.accent)} } &.success { @@ -66,13 +66,14 @@ export default SnackbarBox const getSnackbarStyling = (color: string) => css` ${BlurredBackground} { - background: linear-gradient(to bottom, ${color} 0%, transparent 80%); + background: linear-gradient(to bottom, ${color} 50%, transparent 80%); } ${SnackbarBoxContent} { + font-size: 14px; color: ${({ theme }) => theme.name === 'light' - ? colord(color).alpha(1).darken(0.1).toHex() - : colord(color).alpha(1).lighten(0.3).toHex()}; + ? colord(color).alpha(1).lighten(0.7).toHex() + : colord(color).alpha(1).lighten(0.4).toHex()}; } ` diff --git a/apps/desktop-wallet/src/modals/AddressDetailsModal/AddressDetailsModal.tsx b/apps/desktop-wallet/src/modals/AddressDetailsModal/AddressDetailsModal.tsx index 13ee8ecec..8118c84b7 100644 --- a/apps/desktop-wallet/src/modals/AddressDetailsModal/AddressDetailsModal.tsx +++ b/apps/desktop-wallet/src/modals/AddressDetailsModal/AddressDetailsModal.tsx @@ -2,16 +2,20 @@ import { memo, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' +import AnimatedBackground from '@/components/AnimatedBackground' import { ShortcutButtonsGroupAddress } from '@/components/Buttons/ShortcutButtons' -import WorthOverviewPanel from '@/components/LabeledWorthOverview' +import LabeledWorthOverview from '@/components/LabeledWorthOverview' import { AddressTokensTabs } from '@/features/assetsLists/TokensTabs' import { AddressModalProps } from '@/features/modals/modalTypes' import AddressTransactionsList from '@/features/transactionsDisplay/transactionLists/lists/AddressTransactionsList' +import { useAppSelector } from '@/hooks/redux' import AddressDetailsModalHeader from '@/modals/AddressDetailsModal/AddressDetailsModalHeader' import SideModal from '@/modals/SideModal' +import { selectAddressByHash } from '@/storage/addresses/addressesSelectors' const AddressDetailsModal = memo(({ id, addressHash }: AddressModalProps) => { const { t } = useTranslation() + const addressColor = useAppSelector((s) => selectAddressByHash(s, addressHash)?.color) const [showChart, setShowChart] = useState(false) @@ -23,8 +27,9 @@ const AddressDetailsModal = memo(({ id, addressHash }: AddressModalProps) => { header={} onAnimationComplete={() => setShowChart(true)} > - + + @@ -36,7 +41,7 @@ const AddressDetailsModal = memo(({ id, addressHash }: AddressModalProps) => { export default AddressDetailsModal const Content = styled.div` - padding: var(--spacing-4) var(--spacing-4) var(--spacing-4); + padding: 0 var(--spacing-4) var(--spacing-4); position: relative; gap: 45px; display: flex; diff --git a/apps/desktop-wallet/src/modals/AddressDetailsModal/AddressDetailsModalHeader.tsx b/apps/desktop-wallet/src/modals/AddressDetailsModal/AddressDetailsModalHeader.tsx index 0beb9175a..1285729fe 100644 --- a/apps/desktop-wallet/src/modals/AddressDetailsModal/AddressDetailsModalHeader.tsx +++ b/apps/desktop-wallet/src/modals/AddressDetailsModal/AddressDetailsModalHeader.tsx @@ -20,7 +20,7 @@ const Header = ({ addressHash }: AddressModalBaseProp) => { return ( - + @@ -61,7 +61,7 @@ const HeaderStyled = styled.div` const LeftSide = styled.div` display: flex; align-items: center; - gap: 25px; + gap: 15px; ` const ExplorerButton = styled(Button)` @@ -70,19 +70,18 @@ const ExplorerButton = styled(Button)` ` const AddressBadgeStyled = styled(AddressBadge)` - font-size: 16px; + font-size: 15px; max-width: 160px; ` const Title = styled.div` display: flex; - flex-direction: column; - gap: 5px; - font-weight: var(--fontWeight-semiBold); + align-items: center; + gap: 10px; ` const TitleAddressHash = styled(HashEllipsed)` max-width: 100px; color: ${({ theme }) => theme.font.tertiary}; - font-size: 13px; + font-size: 14px; ` diff --git a/apps/desktop-wallet/src/modals/AddressDetailsModal/AddressWorth.tsx b/apps/desktop-wallet/src/modals/AddressDetailsModal/AddressWorth.tsx index 1ca664c66..5d6ba41f8 100644 --- a/apps/desktop-wallet/src/modals/AddressDetailsModal/AddressWorth.tsx +++ b/apps/desktop-wallet/src/modals/AddressDetailsModal/AddressWorth.tsx @@ -1,4 +1,5 @@ import { memo } from 'react' +import styled from 'styled-components' import useFetchAddressWorth from '@/api/apiDataHooks/address/useFetchAddressWorth' import WorthOverview from '@/components/WorthOverview' @@ -11,7 +12,11 @@ interface AddressWorthProps { const AddressWorth = memo(({ addressHash, ...props }: AddressWorthProps) => { const { data: worth, isLoading } = useFetchAddressWorth(addressHash) - return + return }) export default AddressWorth + +const AddressWorthStyled = styled(WorthOverview)` + font-size: 38px; +` diff --git a/apps/desktop-wallet/src/modals/SettingsModal/DevToolsSettingsSection.tsx b/apps/desktop-wallet/src/modals/SettingsModal/DevToolsSettingsSection.tsx index 4ff5ec661..ae3e29415 100644 --- a/apps/desktop-wallet/src/modals/SettingsModal/DevToolsSettingsSection.tsx +++ b/apps/desktop-wallet/src/modals/SettingsModal/DevToolsSettingsSection.tsx @@ -110,10 +110,10 @@ const DevToolsSettingsSection = () => { {t('Smart contracts')} - - diff --git a/apps/desktop-wallet/src/modals/SideModal.tsx b/apps/desktop-wallet/src/modals/SideModal.tsx index 660b6dad4..a55def133 100644 --- a/apps/desktop-wallet/src/modals/SideModal.tsx +++ b/apps/desktop-wallet/src/modals/SideModal.tsx @@ -1,13 +1,13 @@ import { colord } from 'colord' import { motion } from 'framer-motion' import { X } from 'lucide-react' -import { ReactNode } from 'react' +import { ReactNode, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' import { normalTransition } from '@/animations' import Button from '@/components/Button' -import Scrollbar from '@/components/Scrollbar' +import ScrollbarCustom from '@/components/Scrollbar' import { closeModal } from '@/features/modals/modalActions' import { useAppDispatch } from '@/hooks/redux' import useFocusOnMount from '@/hooks/useFocusOnMount' @@ -36,6 +36,14 @@ const SideModal = ({ const _onClose = id ? () => dispatch(closeModal({ id })) : onClose + const [headerBgOpacity, setHeaderBgOpacity] = useState(0) + + const handleScroll = (scrollTop: number) => { + const maxScroll = 100 + const newOpacity = Math.min(scrollTop / maxScroll, 1) + setHeaderBgOpacity(newOpacity) + } + return ( - + {children} - + + {!hideHeader && ( - {header ?? {title}} - + + + {header ?? {title}} + + )} @@ -83,13 +95,28 @@ const Sidebar = styled(motion.div)<{ width: number }>` const ModalHeader = styled.div` position: absolute; top: 0; - right: 0; left: 0; + right: 0; + height: 70px; + z-index: 1; +` + +const ModalHeaderBackground = styled.div` + position: absolute; + inset: 0; // Awesome shortcut! Top, right, bottom, left = 0 + pointer-events: none; + z-index: 0; + + background: ${({ theme }) => `linear-gradient(to bottom, ${colord(theme.bg.background2).toHex()} 55%, transparent)`}; +` + +const ModalHeaderContent = styled.div` + position: relative; display: flex; align-items: center; padding: 0 10px 16px 20px; height: 70px; - background: ${({ theme }) => `linear-gradient(to bottom, ${colord(theme.bg.background2).toHex()} 55%, transparent)`}; + z-index: 1; ` const HeaderColumn = styled.div` @@ -107,5 +134,5 @@ const Title = styled.div` ` const ContentContainer = styled.div` - padding-top: 50px; + padding-top: 70px; `