taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 21a196769897d1092966103a05e99a1ab9a16c11
parent d3948b0d813a272f6b1c547c459531e992854dcd
Author: Sebastian <sebasjm@gmail.com>
Date:   Thu, 29 May 2025 11:55:57 -0300

fix #9536

Diffstat:
Mpackages/taler-wallet-webextension/set-up-dev-wallet.sh | 4++--
Mpackages/taler-wallet-webextension/src/cta/Withdraw/state.ts | 16+++++++++++++++-
Mpackages/taler-wallet-webextension/src/hooks/useSelectedExchange.ts | 27++++++++++++++-------------
Mpackages/taler-wallet-webextension/src/wallet/History.tsx | 35+++++++++++++++++++++--------------
4 files changed, 52 insertions(+), 30 deletions(-)

diff --git a/packages/taler-wallet-webextension/set-up-dev-wallet.sh b/packages/taler-wallet-webextension/set-up-dev-wallet.sh @@ -43,5 +43,5 @@ cp -r service_worker.js $TEMP_DIR (cd $TEMP_DIR && zip -q -r "../$zipfile" dist static manifest.json service_worker.js) echo now run the development server -echo FOR v3: 'INSTALL_DIR=$PWD/extension-dev/v3/dist ./dev.mjs' -echo FOR v2: 'INSTALL_DIR=$PWD/extension-dev/v2/dist ./dev.mjs' +echo 'INSTALL_DIR=$PWD/extension-dev/v3/dist ./dev.mjs #FOR v3 version' +echo 'INSTALL_DIR=$PWD/extension-dev/v2/dist ./dev.mjs #FOR v2 version' diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts @@ -21,6 +21,7 @@ import { ExchangeFullDetails, ExchangeListItem, NotificationType, + ScopeInfo, ScopeType, TransactionMajorState, TransactionMinorState, @@ -139,6 +140,12 @@ export function useComponentStateFromParams({ }; } + const exchangeScope = scope ?? { + type: ScopeType.Exchange, + currency: currency, + url: exchangeByUrl!, + }; + return () => exchangeSelectionState( doManualWithdraw, @@ -156,6 +163,7 @@ export function useComponentStateFromParams({ exchangeList: exchangeList, }, setUpdatedExchangeByUser, + exchangeScope, ); } @@ -289,6 +297,10 @@ export function useComponentStateFromURI({ }; } + const exchangeScope:ScopeInfo = { + type: ScopeType.Global, + currency: bwi.currency, + }; return useCallback(() => { return exchangeSelectionState( doManagedWithdraw, @@ -306,6 +318,7 @@ export function useComponentStateFromURI({ exchangeList: bwi.possibleExchanges, }, setUpdatedExchangeByUser, + exchangeScope ); }, []); } @@ -334,10 +347,11 @@ function exchangeSelectionState( talerWithdrawUri: string | undefined, wInfo: WithdrawalInfo, onExchangeUpdated: (ex: string) => void, + scope: ScopeInfo, ): RecursiveState<State> { const api = useBackendContext(); const selectedExchange = useSelectedExchange({ - currency: wInfo.currency, + scope, defaultExchange: wInfo.exchange, list: wInfo.exchangeList, }); diff --git a/packages/taler-wallet-webextension/src/hooks/useSelectedExchange.ts b/packages/taler-wallet-webextension/src/hooks/useSelectedExchange.ts @@ -14,7 +14,7 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { ExchangeListItem } from "@gnu-taler/taler-util"; +import { ExchangeListItem, ScopeInfo, ScopeType, stringifyScopeInfoShort } from "@gnu-taler/taler-util"; import { useState } from "preact/hooks"; import { useAlertContext } from "../context/alert.js"; import { ButtonHandler } from "../mui/handlers.js"; @@ -25,7 +25,7 @@ export namespace State { export interface NoExchangeFound { status: "no-exchange-found"; error: undefined; - currency: string; + scope: ScopeInfo; defaultExchange: string | undefined; } export interface Ready { @@ -39,13 +39,13 @@ export namespace State { onSelection: (url: string) => Promise<void>; onCancel: () => Promise<void>; list: ExchangeListItem[]; - currency: string; + scope: ScopeInfo; initialValue: string; } } interface Props { - currency: string; + scope: ScopeInfo; //there is a preference for the default at the initial state defaultExchange?: string; //list of exchanges @@ -53,7 +53,7 @@ interface Props { } export function useSelectedExchange({ - currency, + scope, defaultExchange, list, }: Props): State { @@ -67,18 +67,19 @@ export function useSelectedExchange({ return { status: "no-exchange-found", error: undefined, - currency, + scope, defaultExchange, }; } - const exchangesWithThisCurrency = list.filter((e) => e.currency === currency); - if (!exchangesWithThisCurrency.length) { + const scopeStr = stringifyScopeInfoShort(scope) + const exchangesWithThisScope = list.filter((e) => stringifyScopeInfoShort(e.scopeInfo) === scopeStr); + if (!exchangesWithThisScope.length) { // there should be at least one exchange for this currency return { status: "no-exchange-found", error: undefined, - currency, + scope, defaultExchange, }; } @@ -87,12 +88,12 @@ export function useSelectedExchange({ const currentExchange = selectedExchange ?? defaultExchange ?? - exchangesWithThisCurrency[0].exchangeBaseUrl; + exchangesWithThisScope[0].exchangeBaseUrl; return { status: "selecting-exchange", error: undefined, - list: exchangesWithThisCurrency, - currency, + list: exchangesWithThisScope, + scope, initialValue: currentExchange, onSelection: async (exchangeBaseUrl: string) => { setIsSelecting(false); @@ -136,6 +137,6 @@ export function useSelectedExchange({ doSelect: { onClick: pushAlertOnError(async () => setIsSelecting(true)), }, - selected: exchangesWithThisCurrency[0], + selected: exchangesWithThisScope[0], }; } diff --git a/packages/taler-wallet-webextension/src/wallet/History.tsx b/packages/taler-wallet-webextension/src/wallet/History.tsx @@ -246,6 +246,12 @@ export function HistoryView({ {balances.length === 1 ? ( <CenteredText style={{ fontSize: "x-large", margin: 8 }}> {balance.scopeInfo.currency} + <div style={{ fontSize: "small", color: "grey" }}> + {balance.scopeInfo.type === ScopeType.Exchange || + balance.scopeInfo.type === ScopeType.Auditor + ? balance.scopeInfo.url + : undefined} + </div> </CenteredText> ) : ( <NiceSelect style={{ flexDirection: "column" }}> @@ -265,21 +271,11 @@ export function HistoryView({ }} > {balances.map((entry, si) => { - const sc = entry.scopeInfo; - const st = stringifyScopeInfoShort(sc); - - if (sc.type === ScopeType.Global) { - return ( - <option value={st} key={st}> - {sc.currency} - </option> - ); - } - + const st = stringifyScopeInfoShort(entry.scopeInfo); return ( - <optgroup label={new URL(sc.url).hostname}> - <option value={st}>{sc.currency}</option> - </optgroup> + <option value={st} key={st}> + <BalanceLabel sc={entry.scopeInfo} /> + </option> ); })} </select> @@ -401,3 +397,14 @@ export function FilteredHistoryView({ </Fragment> ); } +function BalanceLabel({ sc }: { sc: ScopeInfo }): VNode { + if (sc.type === ScopeType.Global) { + return <b>{sc.currency}</b>; + } + + return ( + <Fragment> + {sc.currency} {new URL(sc.url).hostname} + </Fragment> + ); +}