-
Notifications
You must be signed in to change notification settings - Fork 24
/
App.tsx
152 lines (136 loc) · 6.14 KB
/
App.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import React from 'react';
import {Button, Card, Col, Input, Menu, MenuProps, message, Row, Space, Typography, Upload, UploadFile} from "antd";
import {CopyOutlined, UploadOutlined} from "@ant-design/icons";
import {useAppDispatch, useAppSelector} from "./store/hooks";
import {startPeer, stopPeerSession} from "./store/peer/peerActions";
import * as connectionAction from "./store/connection/connectionActions"
import {DataType, PeerConnection} from "./helpers/peer";
import {useAsyncState} from "./helpers/hooks";
const {Title} = Typography
type MenuItem = Required<MenuProps>['items'][number]
function getItem(
label: React.ReactNode,
key: React.Key,
icon?: React.ReactNode,
children?: MenuItem[],
type?: 'group',
): MenuItem {
return {
key,
icon,
children,
label,
type,
} as MenuItem;
}
export const App: React.FC = () => {
const peer = useAppSelector((state) => state.peer)
const connection = useAppSelector((state) => state.connection)
const dispatch = useAppDispatch()
const handleStartSession = () => {
dispatch(startPeer())
}
const handleStopSession = async () => {
await PeerConnection.closePeerSession()
dispatch(stopPeerSession())
}
const handleConnectOtherPeer = () => {
connection.id != null ? dispatch(connectionAction.connectPeer(connection.id || "")) : message.warning("Please enter ID")
}
const [fileList, setFileList] = useAsyncState([] as UploadFile[])
const [sendLoading, setSendLoading] = useAsyncState(false)
const handleUpload = async () => {
if (fileList.length === 0) {
message.warning("Please select file")
return
}
if (!connection.selectedId) {
message.warning("Please select a connection")
return
}
try {
await setSendLoading(true);
let file = fileList[0] as unknown as File;
let blob = new Blob([file], {type: file.type});
await PeerConnection.sendConnection(connection.selectedId, {
dataType: DataType.FILE,
file: blob,
fileName: file.name,
fileType: file.type
})
await setSendLoading(false)
message.info("Send file successfully")
} catch (err) {
await setSendLoading(false)
console.log(err)
message.error("Error when sending file")
}
}
return (
<Row justify={"center"} align={"top"}>
<Col xs={24} sm={24} md={20} lg={16} xl={12}>
<Card>
<Title level={2} style={{textAlign: "center"}}>P2P File Transfer</Title>
<Card hidden={peer.started}>
<Button onClick={handleStartSession} loading={peer.loading}>Start</Button>
</Card>
<Card hidden={!peer.started}>
<Space direction="horizontal">
<div>ID: {peer.id}</div>
<Button icon={<CopyOutlined/>} onClick={async () => {
await navigator.clipboard.writeText(peer.id || "")
message.info("Copied: " + peer.id)
}}/>
<Button danger onClick={handleStopSession}>Stop</Button>
</Space>
</Card>
<div hidden={!peer.started}>
<Card>
<Space direction="horizontal">
<Input placeholder={"ID"}
onChange={e => dispatch(connectionAction.changeConnectionInput(e.target.value))}
required={true}
/>
<Button onClick={handleConnectOtherPeer}
loading={connection.loading}>Connect</Button>
</Space>
</Card>
<Card title="Connection">
{
connection.list.length === 0
? <div>Waiting for connection ...</div>
: <div>
Select a connection
<Menu selectedKeys={connection.selectedId ? [connection.selectedId] : []}
onSelect={(item) => dispatch(connectionAction.selectItem(item.key))}
items={connection.list.map(e => getItem(e, e, null))}/>
</div>
}
</Card>
<Card title="Send File">
<Upload fileList={fileList}
maxCount={1}
onRemove={() => setFileList([])}
beforeUpload={(file) => {
setFileList([file])
return false
}}>
<Button icon={<UploadOutlined/>}>Select File</Button>
</Upload>
<Button
type="primary"
onClick={handleUpload}
disabled={fileList.length === 0}
loading={sendLoading}
style={{marginTop: 16}}
>
{sendLoading ? 'Sending' : 'Send'}
</Button>
</Card>
</div>
</Card>
</Col>
</Row>
)
}
export default App