Skip to content

Commit 2c56580

Browse files
committed
refactoring socket connection
1 parent fb0b701 commit 2c56580

11 files changed

+440
-175
lines changed

index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<html>
33
<head>
44
<meta charset="UTF-8" />
5-
<title>Hello World!</title>
5+
<title>Aeromap</title>
66

77
</head>
88
<body>

package-lock.json

+34
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"typescript": "~4.5.4"
4040
},
4141
"dependencies": {
42+
"@foxglove/electron-socket": "^2.1.1",
4243
"electron-settings": "^4.0.2",
4344
"electron-squirrel-startup": "^1.0.0",
4445
"flowbite": "^2.2.1",

src/app.tsx

+71-18
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,91 @@ import { useState, useEffect } from 'react'
22

33
import Map from './components/Map'
44

5+
type Qs121 = {
6+
pitch: number,
7+
bank: number,
8+
heading: number,
9+
altitude: number,
10+
tas: number,
11+
lat: number,
12+
lon: number
13+
};
14+
515
export default function App() {
16+
const [host, setHost] = useState('127.0.0.1')
17+
const [port, setPort] = useState(10747)
618
const [connected, setConnected] = useState(false)
19+
const [connecting, setConnecting] = useState(false)
720
const [viewState, setViewState] = useState({
821
bearing: 0,
922
longitude: 0.051536548427520756,
1023
latitude: 51.50527121507392,
1124
});
1225

1326
useEffect(() => {
14-
const interval = setInterval(async () => {
15-
const currectConnected = () => connected;
16-
if (!currectConnected) return
17-
const pos = await window.api.getPosition()
18-
setViewState({...viewState, longitude: pos.lng, latitude: pos.lat, bearing: pos.hdg})
19-
}, 250);
20-
return () => clearInterval(interval);
21-
}, []);
27+
window.aerowinxApi.onConnected(() => {
28+
console.log('Connected to Aerowinx');
29+
setConnected(true);
30+
setConnecting(false);
31+
});
2232

23-
useEffect(() => {
24-
const currectConnected = () => connected;
25-
const interval = setInterval(async () => {
26-
if (currectConnected) return
27-
const connection = await window.api.getConnection()
28-
setConnected(connection)
29-
}, 1000);
33+
window.aerowinxApi.onClosed(() => {
34+
console.log('Disconnected from Aerowinx');
35+
setConnected(false);
36+
setConnecting(false);
37+
});
38+
39+
window.aerowinxApi.onError((error: string) => {
40+
console.error(error);
41+
setConnected(false);
42+
setConnecting(false);
43+
});
44+
45+
window.aerowinxApi.onTimeout(() => {
46+
console.error('Connection to Aerowinx timed out');
47+
setConnected(false);
48+
setConnecting(false);
49+
});
50+
51+
window.aerowinxApi.onQs121((data: Qs121) => {
52+
if(Object.values(data).some(v => Number.isNaN(v))) return;
53+
setViewState({...viewState, longitude: data.lon, latitude: data.lat, bearing: data.heading})
54+
});
55+
56+
connectAerowinx();
57+
58+
return () => {
59+
window.aerowinxApi.removeListeners();
60+
}
61+
62+
}, [])
63+
64+
const connectAerowinx = () => {
65+
window.aerowinxApi.connect({host, port})
66+
setConnecting(true);
67+
}
3068

31-
return () => clearInterval(interval);
32-
}, []);
69+
const disconnectAerowinx = () => {
70+
window.aerowinxApi.close();
71+
setConnecting(false);
72+
}
3373

3474
return (
3575
<>
36-
<Map viewState={viewState} setViewState={setViewState} defaultZoom={17} />
76+
<Map
77+
viewState={viewState}
78+
setViewState={setViewState}
79+
defaultZoom={17}
80+
host={host}
81+
port={port}
82+
setHost={setHost}
83+
setPort={setPort}
84+
connecting={connecting}
85+
setConnecting={setConnecting}
86+
connected={connected}
87+
connectAerowinx={connectAerowinx}
88+
disconnectAerowinx={disconnectAerowinx}
89+
/>
3790
</>
3891
)
3992
}

src/components/Map.tsx

+30-4
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,26 @@ type AeromapViewState = {
1313
latitude: number;
1414
}
1515

16-
export default function AeroMap({ viewState, setViewState, defaultZoom }: { viewState: AeromapViewState, setViewState: Function, defaultZoom: number }) {
16+
export default function AeroMap(
17+
{ viewState, setViewState, defaultZoom, host, port, setHost, setPort, connecting, setConnecting, connected, connectAerowinx, disconnectAerowinx }:
18+
{
19+
viewState: AeromapViewState,
20+
setViewState: Function,
21+
defaultZoom: number,
22+
host: string,
23+
port: number,
24+
setHost: Function,
25+
setPort: Function,
26+
connecting: boolean,
27+
setConnecting: Function,
28+
connected: boolean,
29+
connectAerowinx: Function,
30+
disconnectAerowinx: Function
31+
}
32+
) {
1733
const [mapStyle, setMapStyle] = useState('openstreetmap');
1834
const [zoom, setZoom] = useState(defaultZoom);
19-
35+
2036
return (
2137
<Map
2238
{...viewState}
@@ -32,13 +48,23 @@ export default function AeroMap({ viewState, setViewState, defaultZoom }: { view
3248
style={{ height: '100vh', width: '100vw' }}
3349
mapStyle={getMapStyle(mapStyle)}
3450
>
35-
<nav className="absolute top-4 left-4">
51+
<nav className="absolute top-4 left-4 flex space-x-2">
3652
<Button.Group>
3753
{MAP_STYLES.map(({ name, label }) => (
3854
<Button className="focus:ring-0" color="gray" onClick={() => setMapStyle(name)} key={name}>{label}</Button>
3955
))}
4056
</Button.Group>
41-
<Settings />
57+
<Settings
58+
host={host}
59+
port={port}
60+
setHost={setHost}
61+
setPort={setPort}
62+
connecting={connecting}
63+
setConnecting={setConnecting}
64+
connected={connected}
65+
connectAerowinx={connectAerowinx}
66+
disconnectAerowinx={disconnectAerowinx}
67+
/>
4268
</nav>
4369
<NavigationControl showCompass={false} />
4470
<ScaleControl />

src/components/Settings.tsx

+46-25
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11

2-
import { set } from 'electron-settings';
3-
import { Button, Modal, ToggleSwitch, Label, TextInput } from 'flowbite-react';
2+
import { Button, Modal, ToggleSwitch, Label, TextInput, FooterDivider } from 'flowbite-react';
43
import { useEffect, useState } from 'react';
54

6-
export function Settings() {
5+
export function Settings({ host, port, setHost, setPort, connecting, setConnecting, connected, connectAerowinx, disconnectAerowinx }:
6+
{ host: string, port: number, setHost: Function, setPort: Function, connecting: boolean, setConnecting: Function, connected: boolean, connectAerowinx: Function, disconnectAerowinx: Function }) {
77
const [openModal, setOpenModal] = useState(false);
88
const [alwaysOnTop, setAlwaysOnTop] = useState(false);
9-
const [host, setHost] = useState('127.0.0.1');
10-
const [port, setPort] = useState('10747');
9+
const [autoConnect, setAutoConnect] = useState(true);
1110

12-
useEffect(() => {
13-
const getSettings = async () => {
14-
const currentAlwaysOnTop = await window.api.getAlwaysOnTop()
15-
setAlwaysOnTop(currentAlwaysOnTop)
11+
// useEffect(() => {
12+
// const getSettings = async () => {
13+
// const currentAlwaysOnTop = await window.api.getAlwaysOnTop()
14+
// setAlwaysOnTop(currentAlwaysOnTop)
1615

17-
const currentHost = await window.api.getHost()
18-
setHost(currentHost)
16+
// const currentHost = await window.api.getHost()
17+
// setHost(currentHost)
1918

20-
const currentPort = await window.api.getPort()
21-
setPort(currentPort)
22-
}
23-
getSettings();
24-
}, []);
19+
// const currentPort = await window.api.getPort()
20+
// setPort(currentPort)
21+
// }
22+
// getSettings();
23+
// }, []);
2524

2625
const onChangeAlwaysOnTop = () => {
2726
const nextAlwaysOnTop = !alwaysOnTop;
@@ -32,13 +31,17 @@ export function Settings() {
3231
const onChangeHost = (event: React.ChangeEvent<HTMLInputElement>) => {
3332
const nextHost = event.target.value;
3433
setHost(nextHost);
35-
window.api.setHost(nextHost);
3634
}
3735

3836
const onChangePort = (event: React.ChangeEvent<HTMLInputElement>) => {
3937
const nextPort = event.target.value;
4038
setPort(nextPort);
41-
window.api.setPort(nextPort);
39+
}
40+
41+
const onChangeAutoConnect = () => {
42+
const nextAutoConnect = !autoConnect;
43+
setAutoConnect(nextAutoConnect);
44+
window.aerowinxApi.setAutoConnect(nextAutoConnect);
4245
}
4346

4447
return (
@@ -52,7 +55,7 @@ export function Settings() {
5255
<div className="mb-2 block">
5356
<Label htmlFor="host" value="Host" />
5457
</div>
55-
<TextInput id="host" type="text" placeholder="127.0.0.1" value={host} onChange={onChangeHost}/>
58+
<TextInput id="host" type="text" placeholder="127.0.0.1" value={host} onChange={onChangeHost} />
5659
</div>
5760
<div>
5861
<div className="mb-2 block">
@@ -64,13 +67,31 @@ export function Settings() {
6467
<ToggleSwitch checked={alwaysOnTop} label="Always on top" onChange={onChangeAlwaysOnTop} />
6568
</div>
6669
</form>
70+
<FooterDivider />
71+
<div className="grid grid-cols-2">
72+
<div className="flex flex-col space-y-2">
73+
<dl className="flex flex-col gap-2">
74+
<dt>Connected</dt>
75+
<dd>{connected ? 'Yes' : 'No'}</dd>
76+
</dl>
77+
<dl className="flex flex-col gap-2">
78+
<dt>Connecting</dt>
79+
<dd>{connecting ? 'Yes' : 'No'}</dd>
80+
</dl>
81+
</div>
82+
<div className="flex flex-col space-y-4">
83+
<div className="flex space-x-2">
84+
<Button onClick={() => connectAerowinx()} disabled={connected || connecting}>Connect</Button>
85+
<Button color="gray" onClick={() => disconnectAerowinx()} disabled={!connected && !connecting}>
86+
Disconnect
87+
</Button>
88+
</div>
89+
<div>
90+
<ToggleSwitch checked={autoConnect} label="Auto-connect" onChange={onChangeAutoConnect} />
91+
</div>
92+
</div>
93+
</div>
6794
</Modal.Body>
68-
<Modal.Footer>
69-
<Button onClick={() => setOpenModal(false)}>I accept</Button>
70-
<Button color="gray" onClick={() => setOpenModal(false)}>
71-
Decline
72-
</Button>
73-
</Modal.Footer>
7495
</Modal>
7596
</>
7697
);

0 commit comments

Comments
 (0)