diff options
author | Florian Dold <florian@dold.me> | 2024-02-22 12:42:54 +0100 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2024-02-22 12:42:54 +0100 |
commit | 8153c5026f3e7a100564e6dd9944e054cbb1b910 (patch) | |
tree | b6fb4e4ba17c9642268a8040cd8803751251e641 | |
parent | 012ba47d0bf669c258d703606a09c5d48922a58f (diff) | |
download | wallet-core-8153c5026f3e7a100564e6dd9944e054cbb1b910.tar.gz wallet-core-8153c5026f3e7a100564e6dd9944e054cbb1b910.tar.bz2 wallet-core-8153c5026f3e7a100564e6dd9944e054cbb1b910.zip |
webextension: render more info about exchanges
6 files changed, 52 insertions, 11 deletions
diff --git a/packages/taler-util/src/time.ts b/packages/taler-util/src/time.ts index 5702b2947..66bde4fa2 100644 --- a/packages/taler-util/src/time.ts +++ b/packages/taler-util/src/time.ts @@ -639,7 +639,21 @@ export const codecForTimestamp: Codec<TalerProtocolTimestamp> = { if (typeof t_s === "number") { return { t_s }; } - throw Error(`expected timestamp at ${renderContext(c)}`); + throw Error(`expected protocol timestamp at ${renderContext(c)}`); + }, +}; + +export const codecForPreciseTimestamp: Codec<TalerPreciseTimestamp> = { + decode(x: any, c?: Context): TalerPreciseTimestamp { + const t_ms = x.t_ms; + if (typeof t_ms === "string") { + if (t_ms === "never") { + return { t_s: "never" }; + } + } else if (typeof t_ms === "number") { + return { t_s: Math.floor(t_ms / 1000) }; + } + throw Error(`expected precise timestamp at ${renderContext(c)}`); }, }; diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts index 5293fcd55..771d4d1f9 100644 --- a/packages/taler-util/src/wallet-types.ts +++ b/packages/taler-util/src/wallet-types.ts @@ -79,6 +79,7 @@ import { TalerProtocolDuration, TalerProtocolTimestamp, codecForAbsoluteTime, + codecForPreciseTimestamp, codecForTimestamp, } from "./time.js"; import { @@ -1342,6 +1343,8 @@ export interface ExchangeListItem { scopeInfo: ScopeInfo | undefined; + lastUpdateTimestamp: TalerPreciseTimestamp | undefined; + /** * Information about the last error that occurred when trying * to update the exchange info. @@ -1414,6 +1417,8 @@ export const codecForExchangeListItem = (): Codec<ExchangeListItem> => .property("exchangeUpdateStatus", codecForAny()) .property("ageRestrictionOptions", codecForList(codecForNumber())) .property("scopeInfo", codecForScopeInfo()) + .property("lastUpdateErrorInfo", codecForAny()) + .property("lastUpdateTimestamp", codecOptional(codecForPreciseTimestamp)) .build("ExchangeListItem"); export const codecForExchangesListResponse = (): Codec<ExchangesListResponse> => diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts index 4792c3c20..d17005705 100644 --- a/packages/taler-wallet-core/src/exchanges.ts +++ b/packages/taler-wallet-core/src/exchanges.ts @@ -309,6 +309,7 @@ async function makeExchangeListItem( ? AgeRestriction.getAgeGroupsFromMask(exchangeDetails.ageMask) : [], paytoUris: exchangeDetails?.wireInfo.accounts.map((x) => x.payto_uri) ?? [], + lastUpdateTimestamp: timestampOptionalPreciseFromDb(r.lastUpdate), lastUpdateErrorInfo, scopeInfo, }; diff --git a/packages/taler-wallet-webextension/src/wallet/AddExchange/test.ts b/packages/taler-wallet-webextension/src/wallet/AddExchange/test.ts index c9c119fd3..60d5b274c 100644 --- a/packages/taler-wallet-webextension/src/wallet/AddExchange/test.ts +++ b/packages/taler-wallet-webextension/src/wallet/AddExchange/test.ts @@ -19,18 +19,18 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { expect } from "chai"; -import { createWalletApiMock } from "../../test-utils.js"; -import * as tests from "@gnu-taler/web-util/testing"; -import { Props } from "./index.js"; -import { useComponentState } from "./state.js"; -import { nullFunction } from "../../mui/handlers.js"; -import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { ExchangeEntryStatus, ExchangeTosStatus, ExchangeUpdateStatus, } from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import * as tests from "@gnu-taler/web-util/testing"; +import { expect } from "chai"; +import { nullFunction } from "../../mui/handlers.js"; +import { createWalletApiMock } from "../../test-utils.js"; +import { Props } from "./index.js"; +import { useComponentState } from "./state.js"; const props: Props = { onBack: nullFunction, noDebounce: true, @@ -54,6 +54,7 @@ describe("AddExchange states", () => { tosStatus: ExchangeTosStatus.Pending, exchangeUpdateStatus: ExchangeUpdateStatus.UnavailableUpdate, paytoUris: [], + lastUpdateTimestamp: undefined, }, ], }, diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts index d42a3477d..3082ae7a4 100644 --- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts +++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts @@ -27,8 +27,8 @@ import { ExchangeUpdateStatus, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { expect } from "chai"; import * as tests from "@gnu-taler/web-util/testing"; +import { expect } from "chai"; import { nullFunction } from "../../mui/handlers.js"; import { createWalletApiMock } from "../../test-utils.js"; import { useComponentState } from "./state.js"; @@ -42,6 +42,7 @@ const exchangeArs: ExchangeListItem = { exchangeUpdateStatus: ExchangeUpdateStatus.Initial, paytoUris: [], ageRestrictionOptions: [], + lastUpdateTimestamp: undefined, }; describe("Destination selection states", () => { diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx b/packages/taler-wallet-webextension/src/wallet/Settings.tsx index 19b30dd5f..38e576496 100644 --- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx @@ -15,6 +15,7 @@ */ import { + AbsoluteTime, ExchangeListItem, ExchangeTosStatus, LibtoolVersion, @@ -153,16 +154,22 @@ export function SettingsView({ <i18n.Translate>URL</i18n.Translate> </th> <th> + <i18n.Translate>Status</i18n.Translate> + </th> + <th> <i18n.Translate>Terms of Service</i18n.Translate> </th> <th> + <i18n.Translate>Last Update</i18n.Translate> + </th> + <th> <i18n.Translate>Actions</i18n.Translate> </th> </tr> </thead> <tbody> {knownExchanges.map((e, idx) => { - function Status(): VNode { + function TosStatus(): VNode { switch (e.tosStatus) { case ExchangeTosStatus.Accepted: return ( @@ -195,7 +202,19 @@ export function SettingsView({ <a href={e.exchangeBaseUrl}>{e.exchangeBaseUrl}</a> </td> <td> - <Status /> + {e.exchangeEntryStatus} / {e.exchangeUpdateStatus} + </td> + <td> + <TosStatus /> + </td> + <td> + {e.lastUpdateTimestamp + ? AbsoluteTime.toIsoString( + AbsoluteTime.fromPreciseTimestamp( + e.lastUpdateTimestamp, + ), + ) + : "never"} </td> <td> <button |