diff --git a/frontends/web/src/components/rates/rates.module.css b/frontends/web/src/components/rates/rates.module.css index dd2735320d..401052d6cb 100644 --- a/frontends/web/src/components/rates/rates.module.css +++ b/frontends/web/src/components/rates/rates.module.css @@ -17,10 +17,6 @@ position: relative; } -.fiatRow { - -} - .availableFiatAmount { padding-right: var(--space-quarter) !important; text-align: right; @@ -33,8 +29,12 @@ position: relative; } -.unitAction::after, -.availableFiatUnit::after { +.rotatable { + position: relative; + cursor: default; +} + +.rotatable::after { border-bottom: dotted 1px var(--color-softblack); content: ""; position: absolute; @@ -58,8 +58,3 @@ } } -@media (max-width: 640px) { - .availableFiatUnit::after { - border-bottom: none; - } -} diff --git a/frontends/web/src/components/rates/rates.tsx b/frontends/web/src/components/rates/rates.tsx index 00b29bc486..3eee5b331c 100644 --- a/frontends/web/src/components/rates/rates.tsx +++ b/frontends/web/src/components/rates/rates.tsx @@ -70,7 +70,7 @@ function Conversion({ alwaysShowAmounts = false }: TProvidedProps) { - const { rotateFiat, defaultCurrency, btcUnit } = useContext(RatesContext); + const { defaultCurrency, btcUnit } = useContext(RatesContext); let formattedAmount = <>{'---'}; let isAvailable = false; @@ -92,7 +92,7 @@ function Conversion({ {formattedAmount} { !noAction && ( - {activeUnit} + ) } { @@ -110,7 +110,7 @@ function Conversion({ {' '} { !skipUnit && !noAction && ( - {activeUnit} + ) } { @@ -122,6 +122,26 @@ function Conversion({ ); } +type TDefaultCurrencyRotator = { + activeUnit?: ConversionUnit; + className?: string; + tableRow?: boolean; +} + +export const DefaultCurrencyRotator = ({ + activeUnit, + className = '', + tableRow = true +}: TDefaultCurrencyRotator) => { + const { rotateDefaultCurrency, defaultCurrency } = useContext(RatesContext); + const displayedCurrency = activeUnit ? activeUnit : defaultCurrency; + const textStyle = `${className} ${style.rotatable}`; + if (!tableRow) { + return {displayedCurrency}; + } + return {displayedCurrency}; +}; + export const formattedCurrencies = currenciesWithDisplayName.map((fiat) => ({ label: `${fiat.displayName} (${fiat.currency})`, value: fiat.currency })); export const FiatConversion = Conversion; diff --git a/frontends/web/src/contexts/RatesContext.tsx b/frontends/web/src/contexts/RatesContext.tsx index 1a23f7cdcc..a90d0946b7 100644 --- a/frontends/web/src/contexts/RatesContext.tsx +++ b/frontends/web/src/contexts/RatesContext.tsx @@ -22,11 +22,11 @@ type RatesContextProps = { defaultCurrency: Fiat; activeCurrencies: Fiat[]; btcUnit?: BtcUnit; - rotateFiat: () => void; - selectFiat: (fiat: Fiat) => Promise; - updateDefaultFiat: (fiat: Fiat) => void; + rotateDefaultCurrency: () => Promise; + addToActiveCurrencies: (fiat: Fiat) => Promise; + updateDefaultCurrency: (fiat: Fiat) => void; updateRatesConfig: () => Promise; - unselectFiat: (fiat: Fiat) => Promise; + removeFromActiveCurrencies: (fiat: Fiat) => Promise; } const RatesContext = createContext({} as RatesContextProps); diff --git a/frontends/web/src/contexts/RatesProvider.tsx b/frontends/web/src/contexts/RatesProvider.tsx index 6956f6e01c..620385c9ea 100644 --- a/frontends/web/src/contexts/RatesProvider.tsx +++ b/frontends/web/src/contexts/RatesProvider.tsx @@ -48,31 +48,33 @@ export const RatesProvider = ({ children }: TProps) => { } }; - const rotateFiat = () => { + const rotateDefaultCurrency = async () => { const index = activeCurrencies.indexOf(defaultCurrency); const fiat = activeCurrencies[(index + 1) % activeCurrencies.length]; - updateDefaultFiat(fiat); + await updateDefaultCurrency(fiat); }; - const updateDefaultFiat = (fiat: Fiat) => { + // sets default currency both in config (mainFiat) + // and in RatesContext context's (local) state + const updateDefaultCurrency = async (fiat: Fiat) => { if (!activeCurrencies.includes(fiat)) { - selectFiat(fiat); + addToActiveCurrencies(fiat); } + await setConfig({ backend: { mainFiat: fiat } }); setDefaultCurrency(fiat); - setConfig({ backend: { mainFiat: fiat } }); }; - //this is a method to select a fiat to be - //added into the selected fiat list - const selectFiat = async (fiat: Fiat) => { + // this is a method to select / add a currency + // into the active currencies list + const addToActiveCurrencies = async (fiat: Fiat) => { const selected = [...activeCurrencies, fiat]; await setConfig({ backend: { fiatList: selected } }); handleChangeSelectedFiat(selected); }; - //this is a method to unselect a fiat to be - //removed from the selected fiat list - const unselectFiat = async (fiat: Fiat) => { + // this is a method to unselect / remove a currency + // from the active currencies list + const removeFromActiveCurrencies = async (fiat: Fiat) => { const selected = activeCurrencies.filter(item => !equal(item, fiat)); await setConfig({ backend: { fiatList: selected } }); handleChangeSelectedFiat(selected); @@ -91,11 +93,11 @@ export const RatesProvider = ({ children }: TProps) => { defaultCurrency, activeCurrencies, btcUnit, - rotateFiat, - selectFiat, - updateDefaultFiat, + rotateDefaultCurrency, + addToActiveCurrencies, + updateDefaultCurrency, updateRatesConfig, - unselectFiat + removeFromActiveCurrencies }} > {children} diff --git a/frontends/web/src/routes/account/summary/accountssummary.tsx b/frontends/web/src/routes/account/summary/accountssummary.tsx index a060ba5e31..ea9513594c 100644 --- a/frontends/web/src/routes/account/summary/accountssummary.tsx +++ b/frontends/web/src/routes/account/summary/accountssummary.tsx @@ -34,6 +34,7 @@ import { Guide } from '../../../components/guide/guide'; import { HideAmountsButton } from '../../../components/hideamountsbutton/hideamountsbutton'; import { AppContext } from '../../../contexts/AppContext'; import { getAccountsByKeystore, isAmbiguiousName } from '../utils'; +import { RatesContext } from '../../../contexts/RatesContext'; type TProps = { accounts: accountApi.IAccount[]; @@ -52,6 +53,7 @@ export function AccountsSummary({ const summaryReqTimerID = useRef(); const mounted = useMountedRef(); const { hideAmounts } = useContext(AppContext); + const { defaultCurrency } = useContext(RatesContext); const accountsByKeystore = getAccountsByKeystore(accounts); @@ -138,17 +140,24 @@ export function AccountsSummary({ } }, [getAccountSummary, mounted, onStatusChanged]); - // fetch accounts summary and balance on the first render. useEffect(() => { + // for subscriptions and unsubscriptions + // runs only on component mount and unmount. const subscriptions = [ statusChanged(update), syncdone(update) ]; + return () => unsubscribe(subscriptions); + }, [update]); + + + useEffect(() => { + // handles fetching data and runs on component mount + // & whenever any of the dependencies change. getAccountSummary(); getAccountsBalance(); getAccountsTotalBalance(); - return () => unsubscribe(subscriptions); - }, [getAccountSummary, getAccountsBalance, getAccountsTotalBalance, update]); + }, [getAccountSummary, getAccountsBalance, getAccountsTotalBalance, defaultCurrency]); // update the timer to get a new account summary update when receiving the previous call result. useEffect(() => { diff --git a/frontends/web/src/routes/account/summary/chart.module.css b/frontends/web/src/routes/account/summary/chart.module.css index 9cf48eb7d5..f5c236f8eb 100644 --- a/frontends/web/src/routes/account/summary/chart.module.css +++ b/frontends/web/src/routes/account/summary/chart.module.css @@ -116,11 +116,14 @@ .totalValue { font-size: 2rem; + display: flex; + align-items: flex-end; } .totalUnit { color: var(--color-secondary); display: inline-block; + margin-bottom: 3px; font-size: 1.4rem; padding: 0 .25rem; } diff --git a/frontends/web/src/routes/account/summary/chart.tsx b/frontends/web/src/routes/account/summary/chart.tsx index 2c48d6c5ae..cda28d544d 100644 --- a/frontends/web/src/routes/account/summary/chart.tsx +++ b/frontends/web/src/routes/account/summary/chart.tsx @@ -24,8 +24,8 @@ import { Amount } from '../../../components/amount/amount'; import Filters from './filters'; import { getDarkmode } from '../../../components/darkmode/darkmode'; import { TChartDisplay, TChartFiltersProps } from './types'; +import { DefaultCurrencyRotator } from '../../../components/rates/rates'; import styles from './chart.module.css'; - export interface FormattedLineData extends LineData { formattedValue: string; } @@ -56,7 +56,6 @@ type Props = ChartProps & TranslateProps; type FormattedData = { [key: number]: string; } - class Chart extends Component { private ref = createRef(); private refToolTip = createRef(); @@ -129,6 +128,10 @@ class Chart extends Component { } }); } + + if (this.props.data.chartFiat !== prev.data.chartFiat) { + this.reinitializeChart(); + } } private hasData = (): boolean => { @@ -240,6 +243,19 @@ class Chart extends Component { } }; + private reinitializeChart = () => { + this.removeChart(); + this.createChart(); + }; + + private removeChart = () => { + if (this.chart) { + this.chart.remove(); + this.chart = undefined; + window.removeEventListener('resize', this.onResize); + } + }; + private onResize = () => { this.checkIfMobile(); if (this.resizeTimerID) { @@ -514,7 +530,7 @@ class Chart extends Component { )} - {chartTotal !== null && chartFiat} + {chartTotal !== null && } {!showMobileTotalValue ? diff --git a/frontends/web/src/routes/settings/components/appearance/defaultCurrencyDropdownSetting.tsx b/frontends/web/src/routes/settings/components/appearance/defaultCurrencyDropdownSetting.tsx index 3f9ca75335..127a2a8301 100644 --- a/frontends/web/src/routes/settings/components/appearance/defaultCurrencyDropdownSetting.tsx +++ b/frontends/web/src/routes/settings/components/appearance/defaultCurrencyDropdownSetting.tsx @@ -24,7 +24,7 @@ import { RatesContext } from '../../../../contexts/RatesContext'; export const DefaultCurrencyDropdownSetting = () => { const { t } = useTranslation(); - const { selectFiat, updateDefaultFiat, defaultCurrency, activeCurrencies } = useContext(RatesContext); + const { addToActiveCurrencies, updateDefaultCurrency, defaultCurrency, activeCurrencies } = useContext(RatesContext); const valueLabel = currenciesWithDisplayName.find(fiat => fiat.currency === defaultCurrency)?.displayName; const defaultValueLabel = valueLabel ? `${valueLabel} (${defaultCurrency})` : defaultCurrency; return ( @@ -36,9 +36,9 @@ export const DefaultCurrencyDropdownSetting = () => { { - updateDefaultFiat(fiat); + updateDefaultCurrency(fiat); if (!activeCurrencies.includes(fiat)) { - await selectFiat(fiat); + await addToActiveCurrencies(fiat); } }} defaultValue={{ diff --git a/frontends/web/src/routes/settings/components/dropdowns/activecurrenciesdropdown.tsx b/frontends/web/src/routes/settings/components/dropdowns/activecurrenciesdropdown.tsx index dc22ee862b..6ad683c3d3 100644 --- a/frontends/web/src/routes/settings/components/dropdowns/activecurrenciesdropdown.tsx +++ b/frontends/web/src/routes/settings/components/dropdowns/activecurrenciesdropdown.tsx @@ -28,7 +28,7 @@ export const ActiveCurrenciesDropdown = ({ const [search, setSearch] = useState(''); const { t } = useTranslation(); - const { unselectFiat, selectFiat } = useContext(RatesContext); + const { removeFromActiveCurrencies, addToActiveCurrencies } = useContext(RatesContext); useEffect(() => { if (activeCurrencies.length > 0) { @@ -77,12 +77,12 @@ export const ActiveCurrenciesDropdown = ({ switch (meta.action) { case 'select-option': if (meta.option) { - await selectFiat(meta.option.value); + await addToActiveCurrencies(meta.option.value); } break; case 'deselect-option': if (meta.option && meta.option.value !== defaultCurrency) { - await unselectFiat(meta.option.value); + await removeFromActiveCurrencies(meta.option.value); } } }}