gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated (1c0cce3f -> 1527b6c5)


From: gnunet
Subject: [taler-wallet-core] branch master updated (1c0cce3f -> 1527b6c5)
Date: Mon, 12 Jul 2021 19:49:10 +0200

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a change to branch master
in repository wallet-core.

    from 1c0cce3f tolerate zero-value payments
     new 0cf52a28 styles for provider detail page
     new 1527b6c5 moved out function creation from render

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../.storybook/preview.js                          |  28 ++-
 .../src/components/ErrorMessage.tsx                |  19 ++
 .../src/components/styled/index.tsx                |  36 ++-
 .../src/popup/BackupPage.tsx                       |  25 ++-
 .../src/popup/ProviderAddPage.tsx                  |  46 +---
 .../src/popup/ProviderDetailPage.tsx               | 243 +++++++++------------
 6 files changed, 203 insertions(+), 194 deletions(-)
 create mode 100644 
packages/taler-wallet-webextension/src/components/ErrorMessage.tsx

diff --git a/packages/taler-wallet-webextension/.storybook/preview.js 
b/packages/taler-wallet-webextension/.storybook/preview.js
index 1c07ba40..0fda6ac0 100644
--- a/packages/taler-wallet-webextension/.storybook/preview.js
+++ b/packages/taler-wallet-webextension/.storybook/preview.js
@@ -52,8 +52,32 @@ export const decorators = [
   (Story, { kind }) => {
     if (kind.startsWith('popup')) {
       return <div class="popup-container">
-        <link key="1" rel="stylesheet" type="text/css" href="/style/pure.css" 
/>
-        <link key="2" rel="stylesheet" type="text/css" href="/style/popup.css" 
/>
+        <style>{`
+        html {
+          font-family: sans-serif; /* 1 */
+        }
+        body {
+          margin: 0;
+        }`}
+        </style>
+        <style>{`
+        html {
+        }
+        h1 {
+          font-size: 2em;
+        }
+        input {
+          font: inherit;
+        }
+        body {
+          margin: 0;
+          font-size: 100%;
+          padding: 0;
+          overflow: hidden;
+          background-color: #f8faf7;
+          font-family: Arial, Helvetica, sans-serif;
+        }`}
+        </style>
         <div style={{ padding: 8, width: 'calc(400px - 16px - 2px)', height: 
'calc(320px - 34px - 16px - 2px)', border: 'black solid 1px' }}>
           <Story />
         </div>
diff --git a/packages/taler-wallet-webextension/src/components/ErrorMessage.tsx 
b/packages/taler-wallet-webextension/src/components/ErrorMessage.tsx
new file mode 100644
index 00000000..6bbdd26d
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/components/ErrorMessage.tsx
@@ -0,0 +1,19 @@
+import { VNode } from "preact";
+import { useState } from "preact/hooks";
+import arrowDown from '../../static/img/chevron-down.svg';
+import { ErrorBox } from "./styled";
+
+export function ErrorMessage({ title, description }: { title?: string|VNode; 
description?: string; }) {
+  const [showErrorDetail, setShowErrorDetail] = useState(false);
+  if (!title)
+    return null;
+  return <ErrorBox>
+    <div>
+      <p>{title}</p>
+      { description && <button onClick={() => { setShowErrorDetail(v => !v); 
}}>
+        <img style={{ height: '1.5em' }} src={arrowDown} />
+      </button> }
+    </div>
+    {showErrorDetail && <p>{description}</p>}
+  </ErrorBox>;
+}
diff --git a/packages/taler-wallet-webextension/src/components/styled/index.tsx 
b/packages/taler-wallet-webextension/src/components/styled/index.tsx
index ffcafd70..434e3350 100644
--- a/packages/taler-wallet-webextension/src/components/styled/index.tsx
+++ b/packages/taler-wallet-webextension/src/components/styled/index.tsx
@@ -4,6 +4,13 @@ import type * as Linaria from '@linaria/core';
 
 import { styled } from '@linaria/react';
 
+export const PaymentStatus = styled.span<{color:string}>`
+  padding: 5px;
+  border-radius: 5px;
+  color: white;
+  background-color: ${p => p.color};
+`
+
 export const PopupBox = styled.div`
   height: calc(320px - 34px - 16px);
   display: flex;
@@ -11,23 +18,40 @@ export const PopupBox = styled.div`
   justify-content: space-between;
 
   & > section {
+    // this margin will send the section up when used with a header
+    margin-bottom: auto; 
     overflow: auto;
+
+    table td {
+      padding: 5px 10px;
+    }
+    table tr {
+      border-bottom: 1px solid black;
+      border-top: 1px solid black;
+    }
+  }
+
+  & > header {
+    flex-direction: row;
+    justify-content: space-between;
+    display: flex;
+    margin-bottom: 5px;
+
+    & > div {
+      align-self: center;
+    }
   }
 
   & > footer {
     padding-top: 5px;
     flex-direction: row;
-    justify-content: flex-end;
+    justify-content: space-between;
     display: flex;
-    & > button {
+    & button {
       margin-left: 5px;
     }
   }
 
-  & > section > h1 {
-    margin-top: 0.3em;
-    margin-bottom: 0.3em;
-  }
 `
 
 export const Button = styled.button`
diff --git a/packages/taler-wallet-webextension/src/popup/BackupPage.tsx 
b/packages/taler-wallet-webextension/src/popup/BackupPage.tsx
index 6e60acc7..c2067ad2 100644
--- a/packages/taler-wallet-webextension/src/popup/BackupPage.tsx
+++ b/packages/taler-wallet-webextension/src/popup/BackupPage.tsx
@@ -20,8 +20,8 @@ import { ProviderInfo, ProviderPaymentStatus } from 
"@gnu-taler/taler-wallet-cor
 import { differenceInMonths, formatDuration, intervalToDuration } from 
"date-fns";
 import { FunctionalComponent, Fragment, JSX, VNode, AnyComponent } from 
"preact";
 import {
-  BoldLight, ButtonPrimary, ButtonSuccess, Centered, 
-  CenteredText, CenteredTextBold, PopupBox, Row, 
+  BoldLight, ButtonPrimary, ButtonSuccess, Centered,
+  CenteredText, CenteredTextBold, PopupBox, Row,
   SmallText, SmallTextLight
 } from "../components/styled";
 import { useBackupStatus } from "../hooks/useBackupStatus";
@@ -47,7 +47,7 @@ export interface ViewProps {
 
 export function BackupView({ providers, onAddProvider, onSyncAll }: 
ViewProps): VNode {
   return (
-    <PopupBox style={{ justifyContent: !providers.length ? 'center' : 
'space-between' }}>
+    <PopupBox>
       <section>
         {providers.map((provider) => <BackupLayout
           status={provider.paymentStatus}
@@ -57,18 +57,21 @@ export function BackupView({ providers, onAddProvider, 
onSyncAll }: ViewProps):
           title={provider.syncProviderBaseUrl}
         />
         )}
-        {!providers.length && <Centered>
+        {!providers.length && <Centered style={{marginTop: 100}}>
           <BoldLight>No backup providers configured</BoldLight>
           <ButtonSuccess onClick={onAddProvider}><i18n.Translate>Add 
provider</i18n.Translate></ButtonSuccess>
         </Centered>}
       </section>
       {!!providers.length && <footer>
-        <ButtonPrimary onClick={onSyncAll}>{
-          providers.length > 1 ?
-            <i18n.Translate>Sync all backups</i18n.Translate> :
-            <i18n.Translate>Sync now</i18n.Translate>
-        }</ButtonPrimary>
-        <ButtonSuccess onClick={onAddProvider}>Add provider</ButtonSuccess>
+        <div />
+        <div>
+          <ButtonPrimary onClick={onSyncAll}>{
+            providers.length > 1 ?
+              <i18n.Translate>Sync all backups</i18n.Translate> :
+              <i18n.Translate>Sync now</i18n.Translate>
+          }</ButtonPrimary>
+          <ButtonSuccess onClick={onAddProvider}>Add provider</ButtonSuccess>
+        </div>
       </footer>}
     </PopupBox>
   )
@@ -111,7 +114,7 @@ function BackupLayout(props: TransactionLayoutProps): 
JSX.Element {
 function ExpirationText({ until }: { until: Timestamp }) {
   return <Fragment>
     <CenteredText> Expires in </CenteredText>
-    <CenteredTextBold {...({color:colorByTimeToExpire(until)})}> 
{daysUntil(until)} </CenteredTextBold>
+    <CenteredTextBold {...({ color: colorByTimeToExpire(until) })}> 
{daysUntil(until)} </CenteredTextBold>
   </Fragment>
 }
 
diff --git a/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx 
b/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx
index 4b5da05f..92579e36 100644
--- a/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx
+++ b/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx
@@ -1,6 +1,9 @@
 import { Amounts, BackupBackupProviderTerms, i18n } from 
"@gnu-taler/taler-util";
-import { Fragment, VNode } from "preact";
+import { VNode } from "preact";
 import { useState } from "preact/hooks";
+import { Checkbox } from "../components/Checkbox";
+import { ErrorMessage } from "../components/ErrorMessage";
+import { Button, ButtonPrimary, Input, LightText, PopupBox, SmallTextLight } 
from "../components/styled/index";
 import * as wxApi from "../wxApi";
 
 interface Props {
@@ -49,26 +52,6 @@ export function ProviderAddPage({ onBack }: Props): VNode {
   />
 }
 
-interface TermsOfServiceProps {
-  onCancel: () => void;
-  onAccept: () => void;
-}
-
-function TermsOfService({ onCancel, onAccept }: TermsOfServiceProps) {
-  return <div style={{ display: 'flex', flexDirection: 'column' }}>
-    <section style={{ height: 'calc(320px - 34px - 34px - 16px)', overflow: 
'auto' }}>
-      <div>
-        Here we will place the complete text of terms of service
-      </div>
-    </section>
-    <footer style={{ marginTop: 'auto', display: 'flex', flexShrink: 0 }}>
-      <button class="pure-button" 
onClick={onCancel}><i18n.Translate>cancel</i18n.Translate></button>
-      <div style={{ width: '100%', flexDirection: 'row', justifyContent: 
'flex-end', display: 'flex' }}>
-        <button class="pure-button" 
onClick={onAccept}><i18n.Translate>accept</i18n.Translate></button>
-      </div>
-    </footer>
-  </div>
-}
 
 export interface SetUrlViewProps {
   initialValue?: string;
@@ -76,23 +59,6 @@ export interface SetUrlViewProps {
   onVerify: (s: string) => Promise<string | undefined>;
   withError?: string;
 }
-import arrowDown from '../../static/img/chevron-down.svg';
-import { Button, ButtonPrimary, ErrorBox, Input, LightText, PopupBox, 
SmallTextLight } from "../components/styled/index";
-import { Checkbox } from "../components/Checkbox";
-
-function ErrorMessage({ title, description }: { title?: string, description?: 
string }) {
-  const [showErrorDetail, setShowErrorDetail] = useState(false);
-  if (!title) return null
-  return <ErrorBox>
-    <div>
-      <p>{title}</p>
-      <button onClick={() => { setShowErrorDetail(v => !v) }} >
-        <img style={{ height: '1.5em' }} src={arrowDown} />
-      </button>
-    </div>
-    {showErrorDetail && <p>{description}</p>}
-  </ErrorBox>
-}
 
 export function SetUrlView({ initialValue, onCancel, onVerify, withError }: 
SetUrlViewProps) {
   const [value, setValue] = useState<string>(initialValue || "")
@@ -113,7 +79,7 @@ export function SetUrlView({ initialValue, onCancel, 
onVerify, withError }: SetU
         </Input>
       </p>
     </section>
-    <footer style={{ justifyContent: 'space-between' }}>
+    <footer>
       <Button onClick={onCancel}><i18n.Translate> &lt; 
Back</i18n.Translate></Button>
       <ButtonPrimary
         disabled={!value}
@@ -150,7 +116,7 @@ export function ConfirmProviderView({ url, provider, 
onCancel, onConfirm }: Conf
       </p>
       <Checkbox label="Accept terms of service" name="terms" onToggle={() => 
setAccepted(old => !old)} enabled={accepted}/>
     </section>
-    <footer style={{ justifyContent: 'space-between' }}>
+    <footer>
       <Button onClick={onCancel}><i18n.Translate> &lt; 
Back</i18n.Translate></Button>
       <ButtonPrimary
         disabled={!accepted}
diff --git 
a/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx 
b/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx
index 0d48ab07..12567c2c 100644
--- a/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx
+++ b/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx
@@ -19,6 +19,8 @@ import { i18n, Timestamp } from "@gnu-taler/taler-util";
 import { ProviderInfo, ProviderPaymentStatus, ProviderPaymentType } from 
"@gnu-taler/taler-wallet-core";
 import { format, formatDuration, intervalToDuration } from "date-fns";
 import { Fragment, VNode } from "preact";
+import { ErrorMessage } from "../components/ErrorMessage";
+import { Button, ButtonDestructive, ButtonPrimary, PaymentStatus, PopupBox } 
from "../components/styled";
 import { useProviderStatus } from "../hooks/useProviderStatus";
 
 interface Props {
@@ -52,142 +54,57 @@ export interface ViewProps {
 }
 
 export function ProviderView({ info, onDelete, onSync, onBack, onExtend }: 
ViewProps): VNode {
-  function Footer() {
-    return <footer style={{ marginTop: 'auto', display: 'flex', flexShrink: 0 
}}>
-      <button class="pure-button" 
onClick={onBack}><i18n.Translate>back</i18n.Translate></button>
-      <div style={{ width: '100%', flexDirection: 'row', justifyContent: 
'flex-end', display: 'flex' }}>
-        {info && <button class="pure-button button-destructive" disabled 
onClick={onDelete}><i18n.Translate>remove</i18n.Translate></button>}
-        {info && <button class="pure-button button-secondary" disabled 
style={{ marginLeft: 5 }} 
onClick={onExtend}><i18n.Translate>extend</i18n.Translate></button>}
-        {info && <button class="pure-button button-secondary" style={{ 
marginLeft: 5 }} onClick={onSync}><i18n.Translate>sync 
now</i18n.Translate></button>}
-      </div>
-    </footer>
-  }
-  function Error() {
-    if (info?.lastError) {
-      return <Fragment>
-        <div class="errorbox" style={{ marginTop: 10 }} >
-          <div style={{ height: 0, textAlign: 'right', color: 'gray', 
fontSize: 'small' }}>last time tried {!info.lastAttemptedBackupTimestamp || 
info.lastAttemptedBackupTimestamp.t_ms === 'never' ? 'never' : format(new 
Date(info.lastAttemptedBackupTimestamp.t_ms), 'dd/MM/yyyy HH:mm:ss')}</div>
-          <p>{info.lastError.hint}</p>
-        </div>
-      </Fragment>
-    }
-    if (info?.backupProblem) {
-      switch (info.backupProblem.type) {
-        case "backup-conflicting-device":
-          return <div class="errorbox" style={{ marginTop: 10 }}>
-            <p>There is conflict with another backup from 
<b>{info.backupProblem.otherDeviceId}</b></p>
-          </div>
-        case "backup-unreadable":
-          return <div class="errorbox" style={{ marginTop: 10 }}>
-            <p>Backup is not readable</p>
-          </div>
-        default:
-          return <div class="errorbox" style={{ marginTop: 10 }}>
-            <p>Unknown backup problem: {JSON.stringify(info.backupProblem)}</p>
-          </div>
-      }
-    }
-    return null
-  }
-  function colorByStatus(status: ProviderPaymentType | undefined) {
-    switch (status) {
-      case ProviderPaymentType.InsufficientBalance:
-        return 'rgb(223, 117, 20)'
-      case ProviderPaymentType.Unpaid:
-        return 'rgb(202, 60, 60)'
-      case ProviderPaymentType.Paid:
-        return 'rgb(28, 184, 65)'
-      case ProviderPaymentType.Pending:
-        return 'gray'
-      case ProviderPaymentType.InsufficientBalance:
-        return 'rgb(202, 60, 60)'
-      case ProviderPaymentType.TermsChanged:
-        return 'rgb(202, 60, 60)'
-      default:
-        break;
-    }
-    return undefined
-  }
-
-  function descriptionByStatus(status: ProviderPaymentStatus | undefined) {
-    if (!status) return ''
-    switch (status.type) {
-      case ProviderPaymentType.InsufficientBalance:
-        return 'no enough balance to make the payment'
-      case ProviderPaymentType.Unpaid:
-        return 'not pay yet'
-      case ProviderPaymentType.Paid:
-      case ProviderPaymentType.TermsChanged:
-        if (status.paidUntil.t_ms === 'never') {
-          return 'service paid.'
-        } else {
-          return `service paid until ${format(status.paidUntil.t_ms, 
'yyyy/MM/dd HH:mm:ss')}`
-        }
-      case ProviderPaymentType.Pending:
-        return ''
-      default:
-        break;
-    }
-    return undefined
-  }
-
   return (
-    <div style={{ height: 'calc(320px - 34px - 16px)', overflow: 'auto' }}>
-      <style>{`
-      table td {
-        padding: 5px 10px;
-      }
-      `}</style>
-      <div style={{ display: 'flex', flexDirection: 'column' }}>
-        <section style={{ flex: '1 0 auto', height: 'calc(320px - 34px - 34px 
- 16px)', overflow: 'auto' }}>
-          <span style={{ padding: 5, display: 'inline-block', backgroundColor: 
colorByStatus(info?.paymentStatus.type), borderRadius: 5, color: 'white' 
}}>{info?.paymentStatus.type}</span>
-          {/* {info && <span style={{ float: "right", fontSize: "small", 
color: "gray", padding: 5 }}>
-            From <b>{info.syncProviderBaseUrl}</b>
-          </span>} */}
-            {info && <div style={{ float: 'right', fontSize: "large", padding: 
5 }}>{info.terms?.annualFee} / year</div>}
-
-          <Error />
-
-          <h3>{info?.syncProviderBaseUrl}</h3>
-          <div style={{ display: "flex", flexDirection: "row", justifyContent: 
"space-between", }}>
-            <div>{daysSince(info?.lastSuccessfulBackupTimestamp)} </div>
-          </div>
-
-          <p>{descriptionByStatus(info?.paymentStatus)}</p>
-
-          {info?.paymentStatus.type === ProviderPaymentType.TermsChanged && 
<div>
-            <p>terms has changed, extending the service will imply accepting 
the new terms of service</p>
-            <table>
-              <thead>
-                <tr>
-                  <td></td>
-                  <td>old</td>
-                  <td> -&gt;</td>
-                  <td>new</td>
-                </tr>
-              </thead>
-              <tbody>
-
-                <tr>
-                  <td>fee</td>
-                  <td>{info.paymentStatus.oldTerms.annualFee}</td>
-                  <td>-&gt;</td>
-                  <td>{info.paymentStatus.newTerms.annualFee}</td>
-                </tr>
-                <tr>
-                  <td>storage</td>
-                  
<td>{info.paymentStatus.oldTerms.storageLimitInMegabytes}</td>
-                  <td>-&gt;</td>
-                  
<td>{info.paymentStatus.newTerms.storageLimitInMegabytes}</td>
-                </tr>
-              </tbody>
-            </table>
-          </div>}
-
-        </section>
-        <Footer />
-      </div>
-    </div>
+    <PopupBox>
+      <header>
+        <PaymentStatus 
color={colorByStatus(info.paymentStatus.type)}>{info.paymentStatus.type}</PaymentStatus>
+
+        {info.terms && <div>{info.terms.annualFee} / year</div>}
+      </header>
+      <section>
+        <Error info={info} />
+        <h3>{info.syncProviderBaseUrl}</h3>
+        <p>{daysSince(info?.lastSuccessfulBackupTimestamp)} </p>
+        <p>{descriptionByStatus(info.paymentStatus)}</p>
+        {info.paymentStatus.type === ProviderPaymentType.TermsChanged && <div>
+          <p>terms has changed, extending the service will imply accepting the 
new terms of service</p>
+          <table>
+            <thead>
+              <tr>
+                <td></td>
+                <td>old</td>
+                <td> -&gt;</td>
+                <td>new</td>
+              </tr>
+            </thead>
+            <tbody>
+
+              <tr>
+                <td>fee</td>
+                <td>{info.paymentStatus.oldTerms.annualFee}</td>
+                <td>-&gt;</td>
+                <td>{info.paymentStatus.newTerms.annualFee}</td>
+              </tr>
+              <tr>
+                <td>storage</td>
+                <td>{info.paymentStatus.oldTerms.storageLimitInMegabytes}</td>
+                <td>-&gt;</td>
+                <td>{info.paymentStatus.newTerms.storageLimitInMegabytes}</td>
+              </tr>
+            </tbody>
+          </table>
+        </div>}
+
+      </section>
+      <footer>
+        <Button onClick={onBack}><i18n.Translate> &lt; 
back</i18n.Translate></Button>
+        <div>
+          <ButtonDestructive disabled 
onClick={onDelete}><i18n.Translate>remove</i18n.Translate></ButtonDestructive>
+          <ButtonPrimary disabled 
onClick={onExtend}><i18n.Translate>extend</i18n.Translate></ButtonPrimary>
+          <ButtonPrimary onClick={onSync}><i18n.Translate>sync 
now</i18n.Translate></ButtonPrimary>
+        </div>
+      </footer>
+    </PopupBox>
   )
 }
 
@@ -213,3 +130,59 @@ function daysSince(d?: Timestamp) {
   })
   return `synced ${str} ago`
 }
+
+function Error({ info }: { info: ProviderInfo }) {
+  if (info.lastError) {
+    return <ErrorMessage title={info.lastError.hint} />
+  }
+  if (info.backupProblem) {
+    switch (info.backupProblem.type) {
+      case "backup-conflicting-device":
+        return <ErrorMessage title={<Fragment>
+          There is conflict with another backup from 
<b>{info.backupProblem.otherDeviceId}</b>
+        </Fragment>} />
+      case "backup-unreadable":
+        return <ErrorMessage title="Backup is not readable" />
+      default:
+        return <ErrorMessage title={<Fragment>
+          Unknown backup problem: {JSON.stringify(info.backupProblem)}
+        </Fragment>} />
+    }
+  }
+  return null
+}
+
+function colorByStatus(status: ProviderPaymentType) {
+  switch (status) {
+    case ProviderPaymentType.InsufficientBalance:
+      return 'rgb(223, 117, 20)'
+    case ProviderPaymentType.Unpaid:
+      return 'rgb(202, 60, 60)'
+    case ProviderPaymentType.Paid:
+      return 'rgb(28, 184, 65)'
+    case ProviderPaymentType.Pending:
+      return 'gray'
+    case ProviderPaymentType.InsufficientBalance:
+      return 'rgb(202, 60, 60)'
+    case ProviderPaymentType.TermsChanged:
+      return 'rgb(202, 60, 60)'
+  }
+}
+
+function descriptionByStatus(status: ProviderPaymentStatus) {
+  switch (status.type) {
+    case ProviderPaymentType.InsufficientBalance:
+      return 'no enough balance to make the payment'
+    case ProviderPaymentType.Unpaid:
+      return 'not pay yet'
+    case ProviderPaymentType.Paid:
+    case ProviderPaymentType.TermsChanged:
+      if (status.paidUntil.t_ms === 'never') {
+        return 'service paid.'
+      } else {
+        return `service paid until ${format(status.paidUntil.t_ms, 'yyyy/MM/dd 
HH:mm:ss')}`
+      }
+    case ProviderPaymentType.Pending:
+      return ''
+  }
+}

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]