+
{name}({inputs})
],
diff --git a/packages/app-extrinsics/src/Params/Param.js b/packages/app-extrinsics/src/Params/Param.js
deleted file mode 100644
index 4bd4d75d46..0000000000
--- a/packages/app-extrinsics/src/Params/Param.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2017-2018 Jaco Greeff
-// This software may be modified and distributed under the terms
-// of the ISC license. See the LICENSE file for details.
-// @flow
-
-import type { Extrinsic$Param } from '@polkadot/extrinsics/types';
-import type { BareProps, RawParam } from '../types';
-
-import React from 'react';
-
-import findComponent from './findComponent';
-import typeToText from './typeToText';
-
-type Props = BareProps & {
- label?: string,
- subject: rxjs$BehaviorSubject
,
- value: Extrinsic$Param
-}
-
-export default function Param ({ className, label, style, subject, value }: Props): React$Node {
- // flowlint-next-line sketchy-null-string:off
- const defaultLabel = label || `${value.name}: ${typeToText(value.type)}`;
- const Component = findComponent(value.type);
-
- return (
-
- );
-}
diff --git a/packages/app-extrinsics/src/Params/Account.js b/packages/app-extrinsics/src/Params/Param/Account.js
similarity index 89%
rename from packages/app-extrinsics/src/Params/Account.js
rename to packages/app-extrinsics/src/Params/Param/Account.js
index 2aaa680a41..5a4baca3ee 100644
--- a/packages/app-extrinsics/src/Params/Account.js
+++ b/packages/app-extrinsics/src/Params/Param/Account.js
@@ -3,12 +3,12 @@
// of the ISC license. See the LICENSE file for details.
// @flow
-import type { Props } from './types';
+import type { Props } from '../types';
import React from 'react';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
-import BaseAccount from '../Account';
+import BaseAccount from '../../Account';
export default function Account ({ isError, label, subject }: Props): React$Node {
const account: rxjs$BehaviorSubject = new BehaviorSubject(new Uint8Array([]));
diff --git a/packages/app-extrinsics/src/Params/Amount.js b/packages/app-extrinsics/src/Params/Param/Amount.js
similarity index 96%
rename from packages/app-extrinsics/src/Params/Amount.js
rename to packages/app-extrinsics/src/Params/Param/Amount.js
index 4bb8199ca9..51074c653a 100644
--- a/packages/app-extrinsics/src/Params/Amount.js
+++ b/packages/app-extrinsics/src/Params/Param/Amount.js
@@ -3,7 +3,7 @@
// of the ISC license. See the LICENSE file for details.
// @flow
-import type { Props } from './types';
+import type { Props } from '../types';
import BN from 'bn.js';
import React from 'react';
diff --git a/packages/app-extrinsics/src/Params/Base.js b/packages/app-extrinsics/src/Params/Param/Base.js
similarity index 92%
rename from packages/app-extrinsics/src/Params/Base.js
rename to packages/app-extrinsics/src/Params/Param/Base.js
index e5868f68be..746b280d01 100644
--- a/packages/app-extrinsics/src/Params/Base.js
+++ b/packages/app-extrinsics/src/Params/Param/Base.js
@@ -3,6 +3,8 @@
// of the ISC license. See the LICENSE file for details.
// @flow
+import type { Size } from '../types';
+
import React from 'react';
import Label from 'semantic-ui-react/dist/es/elements/Label';
@@ -10,7 +12,7 @@ type Props = {
className?: string,
children: React$Node,
label?: string,
- size?: 'full' | 'large' | 'medium' | 'small',
+ size?: Size,
style?: {
[string]: string
}
diff --git a/packages/app-extrinsics/src/Params/Bool.js b/packages/app-extrinsics/src/Params/Param/Bool.js
similarity index 95%
rename from packages/app-extrinsics/src/Params/Bool.js
rename to packages/app-extrinsics/src/Params/Param/Bool.js
index 7f1cc2d20c..54a061c2ad 100644
--- a/packages/app-extrinsics/src/Params/Bool.js
+++ b/packages/app-extrinsics/src/Params/Param/Bool.js
@@ -3,7 +3,7 @@
// of the ISC license. See the LICENSE file for details.
// @flow
-import type { Props } from './types';
+import type { Props } from '../types';
import React from 'react';
import Dropdown from 'semantic-ui-react/dist/es/modules/Dropdown';
diff --git a/packages/app-extrinsics/src/Params/Hash.js b/packages/app-extrinsics/src/Params/Param/Bytes.js
similarity index 60%
rename from packages/app-extrinsics/src/Params/Hash.js
rename to packages/app-extrinsics/src/Params/Param/Bytes.js
index f9d1ea4e0e..5a8d21ce78 100644
--- a/packages/app-extrinsics/src/Params/Hash.js
+++ b/packages/app-extrinsics/src/Params/Param/Bytes.js
@@ -3,7 +3,7 @@
// of the ISC license. See the LICENSE file for details.
// @flow
-import type { Props } from './types';
+import type { Props as BaseProps, Size } from '../types';
import React from 'react';
import Input from 'semantic-ui-react/dist/es/elements/Input';
@@ -11,7 +11,16 @@ import hexToU8a from '@polkadot/util/hex/toU8a';
import Base from './Base';
-export default function Hash ({ isError, label, subject, t }: Props): React$Node {
+type Props = BaseProps & {
+ length?: number,
+ size?: Size,
+ validate?: (u8a: Uint8Array) => boolean
+}
+
+const defaultValidate = (u8a: Uint8Array): boolean =>
+ true;
+
+export default function Bytes ({ isError, length = -1, label, size = 'full', subject, validate = defaultValidate }: Props): React$Node {
// eslint-disable-next-line no-unused-vars
const onChange = (event: SyntheticEvent<*>, { value }) => {
let u8a;
@@ -22,8 +31,12 @@ export default function Hash ({ isError, label, subject, t }: Props): React$Node
u8a = new Uint8Array([]);
}
+ const isValidLength = length !== -1
+ ? u8a.length === length
+ : u8a.length !== 0;
+
subject.next({
- isValid: u8a.length === 32,
+ isValid: isValidLength && validate(u8a),
value: u8a
});
};
@@ -31,7 +44,7 @@ export default function Hash ({ isError, label, subject, t }: Props): React$Node
return (
void,
+ subject: rxjs$BehaviorSubject,
+ t: I18Next$Translate
+}
+
+type WrappedProps = Props & {
+ value: RawParam
+}
+
+function BytesFile ({ className, isError, label, onChange, subject, t }: Props): React$Node {
+ const onDrop = (files: Array) => {
+ files.forEach((file) => {
+ const reader = new FileReader();
+
+ reader.onload = () =>
+ // flowlint-next-line unclear-type:off
+ onChange(file, new Uint8Array((((reader.result): any): ArrayBuffer)));
+ reader.onabort = () =>
+ onChange();
+ reader.onerror = () =>
+ onChange();
+
+ reader.readAsArrayBuffer(file);
+ });
+ };
+
+ const Component = withObservable(subject)(({ value: { data } = {} }: WrappedProps): React$Node => {
+ // flowlint-next-line sketchy-null-bool:off
+ const classes = ['extrinsics--Param-File', isError ? 'error' : '', !!data, className].join(' ');
+
+ return (
+
+
+
+ {
+ !data
+ ? t('file.dnd', {
+ defaultValue: 'drag and drop the file here'
+ })
+ : t('file.description', {
+ defaultValue: '{{name}} ({{size}} bytes)',
+ replace: {
+ name: data.name,
+ size: data.size
+ }
+ })
+ }
+
+
+
+ );
+ });
+
+ return (
+
+ );
+}
+
+export default translate(BytesFile);
diff --git a/packages/app-extrinsics/src/Params/Param/Hash.js b/packages/app-extrinsics/src/Params/Param/Hash.js
new file mode 100644
index 0000000000..87a00520ad
--- /dev/null
+++ b/packages/app-extrinsics/src/Params/Param/Hash.js
@@ -0,0 +1,23 @@
+// Copyright 2017-2018 Jaco Greeff
+// This software may be modified and distributed under the terms
+// of the ISC license. See the LICENSE file for details.
+// @flow
+
+import type { Props } from '../types';
+
+import React from 'react';
+
+import Bytes from './Bytes';
+
+export default function Hash ({ isError, label, subject, value }: Props): React$Node {
+ return (
+
+ );
+}
diff --git a/packages/app-extrinsics/src/Params/Proposal.js b/packages/app-extrinsics/src/Params/Param/Proposal.js
similarity index 84%
rename from packages/app-extrinsics/src/Params/Proposal.js
rename to packages/app-extrinsics/src/Params/Param/Proposal.js
index f0363e8df3..4005129f47 100644
--- a/packages/app-extrinsics/src/Params/Proposal.js
+++ b/packages/app-extrinsics/src/Params/Param/Proposal.js
@@ -3,13 +3,13 @@
// of the ISC license. See the LICENSE file for details.
// @flow
-import type { EncodedParams } from '../types';
-import type { Props } from './types';
+import type { EncodedParams } from '../../types';
+import type { Props } from '../types';
import React from 'react';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
-import Extrinsic from '../Extrinsic';
+import Extrinsic from '../../Extrinsic';
export default function Proposal ({ isError, label, subject }: Props): React$Node {
const extrinsic: rxjs$BehaviorSubject = new BehaviorSubject(({ isValid: false }: $Shape));
diff --git a/packages/app-extrinsics/src/Params/Unknown.js b/packages/app-extrinsics/src/Params/Param/Unknown.js
similarity index 86%
rename from packages/app-extrinsics/src/Params/Unknown.js
rename to packages/app-extrinsics/src/Params/Param/Unknown.js
index 63c83daede..35e04f04bb 100644
--- a/packages/app-extrinsics/src/Params/Unknown.js
+++ b/packages/app-extrinsics/src/Params/Param/Unknown.js
@@ -3,13 +3,13 @@
// of the ISC license. See the LICENSE file for details.
// @flow
-import type { Props as BaseProps } from './types';
+import type { Props as BaseProps } from '../types';
import React from 'react';
-import translate from '../translate';
+import translate from '../../translate';
import Base from './Base';
-import typeToText from './typeToText';
+import typeToText from '../typeToText';
type Props = BaseProps & {
t: I18Next$Translate
diff --git a/packages/app-extrinsics/src/Params/VoteThreshold.js b/packages/app-extrinsics/src/Params/Param/VoteThreshold.js
similarity index 84%
rename from packages/app-extrinsics/src/Params/VoteThreshold.js
rename to packages/app-extrinsics/src/Params/Param/VoteThreshold.js
index 5407cf68e4..e3f6ebfb8c 100644
--- a/packages/app-extrinsics/src/Params/VoteThreshold.js
+++ b/packages/app-extrinsics/src/Params/Param/VoteThreshold.js
@@ -3,7 +3,7 @@
// of the ISC license. See the LICENSE file for details.
// @flow
-import type { Props } from './types';
+import type { Props } from '../types';
import React from 'react';
import Dropdown from 'semantic-ui-react/dist/es/modules/Dropdown';
@@ -17,6 +17,8 @@ const options = [
];
export default function VoteThreshold ({ label, subject, t, value: { options: { initValue = 0 } = {} } }: Props): React$Node {
+ // flowlint-next-line sketchy-null-mixed:off
+ const defaultValue = initValue || 0;
const onChange = (event: SyntheticEvent<*>, { value }) =>
subject.next({
isValid: true,
@@ -30,7 +32,7 @@ export default function VoteThreshold ({ label, subject, t, value: { options: {
>
diff --git a/packages/app-extrinsics/src/Params/Param/Wasm.js b/packages/app-extrinsics/src/Params/Param/Wasm.js
new file mode 100644
index 0000000000..e1bea9b8d5
--- /dev/null
+++ b/packages/app-extrinsics/src/Params/Param/Wasm.js
@@ -0,0 +1,30 @@
+// Copyright 2017-2018 Jaco Greeff
+// This software may be modified and distributed under the terms
+// of the ISC license. See the LICENSE file for details.
+// @flow
+
+import type { Props } from '../types';
+
+import React from 'react';
+
+import BytesFile from './File';
+
+export default function Wasm ({ isError, label, subject }: Props): React$Node {
+ const onChange = (file?: File, value?: Uint8Array) => {
+ // TODO: Validate that we have actual proper WASM code
+ subject.next({
+ data: file,
+ isValid: !!value && value.length !== 0,
+ value
+ });
+ };
+
+ return (
+
+ );
+}
diff --git a/packages/app-extrinsics/src/Params/Params.css b/packages/app-extrinsics/src/Params/Params.css
index c864266eb9..c90e65739e 100644
--- a/packages/app-extrinsics/src/Params/Params.css
+++ b/packages/app-extrinsics/src/Params/Params.css
@@ -9,4 +9,29 @@
padding-left: 2em;
}
-.extrinsics--Params-Param {}
+.extrinsics--Param {}
+
+.extrinsics--Param-File {
+ align-items: center;
+ border: 1px dashed rgba(34, 36, 38, 0.15);
+ border-radius: 0.28571429rem;
+ display: flex;
+ justify-content: center;
+ font-size: 1.2em;
+ height: 5em;
+ margin-bottom: 0.5rem;
+ width: 100% !important;
+}
+
+.extrinsics--Param-File.true {
+ border-style: solid;
+}
+
+.extrinsics--Params-File:hover {
+ background: rgba(200, 200, 200, 0.8);
+ cursor: pointer;
+}
+
+.extrinsics--Param-File .label {
+ color: rgba(0, 0, 0, .6);
+}
diff --git a/packages/app-extrinsics/src/Params/findComponent.js b/packages/app-extrinsics/src/Params/findComponent.js
index 773a3a0f3c..ca9fd4705e 100644
--- a/packages/app-extrinsics/src/Params/findComponent.js
+++ b/packages/app-extrinsics/src/Params/findComponent.js
@@ -5,27 +5,30 @@
import type { Extrinsic$Type } from '@polkadot/extrinsics/types';
-import Account from './Account';
-import Amount from './Amount';
-import Bool from './Bool';
-import Hash from './Hash';
-import Proposal from './Proposal';
-import Unknown from './Unknown';
-import VoteThreshold from './VoteThreshold';
+import Account from './Param/Account';
+import Amount from './Param/Amount';
+import Bool from './Param/Bool';
+import Bytes from './Param/Bytes';
+import Hash from './Param/Hash';
+import Proposal from './Param/Proposal';
+import Unknown from './Param/Unknown';
+import VoteThreshold from './Param/VoteThreshold';
+import Wasm from './Param/Wasm';
const Components = {
'AccountId': Account,
'Balance': Amount,
'BlockNumber': Amount,
'bool': Bool,
- 'Bytes': Unknown,
+ 'Bytes': Bytes,
'Hash': Hash,
'MisbehaviorReport': Unknown,
'Proposal': Proposal,
'SessionKey': Unknown,
'u32': Amount,
'u64': Amount,
- 'VoteThreshold': VoteThreshold
+ 'VoteThreshold': VoteThreshold,
+ 'Wasm': Wasm
};
export default function findComponent (type: Extrinsic$Type): React$ComponentType<*> {
diff --git a/packages/app-extrinsics/src/Params/index.js b/packages/app-extrinsics/src/Params/index.js
index 12dd1a207e..7ac79a56ca 100644
--- a/packages/app-extrinsics/src/Params/index.js
+++ b/packages/app-extrinsics/src/Params/index.js
@@ -9,16 +9,10 @@ import type { BaseProps, RawParam } from '../types';
import './Params.css';
import React from 'react';
-// import Label from 'semantic-ui-react/dist/es/elements/Label';
-//
import translate from '../translate';
-import Param from './Param';
-import createSubscriber from './subscriber';
+import findComponent from './findComponent';
+import createSubjects from './subjects';
import typeToText from './typeToText';
type Props = BaseProps & {
@@ -31,24 +25,27 @@ function Params ({ className, style, subject, value: { name, params } }: Props):
return null;
}
- const subjects = createSubscriber(params, subject);
+ const subjects = createSubjects(params, subject);
return (
-
-
- {params.map((value, index) => (
-
+ {params.map((value, index) => {
+ const Component = findComponent(value.type);
+
+ return (
+
- ))}
-
+ );
+ })}
);
diff --git a/packages/app-extrinsics/src/Params/initValue.js b/packages/app-extrinsics/src/Params/initValue.js
index 1410c5ac2a..4dde3896b2 100644
--- a/packages/app-extrinsics/src/Params/initValue.js
+++ b/packages/app-extrinsics/src/Params/initValue.js
@@ -9,7 +9,13 @@ import type { Extrinsic$Param } from '@polkadot/extrinsics/types';
import BN from 'bn.js';
export default function getInitValue ({ options: { initValue, minValue } = {}, type }: Extrinsic$Param): mixed {
- switch (type) {
+ let inner = type;
+
+ if (Array.isArray(type)) {
+ inner = type[1];
+ }
+
+ switch (inner) {
case 'Balance':
case 'BlockNumber':
case 'u32':
diff --git a/packages/app-extrinsics/src/Params/subjects.js b/packages/app-extrinsics/src/Params/subjects.js
index 1c4e7df61a..5beb20ad82 100644
--- a/packages/app-extrinsics/src/Params/subjects.js
+++ b/packages/app-extrinsics/src/Params/subjects.js
@@ -11,8 +11,8 @@ import isUndefined from '@polkadot/util/is/undefined';
import getInitValue from './initValue';
-export default function createSubjects (params: Extrinsic$Params): Array> {
- return params.map((param) => {
+export default function subjects (params: Extrinsic$Params, subject: rxjs$BehaviorSubject>): Array> {
+ const subjects = params.map((param): rxjs$BehaviorSubject => {
const value = getInitValue(param);
return new BehaviorSubject({
@@ -20,4 +20,16 @@ export default function createSubjects (params: Extrinsic$Params): Array {
+ subject.next(
+ subjects.map((s) => s.getValue())
+ );
+ };
+
+ subjects.forEach((s) => s.subscribe(onChange));
+ }
+
+ return subjects;
}
diff --git a/packages/app-extrinsics/src/Params/subscriber.js b/packages/app-extrinsics/src/Params/subscriber.js
deleted file mode 100644
index 670c73b95a..0000000000
--- a/packages/app-extrinsics/src/Params/subscriber.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017-2018 Jaco Greeff
-// This software may be modified and distributed under the terms
-// of the ISC license. See the LICENSE file for details.
-// @flow
-
-import type { Extrinsic$Params } from '@polkadot/extrinsics/types';
-import type { RawParam } from '../types';
-
-import createSubjects from './subjects';
-
-export default function subscriber (params: Extrinsic$Params, subject: rxjs$BehaviorSubject>): Array> {
- const subjects = createSubjects(params);
-
- if (subject) {
- const onChange = (): void => {
- subject.next(subjects.map((s) => s.getValue()));
- };
-
- subjects.forEach((s) => s.subscribe(onChange));
- }
-
- return subjects;
-}
diff --git a/packages/app-extrinsics/src/Params/types.js b/packages/app-extrinsics/src/Params/types.js
index 1e6cf4f283..8d8a2db44c 100644
--- a/packages/app-extrinsics/src/Params/types.js
+++ b/packages/app-extrinsics/src/Params/types.js
@@ -15,3 +15,5 @@ export type Props = BaseProps & {
isError?: boolean,
label: string
};
+
+export type Size = 'full' | 'large' | 'medium' | 'small';
diff --git a/packages/app-extrinsics/src/Signer/Decoded.js b/packages/app-extrinsics/src/Signer/Decoded.js
index 7f80a96520..c14566def2 100644
--- a/packages/app-extrinsics/src/Signer/Decoded.js
+++ b/packages/app-extrinsics/src/Signer/Decoded.js
@@ -9,7 +9,6 @@ import React from 'react';
import { Trans } from 'react-i18next';
import Modal from 'semantic-ui-react/dist/es/modules/Modal';
import IdentityIcon from '@polkadot/ui-react/IdentityIcon';
-import u8aToHex from '@polkadot/util/u8a/toHex';
import u8aToHexShort from '@polkadot/util/u8a/toHexShort';
import translate from '../translate';
@@ -42,7 +41,7 @@ function Decoded ({ className, style, t, value: { data, extrinsic, index, public
defaultValue: 'The encoded parameters contains the data'
})}
- {u8aToHex(data)}
+ {u8aToHexShort(data, 512)}