From 655c5fc18a22ae167160dd93e53d87e130fa9afa Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 8 Jul 2021 15:23:53 -0300 Subject: add more backup stories, sync by one provider --- .../taler-wallet-webextension/clean_and_build.sh | 1 + .../src/hooks/useBackupStatus.ts | 55 ++++++++++++++++ .../src/hooks/useProviderStatus.ts | 34 ++++++++++ .../src/hooks/useProvidersByCurrency.ts | 50 --------------- .../src/popup/Backup.stories.tsx | 23 ++++++- .../src/popup/BackupPage.tsx | 75 +++++++++++++--------- .../src/popup/ProviderAddPage.tsx | 9 ++- .../src/popup/ProviderDetailPage.tsx | 15 ++--- .../src/popupEntryPoint.tsx | 20 +++--- packages/taler-wallet-webextension/src/wxApi.ts | 9 +++ 10 files changed, 189 insertions(+), 102 deletions(-) create mode 100644 packages/taler-wallet-webextension/src/hooks/useBackupStatus.ts create mode 100644 packages/taler-wallet-webextension/src/hooks/useProviderStatus.ts delete mode 100644 packages/taler-wallet-webextension/src/hooks/useProvidersByCurrency.ts (limited to 'packages/taler-wallet-webextension') diff --git a/packages/taler-wallet-webextension/clean_and_build.sh b/packages/taler-wallet-webextension/clean_and_build.sh index fa9e8d74b..e862be37e 100755 --- a/packages/taler-wallet-webextension/clean_and_build.sh +++ b/packages/taler-wallet-webextension/clean_and_build.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash # This file is in the public domain. +[ "also-wallet" == "$1" ] && { pnpm -C ../taler-wallet-core/ compile || exit 1; } pnpm clean && pnpm compile && rm -rf extension/ && ./pack.sh && (cd extension/ && unzip taler*.zip) diff --git a/packages/taler-wallet-webextension/src/hooks/useBackupStatus.ts b/packages/taler-wallet-webextension/src/hooks/useBackupStatus.ts new file mode 100644 index 000000000..2d51cb303 --- /dev/null +++ b/packages/taler-wallet-webextension/src/hooks/useBackupStatus.ts @@ -0,0 +1,55 @@ +import { ProviderInfo, ProviderPaymentPaid, ProviderPaymentStatus, ProviderPaymentType } from "@gnu-taler/taler-wallet-core"; +import { useEffect, useState } from "preact/hooks"; +import * as wxApi from "../wxApi"; + + +export interface BackupStatus { + deviceName: string; + providers: ProviderInfo[]; + sync: () => Promise; +} + +function getStatusTypeOrder(t: ProviderPaymentStatus) { + return [ + ProviderPaymentType.InsufficientBalance, + ProviderPaymentType.TermsChanged, + ProviderPaymentType.Unpaid, + ProviderPaymentType.Paid, + ProviderPaymentType.Pending, + ].indexOf(t.type) +} + +function getStatusPaidOrder(a: ProviderPaymentPaid, b: ProviderPaymentPaid) { + return a.paidUntil.t_ms === 'never' ? -1 : + b.paidUntil.t_ms === 'never' ? 1 : + a.paidUntil.t_ms - b.paidUntil.t_ms +} + +export function useBackupStatus(): BackupStatus | undefined { + const [status, setStatus] = useState(undefined) + + useEffect(() => { + async function run() { + //create a first list of backup info by currency + const status = await wxApi.getBackupInfo() + + const providers = status.providers.sort((a, b) => { + if (a.paymentStatus.type === ProviderPaymentType.Paid && b.paymentStatus.type === ProviderPaymentType.Paid) { + return getStatusPaidOrder(a.paymentStatus, b.paymentStatus) + } + return getStatusTypeOrder(a.paymentStatus) - getStatusTypeOrder(b.paymentStatus) + }) + + async function sync() { + await wxApi.syncAllProviders() + } + + setStatus({ deviceName: status.deviceId, providers, sync }) + } + run() + }, []) + + return status +} + + diff --git a/packages/taler-wallet-webextension/src/hooks/useProviderStatus.ts b/packages/taler-wallet-webextension/src/hooks/useProviderStatus.ts new file mode 100644 index 000000000..42eab5d80 --- /dev/null +++ b/packages/taler-wallet-webextension/src/hooks/useProviderStatus.ts @@ -0,0 +1,34 @@ +import { ProviderInfo } from "@gnu-taler/taler-wallet-core"; +import { useEffect, useState } from "preact/hooks"; +import * as wxApi from "../wxApi"; + +export interface ProviderStatus { + info?: ProviderInfo; + sync: () => Promise; +} + +export function useProviderStatus(url: string): ProviderStatus | undefined { + const [status, setStatus] = useState(undefined); + + useEffect(() => { + async function run() { + //create a first list of backup info by currency + const status = await wxApi.getBackupInfo(); + + const providers = status.providers.filter(p => p.syncProviderBaseUrl === url); + const info = providers.length ? providers[0] : undefined; + + async function sync() { + console.log("que tiene info", info) + if (info) { + await wxApi.syncOneProvider(info.syncProviderBaseUrl); + } + } + + setStatus({ info, sync }); + } + run(); + }, []); + + return status; +} diff --git a/packages/taler-wallet-webextension/src/hooks/useProvidersByCurrency.ts b/packages/taler-wallet-webextension/src/hooks/useProvidersByCurrency.ts deleted file mode 100644 index 09f61e468..000000000 --- a/packages/taler-wallet-webextension/src/hooks/useProvidersByCurrency.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Amounts } from "@gnu-taler/taler-util"; -import { ProviderInfo, ProviderPaymentPaid, ProviderPaymentStatus, ProviderPaymentType } from "@gnu-taler/taler-wallet-core"; -import { useEffect, useState } from "preact/hooks"; - -import * as wxApi from "../wxApi"; - -export interface BackupStatus { - deviceName: string; - providers: ProviderInfo[] -} - -function getStatusTypeOrder(t: ProviderPaymentStatus) { - return [ - ProviderPaymentType.InsufficientBalance, - ProviderPaymentType.TermsChanged, - ProviderPaymentType.Unpaid, - ProviderPaymentType.Paid, - ProviderPaymentType.Pending, - ].indexOf(t.type) -} - -function getStatusPaidOrder(a: ProviderPaymentPaid, b: ProviderPaymentPaid) { - return a.paidUntil.t_ms === 'never' ? -1 : - b.paidUntil.t_ms === 'never' ? 1 : - a.paidUntil.t_ms - b.paidUntil.t_ms -} - -export function useBackupStatus(): BackupStatus | undefined { - const [status, setStatus] = useState(undefined) - - useEffect(() => { - async function run() { - //create a first list of backup info by currency - const status = await wxApi.getBackupInfo() - - const providers = status.providers.sort((a, b) => { - if (a.paymentStatus.type === ProviderPaymentType.Paid && b.paymentStatus.type === ProviderPaymentType.Paid) { - return getStatusPaidOrder(a.paymentStatus, b.paymentStatus) - } - return getStatusTypeOrder(a.paymentStatus) - getStatusTypeOrder(b.paymentStatus) - }) - - setStatus({ deviceName: status.deviceId, providers }) - } - run() - }, []) - - return status -} - diff --git a/packages/taler-wallet-webextension/src/popup/Backup.stories.tsx b/packages/taler-wallet-webextension/src/popup/Backup.stories.tsx index cd40d69a9..2d28a6ddc 100644 --- a/packages/taler-wallet-webextension/src/popup/Backup.stories.tsx +++ b/packages/taler-wallet-webextension/src/popup/Backup.stories.tsx @@ -20,6 +20,7 @@ */ import { ProviderPaymentType } from '@gnu-taler/taler-wallet-core'; +import { addDays } from 'date-fns'; import { FunctionalComponent } from 'preact'; import { BackupView as TestedComponent } from './BackupPage'; @@ -61,7 +62,27 @@ export const LotOfProviders = createExample(TestedComponent, { "storageLimitInMegabytes": 16, "supportedProtocolVersion": "0.0" } - }, { + },{ + "active": true, + "syncProviderBaseUrl": "http://sync.taler:9967/", + "lastSuccessfulBackupTimestamp": { + "t_ms": 1625063925078 + }, + "paymentProposalIds": [ + "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG" + ], + "paymentStatus": { + "type": ProviderPaymentType.Paid, + "paidUntil": { + "t_ms": addDays(new Date(), 13).getTime() + } + }, + "terms": { + "annualFee": "ARS:1", + "storageLimitInMegabytes": 16, + "supportedProtocolVersion": "0.0" + } + },{ "active": false, "syncProviderBaseUrl": "http://sync.demo.taler.net/", "paymentProposalIds": [], diff --git a/packages/taler-wallet-webextension/src/popup/BackupPage.tsx b/packages/taler-wallet-webextension/src/popup/BackupPage.tsx index 91f1782cc..d7a2d863c 100644 --- a/packages/taler-wallet-webextension/src/popup/BackupPage.tsx +++ b/packages/taler-wallet-webextension/src/popup/BackupPage.tsx @@ -17,9 +17,9 @@ import { i18n, Timestamp } from "@gnu-taler/taler-util"; import { ProviderInfo } from "@gnu-taler/taler-wallet-core"; -import { formatDuration, intervalToDuration } from "date-fns"; -import { JSX, VNode } from "preact"; -import { useBackupStatus } from "../hooks/useProvidersByCurrency"; +import { differenceInMonths, formatDuration, intervalToDuration } from "date-fns"; +import { Fragment, JSX, VNode } from "preact"; +import { useBackupStatus } from "../hooks/useBackupStatus"; import { Pages } from "./popup"; interface Props { @@ -31,59 +31,59 @@ export function BackupPage({ onAddProvider }: Props): VNode { if (!status) { return
Loading...
} - return ; + return ; } export interface ViewProps { providers: ProviderInfo[], onAddProvider: () => void; + onSyncAll: () => Promise; } -export function BackupView({ providers, onAddProvider }: ViewProps): VNode { +export function BackupView({ providers, onAddProvider, onSyncAll }: ViewProps): VNode { return (
{!!providers.length &&
- {providers.map((provider, idx) => { + {providers.map((provider) => { return })}
} - {!providers.length &&
- There is not backup providers configured, add one with the button below + {!providers.length &&
+
No backup providers configured
+
}
-
+ {!!providers.length &&
- - +
-
+
}
) } interface TransactionLayoutProps { - status?: any; + status: any; timestamp?: Timestamp; title: string; - id: number; - subtitle?: string; - active?: boolean; + id: string; + active: boolean; } function BackupLayout(props: TransactionLayoutProps): JSX.Element { @@ -107,13 +107,12 @@ function BackupLayout(props: TransactionLayoutProps): JSX.Element {
- -
- {props.title} + - {dateStr &&
Last time synced: {dateStr}
} - {!dateStr &&
never synced
} + {dateStr &&
Last synced: {dateStr}
} + {!dateStr &&
Not synced
}
-
- {!props.status ? "missing" : ( - props.status?.type === 'paid' ? daysUntil(props.status.paidUntil) : 'unpaid' - )} +
+ { + props.status?.type === 'paid' ? + +
+ Expires in +
+
+ {daysUntil(props.status.paidUntil)} +
+
+ : + 'unpaid' + }
); } +function colorByTimeToExpire(d: Timestamp) { + if (d.t_ms === 'never') return 'rgb(28, 184, 65)' + const months = differenceInMonths(d.t_ms, new Date()) + return months > 1 ? 'rgb(28, 184, 65)' : 'rgb(223, 117, 20)'; +} + function daysUntil(d: Timestamp) { if (d.t_ms === 'never') return undefined const duration = intervalToDuration({ @@ -150,5 +165,5 @@ function daysUntil(d: Timestamp) { ) ] }) - return `${str} left` + return `${str}` } \ No newline at end of file diff --git a/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx b/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx index 1e4a44df1..ac22a5f83 100644 --- a/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx +++ b/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx @@ -5,6 +5,7 @@ import * as wxApi from "../wxApi"; interface Props { currency: string; + onBack: () => void; } function getJsonIfOk(r: Response) { @@ -20,16 +21,14 @@ function getJsonIfOk(r: Response) { } -export function ProviderAddPage({ }: Props): VNode { +export function ProviderAddPage({ onBack }: Props): VNode { const [verifying, setVerifying] = useState<{ url: string, provider: BackupBackupProviderTerms } | undefined>(undefined) const [readingTerms, setReadingTerms] = useState(undefined) const alreadyCheckedTheTerms = readingTerms === false if (!verifying) { return { - setVerifying(undefined); - }} + onCancel={onBack} onVerify={(url) => { return fetch(`${url}/config`) .catch(e => { throw new Error(`Network error`) }) @@ -56,7 +55,7 @@ export function ProviderAddPage({ }: Props): VNode { setReadingTerms(true) }} onConfirm={() => { - wxApi.addBackupProvider(verifying.url).then(_ => history.go(-1)) + wxApi.addBackupProvider(verifying.url).then(onBack) }} /> diff --git a/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx b/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx index 1b8abf44d..b7a6f847c 100644 --- a/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx +++ b/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx @@ -21,7 +21,8 @@ import { ContractTermsUtil } from "@gnu-taler/taler-wallet-core/src/util/contrac import { formatDuration, intervalToDuration, format } from "date-fns"; import { Fragment, VNode } from "preact"; import { useRef, useState } from "preact/hooks"; -import { useBackupStatus } from "../hooks/useProvidersByCurrency"; +import { useBackupStatus } from "../hooks/useBackupStatus"; +import { useProviderStatus } from "../hooks/useProviderStatus.js"; import * as wxApi from "../wxApi"; interface Props { @@ -30,18 +31,16 @@ interface Props { } export function ProviderDetailPage({ pid, onBack }: Props): VNode { - const status = useBackupStatus() + const status = useProviderStatus(pid) if (!status) { return
Loading...
} - const idx = parseInt(pid, 10) - if (Number.isNaN(idx) || !(status.providers[idx])) { + if (!status.info) { onBack() return
} - const info = status.providers[idx]; - return { null }} + return { null }} onBack={onBack} onExtend={() => { null }} @@ -63,7 +62,7 @@ export function ProviderView({ info, onDelete, onSync, onBack, onExtend }: ViewP
{info && } {info && } - {info && } + {info && }
} diff --git a/packages/taler-wallet-webextension/src/popupEntryPoint.tsx b/packages/taler-wallet-webextension/src/popupEntryPoint.tsx index 80a2a2bd3..42e9ab90e 100644 --- a/packages/taler-wallet-webextension/src/popupEntryPoint.tsx +++ b/packages/taler-wallet-webextension/src/popupEntryPoint.tsx @@ -99,17 +99,21 @@ function Application() { - { route(Pages.provider_add) - }} - /> - { - route(Pages.backup) - }} + }} + /> + { + route(Pages.backup) + }} + /> + { + route(Pages.backup) + }} /> - diff --git a/packages/taler-wallet-webextension/src/wxApi.ts b/packages/taler-wallet-webextension/src/wxApi.ts index db440e913..60ad26e7f 100644 --- a/packages/taler-wallet-webextension/src/wxApi.ts +++ b/packages/taler-wallet-webextension/src/wxApi.ts @@ -190,6 +190,15 @@ export function syncAllProviders(): Promise { return callBackend("runBackupCycle", {}) } +export function syncOneProvider(url: string): Promise { + return callBackend("runBackupCycle", { providers: [url] }) +} +export function removeProvider(url: string): Promise { + return callBackend("removeBackupProvider", { provider: url }) +} +export function extendedProvider(url: string): Promise { + return callBackend("extendBackupProvider", { provider: url }) +} /** * Retry a transaction -- cgit v1.2.3