This commit is contained in:
2020-08-21 22:53:46 +02:00
parent c5db725b8c
commit 42e8de1473
12 changed files with 128 additions and 94 deletions

View File

@@ -15,7 +15,7 @@ jobs:
- name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built. - name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built.
run: | run: |
yarn install yarn install
yarn build NODE_ENV=production yarn build
- name: Deploy 🚀 - name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@3.5.9 uses: JamesIves/github-pages-deploy-action@3.5.9

View File

@@ -8,8 +8,8 @@ import AppRouter from './Router';
const App: React.FC = () => ( const App: React.FC = () => (
<GithubProvider username="morten-olsen"> <GithubProvider username="morten-olsen">
<EncryptionProvider> <EncryptionProvider>
<Layout> <Layout style={{minHeight:"100vh"}}>
<Layout.Content style={{ padding: '25px' }}> <Layout.Content style={{ padding: '25px', flex: 1 }}>
<AppRouter/> <AppRouter/>
</Layout.Content> </Layout.Content>
</Layout> </Layout>

View File

@@ -6,6 +6,7 @@ import {
} from 'react-router-dom'; } from 'react-router-dom';
import Encrypt from './screens/Encrypt'; import Encrypt from './screens/Encrypt';
import Welcome from './screens/Welcome';
import Debug from './screens/Debug'; import Debug from './screens/Debug';
const AppRouter: React.FC = () => ( const AppRouter: React.FC = () => (
@@ -14,6 +15,9 @@ const AppRouter: React.FC = () => (
<Route path="/debug"> <Route path="/debug">
<Debug /> <Debug />
</Route> </Route>
<Route path="/welcome">
<Welcome />
</Route>
<Route path="/"> <Route path="/">
<Encrypt /> <Encrypt />
</Route> </Route>

View File

@@ -1,46 +1,22 @@
import React, { Fragment, useState } from 'react'; import React, { useState } from 'react';
import { Menu, Dropdown, Form } from 'antd'; import { Radio, Divider } from 'antd';
import { DownOutlined, FileOutlined, FileTextOutlined } from '@ant-design/icons'; import { FileOutlined, FileTextOutlined } from '@ant-design/icons';
import AddText from './AddText'; import AddText from './AddText';
import AddFile from './AddFile'; import AddFile from './AddFile';
const layout = { const DEFAULT_VALUE = 'text';
labelCol: { span: 2 },
};
const Add: React.FC = () => { const Add: React.FC = () => {
const [type, setType] = useState<'file' | 'text'>('text'); const [type, setType] = useState<'file' | 'text'>(DEFAULT_VALUE);
const menu = (
<Menu>
<Menu.Item
onClick={() => setType('file')}
active={type === 'file'}
icon={<FileOutlined />}
>
File
</Menu.Item>
<Menu.Item
onClick={() => setType('text')}
active={type === 'text'}
icon={<FileTextOutlined />}
>
Text
</Menu.Item>
</Menu>
);
return ( return (
<> <>
<Form {...layout}> <Divider>
<Form.Item <Radio.Group onChange={evt => setType(evt.target.value)} defaultValue={DEFAULT_VALUE}>
label="I want to encrypt a" <Radio.Button value="text"><FileTextOutlined /> Text</Radio.Button>
> <Radio.Button value="file"><FileOutlined /> File</Radio.Button>
<Dropdown overlay={menu}> </Radio.Group>
<a>{type} <DownOutlined /></a> </Divider>
</Dropdown>
</Form.Item>
</Form>
{type === 'text' && <AddText />} {type === 'text' && <AddText />}
{type === 'file' && <AddFile />} {type === 'file' && <AddFile />}
</> </>

View File

@@ -1,12 +1,13 @@
import React, { useContext, useCallback } from 'react'; import React, { useContext, useCallback } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { Layout } from 'antd'; import { Layout } from 'antd';
import { UploadOutlined } from '@ant-design/icons'; import { FileAddTwoTone } from '@ant-design/icons';
import { useDropzone } from 'react-dropzone'; import { useDropzone } from 'react-dropzone';
import EncryptionContext from '../contexts/Encryption'; import EncryptionContext from '../contexts/Encryption';
const Icon = styled(UploadOutlined)` const Icon = styled(FileAddTwoTone)`
font-size: 100px; font-size: 100px;
margin-bottom: 20px;
`; `;
const DropWrapper = styled(Layout)` const DropWrapper = styled(Layout)`

View File

@@ -3,14 +3,6 @@ import { Input, Form, Button } from 'antd';
import { PlusOutlined } from '@ant-design/icons'; import { PlusOutlined } from '@ant-design/icons';
import EncryptionContext from '../contexts/Encryption'; import EncryptionContext from '../contexts/Encryption';
const layout = {
labelCol: { span: 2 },
};
const tailLayout = {
wrapperCol: { offset: 2 },
};
const AddText : React.FC = () => { const AddText : React.FC = () => {
const { addText } = useContext(EncryptionContext); const { addText } = useContext(EncryptionContext);
const [name, setName] = useState(''); const [name, setName] = useState('');
@@ -23,25 +15,23 @@ const AddText : React.FC = () => {
}, [text, addText]); }, [text, addText]);
return ( return (
<Form {...layout}> <Form>
<Form.Item <Form.Item>
label="Name"
>
<Input <Input
placeholder="Title"
value={name} value={name}
onChange={evt => setName(evt.target.value)} onChange={evt => setName(evt.target.value)}
/> />
</Form.Item> </Form.Item>
<Form.Item <Form.Item>
label="Message"
>
<Input.TextArea <Input.TextArea
placeholder="Your message here..."
value={text} value={text}
rows={10} rows={6}
onChange={evt => setText(evt.target.value)} onChange={evt => setText(evt.target.value)}
/> />
</Form.Item> </Form.Item>
<Form.Item {...tailLayout}> <Form.Item>
<Button <Button
onClick={add} onClick={add}
type="primary" type="primary"

View File

@@ -2,6 +2,8 @@ import React, {useMemo} from 'react';
import { import {
List, List,
Button, Button,
Tooltip,
Popconfirm,
} from 'antd'; } from 'antd';
import { import {
DeleteOutlined, DeleteOutlined,
@@ -46,12 +48,12 @@ const share = async (file: FileType, fileData: File[]) => {
} }
const IconText = ({ icon, text, ...props }) => ( const IconText = ({ icon, text, ...props }) => (
<Tooltip title={text}>
<Button <Button
{...props} {...props}
icon={React.createElement(icon)} icon={React.createElement(icon)}
> />
{text} </Tooltip>
</Button>
); );
const FileView: React.FC<Props> = ({ const FileView: React.FC<Props> = ({
@@ -67,12 +69,18 @@ const FileView: React.FC<Props> = ({
if (file.link) { if (file.link) {
actions.push( actions.push(
<Popconfirm
title="Are you sure delete this file?"
onConfirm={remove}
okText="Yes"
cancelText="No"
>
<IconText <IconText
icon={DeleteOutlined} icon={DeleteOutlined}
danger danger
text="Delete" text="Delete"
onClick={remove}
/> />
</Popconfirm>
); );
} }

View File

@@ -58,7 +58,6 @@ const EncryptionProvider: React.FC = ({
const add = (name: string) => { const add = (name: string) => {
const id = nanoid(); const id = nanoid();
message.info(`Beginning to encrypt ${name}`);
const file: FileType = { const file: FileType = {
name: `${name}.asc`, name: `${name}.asc`,
reciever: username, reciever: username,

View File

@@ -4,5 +4,6 @@ import { render } from 'react-dom';
import App from './App'; import App from './App';
const root = document.createElement('div'); const root = document.createElement('div');
root.style.height = '100%';
document.body.appendChild(root); document.body.appendChild(root);
render(<App />, root); render(<App />, root);

View File

@@ -1,32 +1,28 @@
import React, { useContext } from 'react'; import React, { useContext, useEffect } from 'react';
import { Collapse, Badge } from 'antd'; import { Divider, PageHeader } from 'antd';
import Profile from '../components/Profile'; import { useHistory } from 'react-router';
import Add from '../components/Add'; import Add from '../components/Add';
import FileList from '../components/FileList'; import FileList from '../components/FileList';
import EncryptionContext from '../contexts/Encryption'; import EncryptionContext from '../contexts/Encryption';
const Encrypt: React.FC = () => { const Encrypt: React.FC = () => {
const history = useHistory();
const { files } = useContext(EncryptionContext); const { files } = useContext(EncryptionContext);
useEffect(() => {
if (localStorage.getItem('welcome') !== 'seen') {
history.replace('/welcome');
}
}, []);
return ( return (
<> <>
<Collapse ghost defaultActiveKey={[2, 3]}>
<Collapse.Panel key={2} header="Encrypt">
<Add /> <Add />
</Collapse.Panel> {Object.keys(files).length > 0 && (
<Collapse.Panel <>
key={3} <Divider>Files</Divider>
header={(
<Badge count={Object.keys(files).length} offset={[20, 7]}>
Files
</Badge>
)}
>
<FileList /> <FileList />
</Collapse.Panel> </>
<Collapse.Panel key={1} header="Profile"> )}
<Profile />
</Collapse.Panel>
</Collapse>
</> </>
); );
}; };

54
src/screens/Welcome.tsx Normal file
View File

@@ -0,0 +1,54 @@
import React, { useEffect } from 'react';
import { Space, Layout, Button, Typography, notification } from 'antd';
import { AlignLeftOutlined, EyeInvisibleTwoTone, ArrowRightOutlined } from '@ant-design/icons';
import { useHistory } from 'react-router';
const openNotification = () => {
notification.warn({
message: 'Slow down!',
description: 'I am still working on this, but thanks for the interrest.'
});
};
const Welcome: React.FC = () => {
const history = useHistory();
useEffect(() => {
localStorage.setItem('welcome', 'seen');
});
return (
<Layout style={{ maxWidth: 800, margin: 'auto', textAlign: 'center' }}>
<Space direction="vertical">
<EyeInvisibleTwoTone style={{ fontSize: 200 }} />
<Typography.Title level={1}>Protect before sending</Typography.Title>
<p>
The internet can seem like a scary place, especially if you want to send sensitiv information across it.
</p>
<p>
The truth is that a lot of systems, including e-mails, was not build for the internet that we have today.
</p>
<p>
This is why it is so important to make sure your documents are well protected before sharing.
</p>
<p>
This tool can be used to protect information before sharing them with me. The documents will be encrypted so that only I can ever unlock them, so no snoppy man in the middle...
</p>
<Button
type="primary"
icon={<ArrowRightOutlined />}
onClick={() => history.push('/')}
>
Start protecting!
</Button>
<Button
icon={<AlignLeftOutlined />}
onClick={openNotification}
>
Read all the technical stuff
</Button>
</Space>
</Layout>
);
};
export default Welcome;

View File

@@ -1,12 +1,14 @@
import webpack, { Configuration } from 'webpack'; import { Configuration } from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin'; import HtmlWebpackPlugin from 'html-webpack-plugin';
import path from 'path'; import path from 'path';
const __DEV__ = process.env.NODE_ENV !== 'production';
const config: Configuration = { const config: Configuration = {
mode: 'development', mode: __DEV__ ? 'development' : 'production',
entry: { entry: {
app: [ app: [
'react-hot-loader/patch', ...(__DEV__ ? ['react-hot-loader/patch'] : []),
path.join(__dirname, 'src', 'index.tsx'), path.join(__dirname, 'src', 'index.tsx'),
], ],
}, },
@@ -20,7 +22,10 @@ const config: Configuration = {
}, },
}, },
plugins: [ plugins: [
new HtmlWebpackPlugin(), new HtmlWebpackPlugin({
title: 'Parcel',
minify: true,
}),
], ],
module: { module: {
rules: [{ rules: [{