adding tos information in settings and return to manual withdraw when adding an exchange

This commit is contained in:
Sebastian 2021-11-24 08:57:26 -03:00
parent f07436aa49
commit 0bfd4523b3
No known key found for this signature in database
GPG Key ID: BE4FF68352439FC1
14 changed files with 223 additions and 240 deletions

View File

@ -613,6 +613,14 @@ export const LightText = styled.div`
color: gray; color: gray;
`; `;
export const SuccessText = styled.div`
color: #388e3c;
`;
export const DestructiveText = styled.div`
color: rgb(202, 60, 60);
`;
export const WarningText = styled.div` export const WarningText = styled.div`
color: rgb(223, 117, 20); color: rgb(223, 117, 20);
`; `;

View File

@ -8,6 +8,7 @@ import {
LinkSuccess, LinkSuccess,
TermsOfService, TermsOfService,
WarningBox, WarningBox,
WarningText,
} from "../components/styled"; } from "../components/styled";
import { TermsState } from "../utils"; import { TermsState } from "../utils";
@ -28,10 +29,27 @@ export function TermsOfServiceSection({
if (!reviewing) { if (!reviewing) {
if (!reviewed) { if (!reviewed) {
if (!onReview) { if (!onReview) {
return <section>Terms of service status: {terms.status}</section>; return (
<Fragment>
{terms.status === "notfound" && (
<section>
<WarningText>
{i18n.str`Exchange doesn't have terms of service`}
</WarningText>
</section>
)}
</Fragment>
);
} }
return ( return (
<Fragment> <Fragment>
{terms.status === "notfound" && (
<section>
<WarningText>
{i18n.str`Exchange doesn't have terms of service`}
</WarningText>
</section>
)}
{terms.status === "new" && ( {terms.status === "new" && (
<section> <section>
<ButtonSuccess upperCased onClick={() => onReview(true)}> <ButtonSuccess upperCased onClick={() => onReview(true)}>
@ -64,7 +82,6 @@ export function TermsOfServiceSection({
enabled={reviewed} enabled={reviewed}
label={i18n.str`I accept the exchange terms of service`} label={i18n.str`I accept the exchange terms of service`}
onToggle={() => { onToggle={() => {
console.log("asdasd", reviewed);
onAccept(!reviewed); onAccept(!reviewed);
if (onReview) onReview(false); if (onReview) onReview(false);
}} }}

View File

@ -19,7 +19,7 @@
* @author Sebastian Javier Marchano (sebasjm) * @author Sebastian Javier Marchano (sebasjm)
*/ */
import { amountFractionalBase } from "@gnu-taler/taler-util"; import { amountFractionalBase, ExchangeListItem } from "@gnu-taler/taler-util";
import { createExample } from "../test-utils"; import { createExample } from "../test-utils";
import { termsHtml, termsPdf, termsPlain, termsXml } from "./termsExample"; import { termsHtml, termsPdf, termsPlain, termsXml } from "./termsExample";
import { View as TestedComponent } from "./Withdraw"; import { View as TestedComponent } from "./Withdraw";
@ -32,24 +32,38 @@ export default {
}, },
}; };
const exchangeList: ExchangeListItem[] = [
{
currency: "USD",
exchangeBaseUrl: "exchange.demo.taler.net",
tos: {
currentVersion: "1",
acceptedVersion: "1",
content: "terms of service content",
contentType: "text/plain",
},
paytoUris: ["asd"],
},
{
currency: "USD",
exchangeBaseUrl: "exchange.test.taler.net",
tos: {
currentVersion: "1",
acceptedVersion: "1",
content: "terms of service content",
contentType: "text/plain",
},
paytoUris: ["asd"],
},
];
export const NewTerms = createExample(TestedComponent, { export const NewTerms = createExample(TestedComponent, {
knownExchanges: [ knownExchanges: exchangeList,
{
currency: "USD",
exchangeBaseUrl: "exchange.demo.taler.net",
paytoUris: ["asd"],
},
{
currency: "USD",
exchangeBaseUrl: "exchange.test.taler.net",
paytoUris: ["asd"],
},
],
exchangeBaseUrl: "exchange.demo.taler.net", exchangeBaseUrl: "exchange.demo.taler.net",
withdrawalFee: { withdrawalFee: {
currency: "USD", currency: "USD",
fraction: 0, fraction: 0,
value: 0, value: 1,
}, },
amount: { amount: {
currency: "USD", currency: "USD",
@ -71,18 +85,7 @@ export const NewTerms = createExample(TestedComponent, {
}); });
export const TermsReviewingPLAIN = createExample(TestedComponent, { export const TermsReviewingPLAIN = createExample(TestedComponent, {
knownExchanges: [ knownExchanges: exchangeList,
{
currency: "USD",
exchangeBaseUrl: "exchange.demo.taler.net",
paytoUris: ["asd"],
},
{
currency: "USD",
exchangeBaseUrl: "exchange.test.taler.net",
paytoUris: ["asd"],
},
],
exchangeBaseUrl: "exchange.demo.taler.net", exchangeBaseUrl: "exchange.demo.taler.net",
withdrawalFee: { withdrawalFee: {
currency: "USD", currency: "USD",
@ -110,18 +113,7 @@ export const TermsReviewingPLAIN = createExample(TestedComponent, {
}); });
export const TermsReviewingHTML = createExample(TestedComponent, { export const TermsReviewingHTML = createExample(TestedComponent, {
knownExchanges: [ knownExchanges: exchangeList,
{
currency: "USD",
exchangeBaseUrl: "exchange.demo.taler.net",
paytoUris: ["asd"],
},
{
currency: "USD",
exchangeBaseUrl: "exchange.test.taler.net",
paytoUris: ["asd"],
},
],
exchangeBaseUrl: "exchange.demo.taler.net", exchangeBaseUrl: "exchange.demo.taler.net",
withdrawalFee: { withdrawalFee: {
currency: "USD", currency: "USD",
@ -151,18 +143,7 @@ export const TermsReviewingHTML = createExample(TestedComponent, {
}); });
export const TermsReviewingPDF = createExample(TestedComponent, { export const TermsReviewingPDF = createExample(TestedComponent, {
knownExchanges: [ knownExchanges: exchangeList,
{
currency: "USD",
exchangeBaseUrl: "exchange.demo.taler.net",
paytoUris: ["asd"],
},
{
currency: "USD",
exchangeBaseUrl: "exchange.test.taler.net",
paytoUris: ["asd"],
},
],
exchangeBaseUrl: "exchange.demo.taler.net", exchangeBaseUrl: "exchange.demo.taler.net",
withdrawalFee: { withdrawalFee: {
currency: "USD", currency: "USD",
@ -192,18 +173,7 @@ export const TermsReviewingPDF = createExample(TestedComponent, {
}); });
export const TermsReviewingXML = createExample(TestedComponent, { export const TermsReviewingXML = createExample(TestedComponent, {
knownExchanges: [ knownExchanges: exchangeList,
{
currency: "USD",
exchangeBaseUrl: "exchange.demo.taler.net",
paytoUris: ["asd"],
},
{
currency: "USD",
exchangeBaseUrl: "exchange.test.taler.net",
paytoUris: ["asd"],
},
],
exchangeBaseUrl: "exchange.demo.taler.net", exchangeBaseUrl: "exchange.demo.taler.net",
withdrawalFee: { withdrawalFee: {
currency: "USD", currency: "USD",
@ -231,18 +201,7 @@ export const TermsReviewingXML = createExample(TestedComponent, {
}); });
export const NewTermsAccepted = createExample(TestedComponent, { export const NewTermsAccepted = createExample(TestedComponent, {
knownExchanges: [ knownExchanges: exchangeList,
{
currency: "USD",
exchangeBaseUrl: "exchange.demo.taler.net",
paytoUris: ["asd"],
},
{
currency: "USD",
exchangeBaseUrl: "exchange.test.taler.net",
paytoUris: ["asd"],
},
],
exchangeBaseUrl: "exchange.demo.taler.net", exchangeBaseUrl: "exchange.demo.taler.net",
withdrawalFee: { withdrawalFee: {
currency: "USD", currency: "USD",
@ -269,18 +228,7 @@ export const NewTermsAccepted = createExample(TestedComponent, {
}); });
export const TermsShowAgainXML = createExample(TestedComponent, { export const TermsShowAgainXML = createExample(TestedComponent, {
knownExchanges: [ knownExchanges: exchangeList,
{
currency: "USD",
exchangeBaseUrl: "exchange.demo.taler.net",
paytoUris: ["asd"],
},
{
currency: "USD",
exchangeBaseUrl: "exchange.test.taler.net",
paytoUris: ["asd"],
},
],
exchangeBaseUrl: "exchange.demo.taler.net", exchangeBaseUrl: "exchange.demo.taler.net",
withdrawalFee: { withdrawalFee: {
currency: "USD", currency: "USD",
@ -309,18 +257,7 @@ export const TermsShowAgainXML = createExample(TestedComponent, {
}); });
export const TermsChanged = createExample(TestedComponent, { export const TermsChanged = createExample(TestedComponent, {
knownExchanges: [ knownExchanges: exchangeList,
{
currency: "USD",
exchangeBaseUrl: "exchange.demo.taler.net",
paytoUris: ["asd"],
},
{
currency: "USD",
exchangeBaseUrl: "exchange.test.taler.net",
paytoUris: ["asd"],
},
],
exchangeBaseUrl: "exchange.demo.taler.net", exchangeBaseUrl: "exchange.demo.taler.net",
withdrawalFee: { withdrawalFee: {
currency: "USD", currency: "USD",
@ -347,18 +284,7 @@ export const TermsChanged = createExample(TestedComponent, {
}); });
export const TermsNotFound = createExample(TestedComponent, { export const TermsNotFound = createExample(TestedComponent, {
knownExchanges: [ knownExchanges: exchangeList,
{
currency: "USD",
exchangeBaseUrl: "exchange.demo.taler.net",
paytoUris: ["asd"],
},
{
currency: "USD",
exchangeBaseUrl: "exchange.test.taler.net",
paytoUris: ["asd"],
},
],
exchangeBaseUrl: "exchange.demo.taler.net", exchangeBaseUrl: "exchange.demo.taler.net",
withdrawalFee: { withdrawalFee: {
currency: "USD", currency: "USD",
@ -382,18 +308,7 @@ export const TermsNotFound = createExample(TestedComponent, {
}); });
export const TermsAlreadyAccepted = createExample(TestedComponent, { export const TermsAlreadyAccepted = createExample(TestedComponent, {
knownExchanges: [ knownExchanges: exchangeList,
{
currency: "USD",
exchangeBaseUrl: "exchange.demo.taler.net",
paytoUris: ["asd"],
},
{
currency: "USD",
exchangeBaseUrl: "exchange.test.taler.net",
paytoUris: ["asd"],
},
],
exchangeBaseUrl: "exchange.demo.taler.net", exchangeBaseUrl: "exchange.demo.taler.net",
withdrawalFee: { withdrawalFee: {
currency: "USD", currency: "USD",
@ -417,18 +332,7 @@ export const TermsAlreadyAccepted = createExample(TestedComponent, {
}); });
export const WithoutFee = createExample(TestedComponent, { export const WithoutFee = createExample(TestedComponent, {
knownExchanges: [ knownExchanges: exchangeList,
{
currency: "USD",
exchangeBaseUrl: "exchange.demo.taler.net",
paytoUris: ["asd"],
},
{
currency: "USD",
exchangeBaseUrl: "exchange.test.taler.net",
paytoUris: ["asd"],
},
],
exchangeBaseUrl: "exchange.demo.taler.net", exchangeBaseUrl: "exchange.demo.taler.net",
withdrawalFee: { withdrawalFee: {
currency: "USD", currency: "USD",

View File

@ -38,7 +38,6 @@ import {
ButtonWarning, ButtonWarning,
LinkSuccess, LinkSuccess,
WalletAction, WalletAction,
WarningText,
} from "../components/styled"; } from "../components/styled";
import { useAsyncAsHook } from "../hooks/useAsyncAsHook"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
import { amountToString, buildTermsOfServiceState, TermsState } from "../utils"; import { amountToString, buildTermsOfServiceState, TermsState } from "../utils";
@ -98,17 +97,19 @@ export function View({
text={amountToString(Amounts.sub(amount, withdrawalFee).amount)} text={amountToString(Amounts.sub(amount, withdrawalFee).amount)}
kind="positive" kind="positive"
/> />
<Part
title="Chosen amount"
text={amountToString(amount)}
kind="neutral"
/>
{Amounts.isNonZero(withdrawalFee) && ( {Amounts.isNonZero(withdrawalFee) && (
<Part <Fragment>
title="Exchange fee" <Part
text={amountToString(withdrawalFee)} title="Chosen amount"
kind="negative" text={amountToString(amount)}
/> kind="neutral"
/>
<Part
title="Exchange fee"
text={amountToString(withdrawalFee)}
kind="negative"
/>
</Fragment>
)} )}
{exchangeBaseUrl && ( {exchangeBaseUrl && (
<Part title="Exchange" text={exchangeBaseUrl} kind="neutral" big /> <Part title="Exchange" text={exchangeBaseUrl} kind="neutral" big />
@ -140,13 +141,6 @@ export function View({
)} )}
</section> </section>
)} )}
{terms.status === "notfound" && (
<section>
<WarningText>
{i18n.str`Exchange doesn't have terms of service`}
</WarningText>
</section>
)}
<TermsOfServiceSection <TermsOfServiceSection
reviewed={reviewed} reviewed={reviewed}
reviewing={reviewing} reviewing={reviewing}

View File

@ -17,19 +17,15 @@
import { i18n } from "@gnu-taler/taler-util"; import { i18n } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { Checkbox } from "../components/Checkbox"; import { Checkbox } from "../components/Checkbox";
import { useDevContext } from "../context/devContext";
import { useExtendedPermissions } from "../hooks/useExtendedPermissions"; import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
export function SettingsPage(): VNode { export function SettingsPage(): VNode {
const [permissionsEnabled, togglePermissions] = useExtendedPermissions(); const [permissionsEnabled, togglePermissions] = useExtendedPermissions();
const { devMode, toggleDevMode } = useDevContext();
return ( return (
<SettingsView <SettingsView
permissionsEnabled={permissionsEnabled} permissionsEnabled={permissionsEnabled}
togglePermissions={togglePermissions} togglePermissions={togglePermissions}
developerMode={devMode}
toggleDeveloperMode={toggleDevMode}
/> />
); );
} }
@ -37,15 +33,11 @@ export function SettingsPage(): VNode {
export interface ViewProps { export interface ViewProps {
permissionsEnabled: boolean; permissionsEnabled: boolean;
togglePermissions: () => void; togglePermissions: () => void;
developerMode: boolean;
toggleDeveloperMode: () => void;
} }
export function SettingsView({ export function SettingsView({
permissionsEnabled, permissionsEnabled,
togglePermissions, togglePermissions,
developerMode,
toggleDeveloperMode,
}: ViewProps): VNode { }: ViewProps): VNode {
return ( return (
<Fragment> <Fragment>
@ -60,14 +52,6 @@ export function SettingsView({
enabled={permissionsEnabled} enabled={permissionsEnabled}
onToggle={togglePermissions} onToggle={togglePermissions}
/> />
<h2>Config</h2>
<Checkbox
label="Developer mode"
name="devMode"
description="(More options and information useful for debugging)"
enabled={developerMode}
onToggle={toggleDeveloperMode}
/>
</section> </section>
<footer style={{ justifyContent: "space-around" }}> <footer style={{ justifyContent: "space-around" }}>
<a <a

View File

@ -60,15 +60,19 @@ export function buildTermsOfServiceState(tos: GetExchangeTosResult): TermsState
tos.content, tos.content,
); );
const status: TermsStatus = !content const status: TermsStatus = buildTermsOfServiceStatus(tos.content, tos.acceptedEtag, tos.currentEtag);
? "notfound"
: !tos.acceptedEtag
? "new"
: tos.acceptedEtag !== tos.currentEtag
? "changed"
: "accepted";
return { content, status, version: tos.currentEtag } return { content, status, version: tos.currentEtag }
}
export function buildTermsOfServiceStatus(content: string | undefined, acceptedVersion: string | undefined, currentVersion: string | undefined): TermsStatus {
return !content
? "notfound"
: !acceptedVersion
? "new"
: acceptedVersion !== currentVersion
? "changed"
: "accepted";
} }
function parseTermsOfServiceContent( function parseTermsOfServiceContent(

View File

@ -21,7 +21,6 @@
import { AmountJson, Amounts, i18n } from "@gnu-taler/taler-util"; import { AmountJson, Amounts, i18n } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { route } from "preact-router";
import { useState } from "preact/hooks"; import { useState } from "preact/hooks";
import { ErrorMessage } from "../components/ErrorMessage"; import { ErrorMessage } from "../components/ErrorMessage";
import { SelectList } from "../components/SelectList"; import { SelectList } from "../components/SelectList";
@ -35,13 +34,13 @@ import {
LightText, LightText,
LinkPrimary, LinkPrimary,
} from "../components/styled"; } from "../components/styled";
import { Pages } from "../NavigationBar";
export interface Props { export interface Props {
error: string | undefined; error: string | undefined;
initialAmount?: string; initialAmount?: string;
exchangeList: Record<string, string>; exchangeList: Record<string, string>;
onCreate: (exchangeBaseUrl: string, amount: AmountJson) => Promise<void>; onCreate: (exchangeBaseUrl: string, amount: AmountJson) => Promise<void>;
onAddExchange: () => void;
} }
export function CreateManualWithdraw({ export function CreateManualWithdraw({
@ -49,6 +48,7 @@ export function CreateManualWithdraw({
exchangeList, exchangeList,
error, error,
onCreate, onCreate,
onAddExchange,
}: Props): VNode { }: Props): VNode {
const exchangeSelectList = Object.keys(exchangeList); const exchangeSelectList = Object.keys(exchangeList);
const currencySelectList = Object.values(exchangeList); const currencySelectList = Object.values(exchangeList);
@ -90,7 +90,7 @@ export function CreateManualWithdraw({
return ( return (
<Centered style={{ marginTop: 100 }}> <Centered style={{ marginTop: 100 }}>
<BoldLight>No exchange configured</BoldLight> <BoldLight>No exchange configured</BoldLight>
<ButtonSuccess onClick={() => route(Pages.exchange_add)}> <ButtonSuccess onClick={onAddExchange}>
<i18n.Translate>Add exchange</i18n.Translate> <i18n.Translate>Add exchange</i18n.Translate>
</ButtonSuccess> </ButtonSuccess>
</Centered> </Centered>
@ -130,10 +130,7 @@ export function CreateManualWithdraw({
/> />
</Input> </Input>
<div style={{ display: "flex", justifyContent: "space-between" }}> <div style={{ display: "flex", justifyContent: "space-between" }}>
<LinkPrimary <LinkPrimary onClick={onAddExchange} style={{ marginLeft: "auto" }}>
onClick={() => route(Pages.exchange_add)}
style={{ marginLeft: "auto" }}
>
<i18n.Translate>Add exchange</i18n.Translate> <i18n.Translate>Add exchange</i18n.Translate>
</LinkPrimary> </LinkPrimary>
</div> </div>

View File

@ -5,7 +5,6 @@ import {
Button, Button,
ButtonSuccess, ButtonSuccess,
ButtonWarning, ButtonWarning,
WarningBox,
} from "../components/styled/index"; } from "../components/styled/index";
import { TermsOfServiceSection } from "../cta/TermsOfServiceSection"; import { TermsOfServiceSection } from "../cta/TermsOfServiceSection";
import { useAsyncAsHook } from "../hooks/useAsyncAsHook"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
@ -97,14 +96,6 @@ export function View({
</a> </a>
</div> </div>
</section> </section>
{terms && terms.status === "notfound" && (
<section>
<WarningBox>
{i18n.str`Exchange doesn't have terms of service`}
</WarningBox>
</section>
)}
{terms && ( {terms && (
<TermsOfServiceSection <TermsOfServiceSection
reviewed={reviewed} reviewed={reviewed}

View File

@ -27,7 +27,7 @@ import { ExchangeAddConfirmPage } from "./ExchangeAddConfirm";
import { ExchangeSetUrlPage } from "./ExchangeSetUrl"; import { ExchangeSetUrlPage } from "./ExchangeSetUrl";
interface Props { interface Props {
currency: string; currency?: string;
onBack: () => void; onBack: () => void;
} }

View File

@ -55,6 +55,12 @@ export const WithDemoAsKnownExchange = createExample(TestedComponent, {
{ {
currency: "TESTKUDOS", currency: "TESTKUDOS",
exchangeBaseUrl: "https://exchange.demo.taler.net/", exchangeBaseUrl: "https://exchange.demo.taler.net/",
tos: {
currentVersion: "1",
acceptedVersion: "1",
content: "content of tos",
contentType: "text/plain",
},
paytoUris: [], paytoUris: [],
}, },
], ],

View File

@ -22,11 +22,13 @@ import {
AcceptManualWithdrawalResult, AcceptManualWithdrawalResult,
AmountJson, AmountJson,
Amounts, Amounts,
NotificationType,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { ReserveCreated } from "./ReserveCreated"; import { ReserveCreated } from "./ReserveCreated";
import { route } from "preact-router"; import { route } from "preact-router";
import { Pages } from "../NavigationBar"; import { Pages } from "../NavigationBar";
import { useAsyncAsHook } from "../hooks/useAsyncAsHook"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
import { ExchangeAddPage } from "./ExchangeAddPage";
export function ManualWithdrawPage(): VNode { export function ManualWithdrawPage(): VNode {
const [success, setSuccess] = useState< const [success, setSuccess] = useState<
@ -39,7 +41,9 @@ export function ManualWithdrawPage(): VNode {
>(undefined); >(undefined);
const [error, setError] = useState<string | undefined>(undefined); const [error, setError] = useState<string | undefined>(undefined);
const state = useAsyncAsHook(() => wxApi.listExchanges()); const state = useAsyncAsHook(wxApi.listExchanges, [
NotificationType.ExchangeAdded,
]);
async function doCreate( async function doCreate(
exchangeBaseUrl: string, exchangeBaseUrl: string,
@ -61,6 +65,12 @@ export function ManualWithdrawPage(): VNode {
} }
} }
const [addingExchange, setAddingExchange] = useState(false);
if (addingExchange) {
return <ExchangeAddPage onBack={() => setAddingExchange(false)} />;
}
if (success) { if (success) {
return ( return (
<ReserveCreated <ReserveCreated
@ -91,6 +101,7 @@ export function ManualWithdrawPage(): VNode {
return ( return (
<CreateManualWithdraw <CreateManualWithdraw
onAddExchange={() => setAddingExchange(true)}
error={error} error={error}
exchangeList={exchangeList} exchangeList={exchangeList}
onCreate={doCreate} onCreate={doCreate}

View File

@ -49,6 +49,52 @@ export const WithOneExchange = createExample(TestedComponent, {
{ {
currency: "USD", currency: "USD",
exchangeBaseUrl: "http://exchange.taler", exchangeBaseUrl: "http://exchange.taler",
tos: {
currentVersion: "1",
acceptedVersion: "1",
content: "content of tos",
contentType: "text/plain",
},
paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"],
},
],
});
export const WithExchangeInDifferentState = createExample(TestedComponent, {
deviceName: "this-is-the-device-name",
permissionsEnabled: true,
setDeviceName: () => Promise.resolve(),
knownExchanges: [
{
currency: "USD",
exchangeBaseUrl: "http://exchange1.taler",
tos: {
currentVersion: "1",
acceptedVersion: "1",
content: "content of tos",
contentType: "text/plain",
},
paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"],
},
{
currency: "USD",
exchangeBaseUrl: "http://exchange2.taler",
tos: {
currentVersion: "2",
acceptedVersion: "1",
content: "content of tos",
contentType: "text/plain",
},
paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"],
},
{
currency: "USD",
exchangeBaseUrl: "http://exchange3.taler",
tos: {
currentVersion: "1",
content: "content of tos",
contentType: "text/plain",
},
paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"], paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"],
}, },
], ],

View File

@ -17,14 +17,19 @@
import { ExchangeListItem, i18n } from "@gnu-taler/taler-util"; import { ExchangeListItem, i18n } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { Checkbox } from "../components/Checkbox"; import { Checkbox } from "../components/Checkbox";
import { LinkPrimary } from "../components/styled"; import {
DestructiveText,
LinkPrimary,
SuccessText,
WarningText,
} from "../components/styled";
import { useDevContext } from "../context/devContext"; import { useDevContext } from "../context/devContext";
import { useAsyncAsHook } from "../hooks/useAsyncAsHook"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
import { useBackupDeviceName } from "../hooks/useBackupDeviceName"; import { useBackupDeviceName } from "../hooks/useBackupDeviceName";
import { useExtendedPermissions } from "../hooks/useExtendedPermissions"; import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
import { useLang } from "../hooks/useLang"; import { useLang } from "../hooks/useLang";
import { Pages } from "../NavigationBar"; import { Pages } from "../NavigationBar";
// import { strings as messages } from "../i18n/strings"; import { buildTermsOfServiceStatus } from "../utils";
import * as wxApi from "../wxApi"; import * as wxApi from "../wxApi";
export function SettingsPage(): VNode { export function SettingsPage(): VNode {
@ -65,25 +70,8 @@ export interface ViewProps {
knownExchanges: Array<ExchangeListItem>; knownExchanges: Array<ExchangeListItem>;
} }
// type LangsNames = {
// [P in keyof typeof messages]: string;
// };
// const names: LangsNames = {
// es: "Español [es]",
// en: "English [en]",
// fr: "Français [fr]",
// de: "Deutsch [de]",
// sv: "Svenska [sv]",
// it: "Italiano [it]",
// };
export function SettingsView({ export function SettingsView({
knownExchanges, knownExchanges,
// lang,
// changeLang,
// deviceName,
// setDeviceName,
permissionsEnabled, permissionsEnabled,
togglePermissions, togglePermissions,
developerMode, developerMode,
@ -92,30 +80,6 @@ export function SettingsView({
return ( return (
<Fragment> <Fragment>
<section> <section>
<h2>
<i18n.Translate>Known exchanges</i18n.Translate>
</h2>
{!knownExchanges || !knownExchanges.length ? (
<div>No exchange yet!</div>
) : (
<Fragment>
<table>
{knownExchanges.map((e, idx) => (
<tr key={idx}>
<td>{e.currency}</td>
<td>
<a href={e.exchangeBaseUrl}>{e.exchangeBaseUrl}</a>
</td>
</tr>
))}
</table>
</Fragment>
)}
<div style={{ display: "flex", justifyContent: "space-between" }}>
<div />
<LinkPrimary href={Pages.exchange_add}>Add an exchange</LinkPrimary>
</div>
<h2> <h2>
<i18n.Translate>Permissions</i18n.Translate> <i18n.Translate>Permissions</i18n.Translate>
</h2> </h2>
@ -126,6 +90,61 @@ export function SettingsView({
enabled={permissionsEnabled} enabled={permissionsEnabled}
onToggle={togglePermissions} onToggle={togglePermissions}
/> />
<h2>
<i18n.Translate>Known exchanges</i18n.Translate>
</h2>
{!knownExchanges || !knownExchanges.length ? (
<div>No exchange yet!</div>
) : (
<Fragment>
<table>
<thead>
<tr>
<th>currency</th>
<th>url</th>
<th>term of service</th>
</tr>
</thead>
<tbody>
{knownExchanges.map((e, idx) => {
function Status(): VNode {
const status = buildTermsOfServiceStatus(
e.tos.content,
e.tos.acceptedVersion,
e.tos.currentVersion,
);
switch (status) {
case "accepted":
return <SuccessText>ok</SuccessText>;
case "changed":
return <WarningText>changed!</WarningText>;
case "new":
case "notfound":
return <DestructiveText>not accepted</DestructiveText>;
}
}
return (
<tr key={idx}>
<td>{e.currency}</td>
<td>
<a href={e.exchangeBaseUrl}>{e.exchangeBaseUrl}</a>
</td>
<td>
<Status />
</td>
</tr>
);
})}
</tbody>
</table>
</Fragment>
)}
<div style={{ display: "flex", justifyContent: "space-between" }}>
<div />
<LinkPrimary href={Pages.exchange_add}>Add an exchange</LinkPrimary>
</div>
<h2>Config</h2> <h2>Config</h2>
<Checkbox <Checkbox
label="Developer mode" label="Developer mode"

View File

@ -350,11 +350,13 @@ export function acceptTip(req: AcceptTipRequest): Promise<void> {
return callBackend("acceptTip", req); return callBackend("acceptTip", req);
} }
export function onUpdateNotification(messageType: Array<NotificationType>, doCallback: () => void): () => void { export function onUpdateNotification(messageTypes: Array<NotificationType>, doCallback: () => void): () => void {
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const port = chrome.runtime.connect({ name: "notifications" }); const port = chrome.runtime.connect({ name: "notifications" });
const listener = (message: MessageFromBackend): void => { const listener = (message: MessageFromBackend): void => {
if (messageType.includes(message.type)) { const shouldNotify = messageTypes.includes(message.type)
console.log("Notification arrived, should notify?", shouldNotify, message.type, messageTypes)
if (shouldNotify) {
doCallback(); doCallback();
} }
}; };