Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

style: adjust minor style issues #1707

Merged
merged 6 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions packages/extension-polkagate/src/components/ScrollingTextBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
/* eslint-disable react/jsx-max-props-per-line */

import { Box, styled, type SxProps, type Theme, Typography } from '@mui/material';
import React, { memo, useEffect, useMemo, useRef, useState } from 'react';
import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';

interface ScrollingTextBoxProps {
text: string;
width: number;
style?: SxProps<Theme>;
textStyle?: SxProps<Theme>;
scrollOnHover?: boolean;
}

const BoxContainer = styled(Box)(({ maximumWidth, shouldScroll }: { shouldScroll: boolean; maximumWidth: number }) => ({
Expand Down Expand Up @@ -40,27 +41,34 @@ const BoxContainer = styled(Box)(({ maximumWidth, shouldScroll }: { shouldScroll
width: 'fit-content'
}));

function ScrollingTextBox ({ style, text, textStyle, width }: ScrollingTextBoxProps): React.ReactElement {
function ScrollingTextBox ({ scrollOnHover = false, style, text, textStyle, width }: ScrollingTextBoxProps): React.ReactElement {
const textRef = useRef<HTMLDivElement>(null);
const [shouldScroll, setShouldScroll] = useState(false);
const [textWidth, setTextWidth] = useState(0);
const [isHovering, setIsHovering] = useState(false);

const uniqueKeyframeName = useMemo(() => `scrollText-${Math.random().toString(36).substring(2, 11)}`, []);

useEffect(() => {
if (scrollOnHover && !isHovering) {
setShouldScroll(false);

return;
}

if (textRef.current) {
const isOverflowing = textRef.current.scrollWidth > textRef.current.clientWidth;

setShouldScroll(isOverflowing);
setTextWidth(textRef.current.scrollWidth);
}
}, [text]);
}, [isHovering, scrollOnHover, text]);

const animationDuration = useMemo(() => Math.max(10, textWidth / 50), [textWidth]); // Adjusts scrolling speed

const textboxStyle: SxProps<Theme> = useMemo(() => ({
'&:hover': {
animationPlayState: 'paused'
animationPlayState: scrollOnHover ? 'running' : 'paused'
},
[`@keyframes ${uniqueKeyframeName}`]: {
'0%': { transform: 'translateX(0)' },
Expand All @@ -72,11 +80,14 @@ function ScrollingTextBox ({ style, text, textStyle, width }: ScrollingTextBoxPr
animation: shouldScroll
? `${uniqueKeyframeName} ${animationDuration}s linear infinite`
: 'none',
animationPlayState: scrollOnHover ? (isHovering ? 'running' : 'paused') : isHovering ? 'paused' : 'running',
whiteSpace: 'nowrap'
}), [animationDuration, shouldScroll, textWidth, uniqueKeyframeName, width]);
}), [animationDuration, isHovering, scrollOnHover, shouldScroll, textWidth, uniqueKeyframeName, width]);

const toggleHover = useCallback(() => setIsHovering((isHovered) => !isHovered), []);

return (
<BoxContainer maximumWidth={width} shouldScroll={shouldScroll} sx={style}>
<BoxContainer maximumWidth={width} onMouseEnter={toggleHover} onMouseLeave={toggleHover} shouldScroll={shouldScroll} sx={style}>
<Typography ref={textRef} sx={{ ...textboxStyle, ...textStyle }}>
{text}
</Typography>
Expand Down
1 change: 1 addition & 0 deletions packages/extension-polkagate/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ export { default as useTimeToUnlock } from './useTimeToUnlock';
export { default as useTimeToUnlock2 } from './useTimeToUnlock2';
export { default as useToken } from './useToken';
export { default as useTokenPrice } from './useTokenPrice';
export { default as useTokenPriceBySymbol } from './useTokenPriceBySymbol';
export { default as useTokens } from './useTokens';
export { default as useTrack } from './useTrack';
export { default as useTracks } from './useTracks';
Expand Down
54 changes: 54 additions & 0 deletions packages/extension-polkagate/src/hooks/useTokenPriceBySymbol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2019-2025 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { createAssets } from '@polkagate/apps-config/assets';
import { useMemo } from 'react';

import { useUserAddedPriceId } from '../fullscreen/addNewChain/utils';
import { toCamelCase } from '../fullscreen/governance/utils/util';
import { getPriceIdByChainName } from '../util/utils';
import { useChainInfo, usePrices } from '.';

const DEFAULT_PRICE = {
price: undefined,
priceDate: undefined
};

interface Price {
price: number | undefined,
priceDate: number | undefined;
}

const assetsChains = createAssets();

/**
* @description retrieve the price of a token from local storage PRICES
* @param address : accounts substrate address
* @param assetId : asset id on multi asset chains
* @param assetChainName : chain name to fetch asset id price from
* @returns price : price of the token which the address is already switched to
*/
export default function useTokenPriceBySymbol (tokenSymbol: string | undefined, genesisHash: string | undefined): Price {
const { chainName } = useChainInfo(genesisHash);
const userAddedPriceId = useUserAddedPriceId(genesisHash);
const pricesInCurrencies = usePrices();
const maybeAssetsOnMultiAssetChains = assetsChains[toCamelCase(chainName || '')];

return useMemo(() => {
if (!chainName || !pricesInCurrencies || !tokenSymbol || !genesisHash) {
return DEFAULT_PRICE;
}

// FixMe, on second fetch of asset id its type will get string which is weird!!
const maybeAssetInfo = maybeAssetsOnMultiAssetChains?.find(({ symbol }) => symbol.toLowerCase() === tokenSymbol.toLowerCase()) ?? undefined;

const priceId = maybeAssetInfo?.priceId || userAddedPriceId || getPriceIdByChainName(chainName);

const maybePriceValue = priceId ? pricesInCurrencies.prices?.[priceId]?.value || 0 : 0;

return {
price: maybePriceValue,
priceDate: pricesInCurrencies.date
};
}, [chainName, genesisHash, maybeAssetsOnMultiAssetChains, pricesInCurrencies, tokenSymbol, userAddedPriceId]);
}
1 change: 1 addition & 0 deletions packages/extension-polkagate/src/partials/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { default as ConnectedDapp } from './ConnectedDapp';
export { default as FullScreenChainSwitch } from './FullScreenChainSwitch';
export { default as FullscreenModeButton } from './FullscreenModeButton';
export { default as HeaderBrand } from './HeaderBrand';
export { default as HomeMenu } from './HomeMenu';
export { default as LogoDropAnimation } from './LogoDropAnimation';
export { default as Name } from './Name';
export { default as Passwords } from './Passwords';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
import type { TransactionDetail } from '@polkadot/extension-polkagate/util/types';

import { Box, Container, type SxProps, type Theme, Typography } from '@mui/material';
import React, { memo } from 'react';
import React, { memo, useCallback } from 'react';

import { emptyHistoryList } from '../../../assets/icons/index';
import { useTranslation } from '../../../hooks';
import VelvetBox from '../../../style/VelvetBox';
import AssetLoading from '../../home/partial/AssetLoading';
import HistoryItem from './HistoryItem';

function EmptyHistoryBox () {
Expand All @@ -36,21 +37,59 @@ interface Props {
}

function HistoryBox ({ historyItems, style }: Props) {
const formatDate = useCallback((inputDate: string) => {
// Handle invalid dates
const date = new Date(inputDate);

if (isNaN(date.getTime())) {
return inputDate;
}

const today = new Date();
const yesterday = new Date(today);

yesterday.setDate(today.getDate() - 1);

// Reset time components for accurate comparison
const resetTime = (date: Date) => {
date.setHours(0, 0, 0, 0);

return date;
};

const compareDate = resetTime(new Date(date));
const compareToday = resetTime(new Date(today));
const compareYesterday = resetTime(new Date(yesterday));

if (compareDate.getTime() === compareToday.getTime()) {
return 'Today';
}

if (compareDate.getTime() === compareYesterday.getTime()) {
return 'Yesterday';
}

return inputDate;
}, []);

return (
<VelvetBox style={style}>
<Container disableGutters sx={{ display: 'grid', rowGap: '4px' }}>
{historyItems && Object.entries(historyItems).map(([date, items], index) => (
<HistoryItem
historyDate={date}
historyDate={formatDate(date)}
historyItems={items}
key={index}
/>
))
}
<div id='observerObj' style={{ height: '1px' }} />
{!historyItems &&
{historyItems === null &&
<EmptyHistoryBox />
}
{historyItems === undefined &&
<AssetLoading itemsCount={2} noDrawer />
}
</Container>
</VelvetBox>
);
Expand Down
Loading