mirror of https://github.com/waku-org/js-waku.git
Organise elements in fieldboxes
This commit is contained in:
parent
5661c7d1ec
commit
31d0efc8d2
|
@ -8,6 +8,7 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material-ui/core": "^4.11.4",
|
"@material-ui/core": "^4.11.4",
|
||||||
|
"@material-ui/icons": "^4.11.2",
|
||||||
"@testing-library/jest-dom": "^5.11.4",
|
"@testing-library/jest-dom": "^5.11.4",
|
||||||
"@testing-library/react": "^11.1.0",
|
"@testing-library/react": "^11.1.0",
|
||||||
"@testing-library/user-event": "^12.1.10",
|
"@testing-library/user-event": "^12.1.10",
|
||||||
|
@ -3451,6 +3452,28 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@material-ui/icons": {
|
||||||
|
"version": "4.11.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.11.2.tgz",
|
||||||
|
"integrity": "sha512-fQNsKX2TxBmqIGJCSi3tGTO/gZ+eJgWmMJkgDiOfyNaunNaxcklJQFaFogYcFl0qFuaEz1qaXYXboa/bUXVSOQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.4.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@material-ui/core": "^4.0.0",
|
||||||
|
"@types/react": "^16.8.6 || ^17.0.0",
|
||||||
|
"react": "^16.8.0 || ^17.0.0",
|
||||||
|
"react-dom": "^16.8.0 || ^17.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@material-ui/styles": {
|
"node_modules/@material-ui/styles": {
|
||||||
"version": "4.11.4",
|
"version": "4.11.4",
|
||||||
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.4.tgz",
|
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.4.tgz",
|
||||||
|
@ -26510,6 +26533,14 @@
|
||||||
"react-transition-group": "^4.4.0"
|
"react-transition-group": "^4.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@material-ui/icons": {
|
||||||
|
"version": "4.11.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.11.2.tgz",
|
||||||
|
"integrity": "sha512-fQNsKX2TxBmqIGJCSi3tGTO/gZ+eJgWmMJkgDiOfyNaunNaxcklJQFaFogYcFl0qFuaEz1qaXYXboa/bUXVSOQ==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.4.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@material-ui/styles": {
|
"@material-ui/styles": {
|
||||||
"version": "4.11.4",
|
"version": "4.11.4",
|
||||||
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.4.tgz",
|
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.4.tgz",
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
"homepage": "/js-waku/eth-dm",
|
"homepage": "/js-waku/eth-dm",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material-ui/core": "^4.11.4",
|
"@material-ui/core": "^4.11.4",
|
||||||
|
"@material-ui/icons": "^4.11.2",
|
||||||
"@testing-library/jest-dom": "^5.11.4",
|
"@testing-library/jest-dom": "^5.11.4",
|
||||||
"@testing-library/react": "^11.1.0",
|
"@testing-library/react": "^11.1.0",
|
||||||
"@testing-library/user-event": "^12.1.10",
|
"@testing-library/user-event": "^12.1.10",
|
||||||
|
|
|
@ -9,16 +9,61 @@ import { createPublicKeyMessage, KeyPair } from './crypto';
|
||||||
import { encode, PublicKeyMessage } from './messages';
|
import { encode, PublicKeyMessage } from './messages';
|
||||||
import Messages, { Message } from './Messages';
|
import Messages, { Message } from './Messages';
|
||||||
import 'fontsource-roboto';
|
import 'fontsource-roboto';
|
||||||
import { Button } from '@material-ui/core';
|
import {
|
||||||
|
AppBar,
|
||||||
|
Button,
|
||||||
|
IconButton,
|
||||||
|
Toolbar,
|
||||||
|
Typography,
|
||||||
|
} from '@material-ui/core';
|
||||||
import SendMessage from './SendMessage';
|
import SendMessage from './SendMessage';
|
||||||
import KeyPairHandling from './key_pair_handling/KeyPairHandling';
|
import KeyPairHandling from './key_pair_handling/KeyPairHandling';
|
||||||
import InitWaku from './InitWaku';
|
import InitWaku from './InitWaku';
|
||||||
|
import {
|
||||||
|
createMuiTheme,
|
||||||
|
ThemeProvider,
|
||||||
|
makeStyles,
|
||||||
|
} from '@material-ui/core/styles';
|
||||||
|
import { teal, purple, green } from '@material-ui/core/colors';
|
||||||
|
import WifiIcon from '@material-ui/icons/Wifi';
|
||||||
|
|
||||||
export const PublicKeyContentTopic = '/eth-dm/1/public-key/json';
|
export const PublicKeyContentTopic = '/eth-dm/1/public-key/json';
|
||||||
export const DirectMessageContentTopic = '/eth-dm/1/direct-message/json';
|
export const DirectMessageContentTopic = '/eth-dm/1/direct-message/json';
|
||||||
|
|
||||||
declare let window: any;
|
declare let window: any;
|
||||||
|
|
||||||
|
const theme = createMuiTheme({
|
||||||
|
palette: {
|
||||||
|
primary: {
|
||||||
|
main: purple[500],
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
main: teal[600],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const useStyles = makeStyles({
|
||||||
|
root: {
|
||||||
|
textAlign: 'center',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
minHeight: '100vh',
|
||||||
|
},
|
||||||
|
appBar: {
|
||||||
|
// height: '200p',
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
display: 'flex',
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
main: {
|
||||||
|
flex: 1,
|
||||||
|
margin: '10px',
|
||||||
|
},
|
||||||
|
wakuStatus: {},
|
||||||
|
});
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [waku, setWaku] = useState<Waku>();
|
const [waku, setWaku] = useState<Waku>();
|
||||||
const [provider, setProvider] = useState<Web3Provider>();
|
const [provider, setProvider] = useState<Web3Provider>();
|
||||||
|
@ -28,6 +73,8 @@ function App() {
|
||||||
const [messages, setMessages] = useState<Message[]>([]);
|
const [messages, setMessages] = useState<Message[]>([]);
|
||||||
const [address, setAddress] = useState<string>();
|
const [address, setAddress] = useState<string>();
|
||||||
|
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (provider) return;
|
if (provider) return;
|
||||||
try {
|
try {
|
||||||
|
@ -72,34 +119,58 @@ function App() {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<ThemeProvider theme={theme}>
|
||||||
<header className="App-header">
|
<div className={classes.root}>
|
||||||
<InitWaku
|
<AppBar className={classes.appBar} position="static">
|
||||||
ethDmKeyPair={ethDmKeyPair}
|
<Toolbar>
|
||||||
setMessages={setMessages}
|
<Typography>Ethereum Direct Message</Typography>
|
||||||
setPublicKeys={setPublicKeys}
|
<IconButton
|
||||||
setWaku={setWaku}
|
edge="end"
|
||||||
waku={waku}
|
className={classes.wakuStatus}
|
||||||
address={address}
|
aria-label="waku-status"
|
||||||
/>
|
>
|
||||||
<KeyPairHandling
|
<WifiIcon
|
||||||
ethDmKeyPair={ethDmKeyPair}
|
color={waku ? undefined : 'disabled'}
|
||||||
setEthDmKeyPair={(keyPair) => setEthDmKeyPair(keyPair)}
|
style={waku ? { color: green[500] } : {}}
|
||||||
/>
|
/>
|
||||||
<div>
|
</IconButton>
|
||||||
<Button
|
</Toolbar>
|
||||||
variant="contained"
|
</AppBar>
|
||||||
color="primary"
|
|
||||||
onClick={broadcastPublicKey}
|
<div className={classes.container}>
|
||||||
disabled={!ethDmKeyPair || !waku}
|
<main className={classes.main}>
|
||||||
>
|
<InitWaku
|
||||||
Broadcast Eth-DM Public Key
|
ethDmKeyPair={ethDmKeyPair}
|
||||||
</Button>
|
setMessages={setMessages}
|
||||||
|
setPublicKeys={setPublicKeys}
|
||||||
|
setWaku={setWaku}
|
||||||
|
waku={waku}
|
||||||
|
address={address}
|
||||||
|
/>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Eth-DM Key Pair</legend>
|
||||||
|
<KeyPairHandling
|
||||||
|
ethDmKeyPair={ethDmKeyPair}
|
||||||
|
setEthDmKeyPair={(keyPair) => setEthDmKeyPair(keyPair)}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={broadcastPublicKey}
|
||||||
|
disabled={!ethDmKeyPair || !waku}
|
||||||
|
>
|
||||||
|
Broadcast Eth-DM Public Key
|
||||||
|
</Button>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Messaging</legend>
|
||||||
|
<SendMessage recipients={publicKeys} waku={waku} />
|
||||||
|
<Messages messages={messages} />
|
||||||
|
</fieldset>
|
||||||
|
</main>
|
||||||
</div>
|
</div>
|
||||||
<SendMessage recipients={publicKeys} waku={waku} />
|
</div>
|
||||||
<Messages messages={messages} />
|
</ThemeProvider>
|
||||||
</header>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ export default function InitWaku({
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
return <p>{!!waku ? 'Waku is ready' : 'Waku is loading'}</p>;
|
return <div />;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initWaku(): Promise<Waku> {
|
async function initWaku(): Promise<Waku> {
|
||||||
|
|
|
@ -1,8 +1,32 @@
|
||||||
import { Button } from '@material-ui/core';
|
import { Button } from '@material-ui/core';
|
||||||
import { LoadKeyPair } from './LoadKeyPair';
|
import { LoadKeyPair } from './LoadKeyPair';
|
||||||
import { SaveKeyPair } from './SaveKeyPair';
|
import { SaveKeyPair } from './SaveKeyPair';
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { generateEthDmKeyPair, KeyPair } from '../crypto';
|
import { generateEthDmKeyPair, KeyPair } from '../crypto';
|
||||||
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
|
import PasswordInput from './PasswordInput';
|
||||||
|
|
||||||
|
const useStyles = makeStyles({
|
||||||
|
root: {
|
||||||
|
textAlign: 'center',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
flexDirection: 'column',
|
||||||
|
margin: '5px',
|
||||||
|
},
|
||||||
|
generate: { margin: '5px' },
|
||||||
|
storage: {
|
||||||
|
margin: '5px',
|
||||||
|
},
|
||||||
|
loadSave: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
margin: '5px',
|
||||||
|
},
|
||||||
|
loadSaveButton: {
|
||||||
|
margin: '5px',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
ethDmKeyPair: KeyPair | undefined;
|
ethDmKeyPair: KeyPair | undefined;
|
||||||
|
@ -13,6 +37,10 @@ export default function KeyPairHandling({
|
||||||
ethDmKeyPair,
|
ethDmKeyPair,
|
||||||
setEthDmKeyPair,
|
setEthDmKeyPair,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
const [password, setPassword] = useState<string>();
|
||||||
|
|
||||||
const generateKeyPair = () => {
|
const generateKeyPair = () => {
|
||||||
if (ethDmKeyPair) return;
|
if (ethDmKeyPair) return;
|
||||||
|
|
||||||
|
@ -26,43 +54,33 @@ export default function KeyPairHandling({
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className={classes.root}>
|
||||||
<div
|
<Button
|
||||||
style={{
|
className={classes.generate}
|
||||||
display: 'flex',
|
variant="contained"
|
||||||
alignItems: 'center',
|
color="primary"
|
||||||
flexWrap: 'wrap',
|
onClick={generateKeyPair}
|
||||||
}}
|
disabled={!!ethDmKeyPair}
|
||||||
>
|
>
|
||||||
<Button
|
Generate Eth-DM Key Pair
|
||||||
variant="contained"
|
</Button>
|
||||||
color="primary"
|
<div className={classes.storage}>
|
||||||
onClick={generateKeyPair}
|
<PasswordInput
|
||||||
disabled={!!ethDmKeyPair}
|
password={password}
|
||||||
>
|
setPassword={(p) => setPassword(p)}
|
||||||
Generate Eth-DM Key Pair
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
flexWrap: 'wrap',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<LoadKeyPair
|
|
||||||
setEthDmKeyPair={(keyPair) => setEthDmKeyPair(keyPair)}
|
|
||||||
disabled={!!ethDmKeyPair}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
<div className={classes.loadSave}>
|
||||||
<div
|
<div className={classes.loadSaveButton}>
|
||||||
style={{
|
<LoadKeyPair
|
||||||
display: 'flex',
|
setEthDmKeyPair={(keyPair) => setEthDmKeyPair(keyPair)}
|
||||||
alignItems: 'center',
|
disabled={!!ethDmKeyPair}
|
||||||
flexWrap: 'wrap',
|
password={password}
|
||||||
}}
|
/>
|
||||||
>
|
</div>
|
||||||
<SaveKeyPair ethDmKeyPair={ethDmKeyPair} />
|
<div className={classes.loadSaveButton}>
|
||||||
|
<SaveKeyPair ethDmKeyPair={ethDmKeyPair} password={password} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,20 +1,15 @@
|
||||||
import { Button, TextField } from '@material-ui/core';
|
import { Button } from '@material-ui/core';
|
||||||
import React, { ChangeEvent, useState } from 'react';
|
import React from 'react';
|
||||||
import { loadKeyPairFromStorage } from './key_pair_storage';
|
import { loadKeyPairFromStorage } from './key_pair_storage';
|
||||||
import { KeyPair } from '../crypto';
|
import { KeyPair } from '../crypto';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
setEthDmKeyPair: (keyPair: KeyPair) => void;
|
setEthDmKeyPair: (keyPair: KeyPair) => void;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
password: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function LoadKeyPair({ disabled, setEthDmKeyPair }: Props) {
|
export function LoadKeyPair({ password, disabled, setEthDmKeyPair }: Props) {
|
||||||
const [password, setPassword] = useState<string>();
|
|
||||||
|
|
||||||
const handlePasswordChange = (event: ChangeEvent<HTMLInputElement>) => {
|
|
||||||
setPassword(event.target.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadKeyPair = () => {
|
const loadKeyPair = () => {
|
||||||
if (disabled) return;
|
if (disabled) return;
|
||||||
if (!password) return;
|
if (!password) return;
|
||||||
|
@ -26,29 +21,13 @@ export function LoadKeyPair({ disabled, setEthDmKeyPair }: Props) {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<Button
|
||||||
style={{
|
variant="contained"
|
||||||
display: 'flex',
|
color="primary"
|
||||||
alignItems: 'center',
|
onClick={loadKeyPair}
|
||||||
flexWrap: 'wrap',
|
disabled={!password || disabled}
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<TextField
|
Load Eth-DM Key Pair from storage
|
||||||
id="password-input"
|
</Button>
|
||||||
label="Password"
|
|
||||||
variant="filled"
|
|
||||||
type="password"
|
|
||||||
onChange={handlePasswordChange}
|
|
||||||
value={password}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
onClick={loadKeyPair}
|
|
||||||
disabled={!password || disabled}
|
|
||||||
>
|
|
||||||
Load Eth-DM Key Pair from storage
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { TextField } from '@material-ui/core';
|
||||||
|
import React, { ChangeEvent } from 'react';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
password: string | undefined;
|
||||||
|
setPassword: (password: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function PasswordInput({ password, setPassword }: Props) {
|
||||||
|
const handlePasswordChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setPassword(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TextField
|
||||||
|
id="password-input"
|
||||||
|
label="Password"
|
||||||
|
variant="filled"
|
||||||
|
type="password"
|
||||||
|
onChange={handlePasswordChange}
|
||||||
|
value={password}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,19 +1,14 @@
|
||||||
import { Button, TextField } from '@material-ui/core';
|
import { Button } from '@material-ui/core';
|
||||||
import React, { ChangeEvent, useState } from 'react';
|
import React from 'react';
|
||||||
import { KeyPair } from '../crypto';
|
import { KeyPair } from '../crypto';
|
||||||
import { saveKeyPairToStorage } from './key_pair_storage';
|
import { saveKeyPairToStorage } from './key_pair_storage';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
ethDmKeyPair: KeyPair | undefined;
|
ethDmKeyPair: KeyPair | undefined;
|
||||||
|
password: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SaveKeyPair({ ethDmKeyPair }: Props) {
|
export function SaveKeyPair({ password, ethDmKeyPair }: Props) {
|
||||||
const [password, setPassword] = useState<string>();
|
|
||||||
|
|
||||||
const handlePasswordChange = (event: ChangeEvent<HTMLInputElement>) => {
|
|
||||||
setPassword(event.target.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const saveKeyPair = () => {
|
const saveKeyPair = () => {
|
||||||
if (!ethDmKeyPair) return;
|
if (!ethDmKeyPair) return;
|
||||||
if (!password) return;
|
if (!password) return;
|
||||||
|
@ -23,29 +18,13 @@ export function SaveKeyPair({ ethDmKeyPair }: Props) {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<Button
|
||||||
style={{
|
variant="contained"
|
||||||
display: 'flex',
|
color="primary"
|
||||||
alignItems: 'center',
|
onClick={saveKeyPair}
|
||||||
flexWrap: 'wrap',
|
disabled={!password || !ethDmKeyPair}
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<TextField
|
Save Eth-DM Key Pair to storage
|
||||||
id="password-input"
|
</Button>
|
||||||
label="Password"
|
|
||||||
variant="filled"
|
|
||||||
type="password"
|
|
||||||
onChange={handlePasswordChange}
|
|
||||||
value={password}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
onClick={saveKeyPair}
|
|
||||||
disabled={!password || !ethDmKeyPair}
|
|
||||||
>
|
|
||||||
Save Eth-DM Key Pair to storage
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue