async, onInput, and some fixes

This commit is contained in:
Sebastian 2021-11-04 15:17:57 -03:00
parent 5c6f380910
commit ae0a35df2b
No known key found for this signature in database
GPG Key ID: BE4FF68352439FC1
19 changed files with 101 additions and 105 deletions

View File

@ -37,9 +37,7 @@ export function AsyncButton({ onClick, disabled, children, ...rest }: Props): VN
// if (isSlow) { // if (isSlow) {
// return <LoadingModal onCancel={cancel} />; // return <LoadingModal onCancel={cancel} />;
// } // }
console.log(isLoading)
if (isLoading) { if (isLoading) {
return <button class="button">Loading...</button>; return <button class="button">Loading...</button>;
} }

View File

@ -41,7 +41,7 @@ export function DateInput(props: DateInputProps): VNode {
type="text" type="text"
class={showError ? 'input is-danger' : 'input'} class={showError ? 'input is-danger' : 'input'}
value={value} value={value}
onChange={(e) => { onInput={(e) => {
const text = e.currentTarget.value const text = e.currentTarget.value
setDirty(true) setDirty(true)
props.bind[1](text); props.bind[1](text);

View File

@ -34,7 +34,7 @@ export function EmailInput(props: TextInputProps): VNode {
placeholder={props.placeholder} placeholder={props.placeholder}
type="email" type="email"
class={showError ? 'input is-danger' : 'input'} class={showError ? 'input is-danger' : 'input'}
onChange={(e) => {setDirty(true); props.bind[1]((e.target as HTMLInputElement).value)}} onInput={(e) => {setDirty(true); props.bind[1]((e.target as HTMLInputElement).value)}}
ref={inputRef} ref={inputRef}
style={{ display: "block" }} /> style={{ display: "block" }} />
</div> </div>

View File

@ -33,7 +33,7 @@ export function NumberInput(props: TextInputProps): VNode {
type="number" type="number"
placeholder={props.placeholder} placeholder={props.placeholder}
class={showError ? 'input is-danger' : 'input'} class={showError ? 'input is-danger' : 'input'}
onChange={(e) => {setDirty(true); props.bind[1]((e.target as HTMLInputElement).value)}} onInput={(e) => {setDirty(true); props.bind[1]((e.target as HTMLInputElement).value)}}
ref={inputRef} ref={inputRef}
style={{ display: "block" }} /> style={{ display: "block" }} />
</div> </div>

View File

@ -32,7 +32,7 @@ export function TextInput(props: TextInputProps): VNode {
value={value} value={value}
placeholder={props.placeholder} placeholder={props.placeholder}
class={showError ? 'input is-danger' : 'input'} class={showError ? 'input is-danger' : 'input'}
onChange={(e) => {setDirty(true); props.bind[1]((e.target as HTMLInputElement).value)}} onInput={(e) => {setDirty(true); props.bind[1]((e.target as HTMLInputElement).value)}}
ref={inputRef} ref={inputRef}
style={{ display: "block" }} /> style={{ display: "block" }} />
</div> </div>

View File

@ -214,7 +214,7 @@ export class DatePicker extends Component<Props, State> {
// } // }
} }
constructor(props) { constructor(props: any) {
super(props); super(props);
this.closeDatePicker = this.closeDatePicker.bind(this); this.closeDatePicker = this.closeDatePicker.bind(this);

View File

@ -43,14 +43,14 @@ export function useAsync<T>(fn?: (...args: any) => Promise<T>, { slowTolerance:
const request = async (...args: any) => { const request = async (...args: any) => {
if (!fn) return; if (!fn) return;
setLoading(true); setLoading(true);
console.log("loading true")
const handler = setTimeout(() => { const handler = setTimeout(() => {
setSlow(true) setSlow(true)
}, tooLong) }, tooLong)
try { try {
console.log("calling async", args)
const result = await fn(...args); const result = await fn(...args);
console.log(result) console.log("async back", result)
setData(result); setData(result);
} catch (error) { } catch (error) {
setError(error); setError(error);

View File

@ -48,10 +48,10 @@ export function AttributeEntryScreen(): VNode {
})} })}
> >
<div class="columns" style={{ maxWidth: 'unset' }}> <div class="columns" style={{ maxWidth: 'unset' }}>
<div class="column is-one-third"> <div class="column is-half">
{fieldList} {fieldList}
</div> </div>
<div class="column is-two-third" > <div class="column is-is-half" >
<p>This personal information will help to locate your secret.</p> <p>This personal information will help to locate your secret.</p>
<h1 class="title">This stays private</h1> <h1 class="title">This stays private</h1>
<p>The information you have entered here:</p> <p>The information you have entered here:</p>

View File

@ -135,7 +135,7 @@ export function AuthenticationEditorScreen(): VNode {
return ( return (
<AnastasisClientFrame title="Backup: Configure Authentication Methods" hideNext={errors}> <AnastasisClientFrame title="Backup: Configure Authentication Methods" hideNext={errors}>
<div class="columns"> <div class="columns">
<div class="column one-third"> <div class="column is-half">
<div> <div>
{getKeys(authMethods).map(method => <MethodButton key={method} method={method} />)} {getKeys(authMethods).map(method => <MethodButton key={method} method={method} />)}
</div> </div>
@ -152,7 +152,7 @@ export function AuthenticationEditorScreen(): VNode {
</p> </p>
</ConfirmModal>} </ConfirmModal>}
</div> </div>
<div class="column two-third"> <div class="column is-half">
<p class="block"> <p class="block">
When recovering your wallet, you will be asked to verify your identity via the methods you configure here. When recovering your wallet, you will be asked to verify your identity via the methods you configure here.
The list of authentication method is defined by the backup provider list. The list of authentication method is defined by the backup provider list.

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/camelcase */
import { ChallengeFeedback, ChallengeFeedbackStatus } from "anastasis-core"; import { ChallengeFeedback, ChallengeFeedbackStatus } from "anastasis-core";
import { h, VNode } from "preact"; import { h, VNode } from "preact";
import { useAnastasisContext } from "../../context/anastasis"; import { useAnastasisContext } from "../../context/anastasis";

View File

@ -1,5 +1,4 @@
/* eslint-disable @typescript-eslint/camelcase */ /* eslint-disable @typescript-eslint/camelcase */
import { BackupStates, ContinentInfo, RecoveryStates } from "anastasis-core";
import { h, VNode } from "preact"; import { h, VNode } from "preact";
import { useState } from "preact/hooks"; import { useState } from "preact/hooks";
import { useAnastasisContext } from "../../context/anastasis"; import { useAnastasisContext } from "../../context/anastasis";
@ -9,7 +8,8 @@ export function ContinentSelectionScreen(): VNode {
const reducer = useAnastasisContext() const reducer = useAnastasisContext()
//FIXME: remove this when #7056 is fixed //FIXME: remove this when #7056 is fixed
const [countryCode, setCountryCode] = useState("") const countryFromReducer = (reducer?.currentReducerState as any).selected_country || ""
const [countryCode, setCountryCode] = useState( countryFromReducer )
if (!reducer || !reducer.currentReducerState || !("continents" in reducer.currentReducerState)) { if (!reducer || !reducer.currentReducerState || !("continents" in reducer.currentReducerState)) {
return <div /> return <div />

View File

@ -29,6 +29,9 @@ export function RecoveryFinishedScreen(): VNode {
<p> <p>
Secret: {secret} Secret: {secret}
</p> </p>
<div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
<button class="button" onClick={() => reducer.back()}>Back</button>
</div>
</AnastasisClientFrame> </AnastasisClientFrame>
); );
} }

View File

@ -4,7 +4,8 @@ import { h, VNode } from "preact";
import { useState } from "preact/hooks"; import { useState } from "preact/hooks";
import { useAnastasisContext } from "../../context/anastasis"; import { useAnastasisContext } from "../../context/anastasis";
import { import {
AnastasisClientFrame} from "./index"; AnastasisClientFrame
} from "./index";
import { TextInput } from "../../components/fields/TextInput"; import { TextInput } from "../../components/fields/TextInput";
import { FileInput } from "../../components/fields/FileInput"; import { FileInput } from "../../components/fields/FileInput";
@ -25,8 +26,8 @@ export function SecretEditorScreen(): VNode {
return <div>invalid state</div> return <div>invalid state</div>
} }
const secretNext = (): void => { const secretNext = async (): Promise<void> => {
reducer.runTransaction(async (tx) => { return reducer.runTransaction(async (tx) => {
await tx.transition("enter_secret_name", { await tx.transition("enter_secret_name", {
name: secretName, name: secretName,
}); });
@ -44,25 +45,29 @@ export function SecretEditorScreen(): VNode {
}; };
return ( return (
<AnastasisClientFrame <AnastasisClientFrame
title="Backup: Provide secret" title="Backup: Provide secret to backup"
onNext={() => secretNext()} onNext={() => secretNext()}
> >
<div> <div>
<TextInput <TextInput
label="Secret Name:" label="Secret's name:"
grabFocus grabFocus
bind={[secretName, setSecretName]} bind={[secretName, setSecretName]}
/> />
</div> </div>
<div> <div>
<TextInput <TextInput
label="Secret Value:" label="Enter the secret as text:"
bind={[secretValue, setSecretValue]}
/> or import a file
<FileInput
label="Open file from your device"
bind={[secretValue, setSecretValue]} bind={[secretValue, setSecretValue]}
/> />
<div style={{display:'flex',}}>
or&nbsp;
<FileInput
label="click here"
bind={[secretValue, setSecretValue]}
/>
&nbsp;to import a file
</div>
</div> </div>
</AnastasisClientFrame> </AnastasisClientFrame>
); );

View File

@ -97,18 +97,11 @@ export function SecretSelectionScreen(): VNode {
} }
return ( return (
<AnastasisClientFrame title="Recovery: Select secret"> <AnastasisClientFrame title="Recovery: Select secret">
<p>Secret found, you can select another version or continue to the challenges solving</p> <div class="columns">
<div class="column is-half">
<div class="box">
<h1 class="subtitle">{recoveryDocument.provider_url}</h1>
<table class="table"> <table class="table">
<tr>
<td>
<b>Provider</b>
<span class="icon has-tooltip-right" data-tooltip="Service provider backing up your secret">
<i class="mdi mdi-information" />
</span>
</td>
<td>{recoveryDocument.provider_url}</td>
<td><a onClick={() => setSelectingVersion(true)}>use another provider</a></td>
</tr>
<tr> <tr>
<td> <td>
<b>Secret version</b> <b>Secret version</b>
@ -130,6 +123,18 @@ export function SecretSelectionScreen(): VNode {
<td> </td> <td> </td>
</tr> </tr>
</table> </table>
<div class="buttons is-right">
<button class="button" disabled onClick={() => reducer.reset()}>Use this provider</button>
</div>
</div>
<div class="buttons is-right">
<button class="button" disabled onClick={() => reducer.reset()}>Change provider</button>
</div>
</div>
<div class="column is-two-third">
<p>Secret found, you can select another version or continue to the challenges solving</p>
</div>
</div>
</AnastasisClientFrame> </AnastasisClientFrame>
); );
} }

View File

@ -77,6 +77,9 @@ export function SolveScreen(): VNode {
return ( return (
<AnastasisClientFrame hideNav title="Recovery problem"> <AnastasisClientFrame hideNav title="Recovery problem">
<div>invalid state</div> <div>invalid state</div>
<div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
<button class="button" onClick={() => reducer.back()}>Back</button>
</div>
</AnastasisClientFrame> </AnastasisClientFrame>
); );
} }

View File

@ -96,12 +96,12 @@ export function AnastasisClientFrame(props: AnastasisClientFrameProps): VNode {
return <p>Fatal: Reducer must be in context.</p>; return <p>Fatal: Reducer must be in context.</p>;
} }
const next = async (): Promise<void> => { const next = async (): Promise<void> => {
return new Promise((res, rej) => { return new Promise(async (res, rej) => {
try { try {
if (props.onNext) { if (props.onNext) {
props.onNext(); await props.onNext();
} else { } else {
reducer.transition("next", {}); await reducer.transition("next", {});
} }
res() res()
} catch { } catch {

View File

@ -8,13 +8,13 @@ export function createExample<Props>(Component: FunctionalComponent<Props>, curr
return <AnastasisProvider value={{ return <AnastasisProvider value={{
currentReducerState, currentReducerState,
currentError: undefined, currentError: undefined,
back: () => { null }, back: async () => { null },
dismissError: () => { null }, dismissError: async () => { null },
reset: () => { null }, reset: () => { null },
runTransaction: () => { null }, runTransaction: async () => { null },
startBackup: () => { null }, startBackup: () => { null },
startRecover: () => { null }, startRecover: () => { null },
transition: () => { null }, transition: async () => { null },
}}> }}>
<Component {...args} /> <Component {...args} />
</AnastasisProvider> </AnastasisProvider>

View File

@ -45,7 +45,7 @@
"@storybook/preact": "^6.2.9", "@storybook/preact": "^6.2.9",
"@testing-library/preact": "^2.0.1", "@testing-library/preact": "^2.0.1",
"@types/chrome": "^0.0.128", "@types/chrome": "^0.0.128",
"@types/enzyme": "^3.10.8", "@types/enzyme": "^3.10.10",
"@types/history": "^4.7.8", "@types/history": "^4.7.8",
"@types/jest": "^26.0.23", "@types/jest": "^26.0.23",
"@types/node": "^14.14.22", "@types/node": "^14.14.22",

View File

@ -341,7 +341,7 @@ importers:
'@storybook/preact': ^6.2.9 '@storybook/preact': ^6.2.9
'@testing-library/preact': ^2.0.1 '@testing-library/preact': ^2.0.1
'@types/chrome': ^0.0.128 '@types/chrome': ^0.0.128
'@types/enzyme': ^3.10.8 '@types/enzyme': ^3.10.10
'@types/history': ^4.7.8 '@types/history': ^4.7.8
'@types/jest': ^26.0.23 '@types/jest': ^26.0.23
'@types/node': ^14.14.22 '@types/node': ^14.14.22
@ -397,7 +397,7 @@ importers:
'@storybook/preact': 6.3.7_9cd0ede338ef3d2deb8dbc69bc115c66 '@storybook/preact': 6.3.7_9cd0ede338ef3d2deb8dbc69bc115c66
'@testing-library/preact': 2.0.1_preact@10.5.14 '@testing-library/preact': 2.0.1_preact@10.5.14
'@types/chrome': 0.0.128 '@types/chrome': 0.0.128
'@types/enzyme': 3.10.9 '@types/enzyme': 3.10.10
'@types/history': 4.7.9 '@types/history': 4.7.9
'@types/jest': 26.0.24 '@types/jest': 26.0.24
'@types/node': 14.17.10 '@types/node': 14.17.10
@ -9881,13 +9881,6 @@ packages:
'@types/react': 17.0.34 '@types/react': 17.0.34
dev: true dev: true
/@types/enzyme/3.10.9:
resolution: {integrity: sha512-dx5UvcWe2Vtye6S9Hw2rFB7Ul9uMXOAje2FAbXvVYieQDNle9qPAo7DfvFMSztZ9NFiD3dVZ4JsRYGTrSLynJg==}
dependencies:
'@types/cheerio': 0.22.30
'@types/react': 17.0.19
dev: true
/@types/estree/0.0.39: /@types/estree/0.0.39:
resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
dev: true dev: true
@ -10099,14 +10092,6 @@ packages:
'@types/react': 17.0.34 '@types/react': 17.0.34
dev: true dev: true
/@types/react/17.0.19:
resolution: {integrity: sha512-sX1HisdB1/ZESixMTGnMxH9TDe8Sk709734fEQZzCV/4lSu9kJCPbo2PbTRoZM+53Pp0P10hYVyReUueGwUi4A==}
dependencies:
'@types/prop-types': 15.7.4
'@types/scheduler': 0.16.2
csstype: 3.0.8
dev: true
/@types/react/17.0.34: /@types/react/17.0.34:
resolution: {integrity: sha512-46FEGrMjc2+8XhHXILr+3+/sTe3OfzSPU9YGKILLrUYbQ1CLQC9Daqo1KzENGXAWwrFwiY0l4ZbF20gRvgpWTg==} resolution: {integrity: sha512-46FEGrMjc2+8XhHXILr+3+/sTe3OfzSPU9YGKILLrUYbQ1CLQC9Daqo1KzENGXAWwrFwiY0l4ZbF20gRvgpWTg==}
dependencies: dependencies:
@ -11397,7 +11382,7 @@ packages:
/axios/0.21.4: /axios/0.21.4:
resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
dependencies: dependencies:
follow-redirects: 1.14.5 follow-redirects: 1.14.5_debug@4.3.2
transitivePeerDependencies: transitivePeerDependencies:
- debug - debug
dev: true dev: true
@ -13562,10 +13547,6 @@ packages:
resolution: {integrity: sha512-RSU6Hyeg14am3Ah4VZEmeX8H7kLwEEirXe6aU2IPfKNvhXwTflK5HQRDNI0ypQXoqmm+QPyG2IaPuQE5zMwSIQ==} resolution: {integrity: sha512-RSU6Hyeg14am3Ah4VZEmeX8H7kLwEEirXe6aU2IPfKNvhXwTflK5HQRDNI0ypQXoqmm+QPyG2IaPuQE5zMwSIQ==}
dev: true dev: true
/csstype/3.0.8:
resolution: {integrity: sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==}
dev: true
/csstype/3.0.9: /csstype/3.0.9:
resolution: {integrity: sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==} resolution: {integrity: sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==}
dev: true dev: true
@ -15471,16 +15452,6 @@ packages:
optional: true optional: true
dev: false dev: false
/follow-redirects/1.14.5:
resolution: {integrity: sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
dev: true
/follow-redirects/1.14.5_debug@4.3.2: /follow-redirects/1.14.5_debug@4.3.2:
resolution: {integrity: sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==} resolution: {integrity: sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==}
engines: {node: '>=4.0'} engines: {node: '>=4.0'}
@ -20713,7 +20684,7 @@ packages:
resolution: {integrity: sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==} resolution: {integrity: sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==}
engines: {node: '>=6'} engines: {node: '>=6'}
dependencies: dependencies:
ts-pnp: 1.2.0_typescript@4.4.3 ts-pnp: 1.2.0_typescript@4.3.5
transitivePeerDependencies: transitivePeerDependencies:
- typescript - typescript
dev: true dev: true
@ -24776,6 +24747,18 @@ packages:
tslib: 2.3.1 tslib: 2.3.1
dev: true dev: true
/ts-pnp/1.2.0_typescript@4.3.5:
resolution: {integrity: sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==}
engines: {node: '>=6'}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
typescript: 4.3.5
dev: true
/ts-pnp/1.2.0_typescript@4.4.3: /ts-pnp/1.2.0_typescript@4.4.3:
resolution: {integrity: sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==} resolution: {integrity: sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==}
engines: {node: '>=6'} engines: {node: '>=6'}