diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 2d91894..2e77ef9 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -30,4 +30,4 @@ jobs:
npm run make
npm run publish
env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/src/app.tsx b/src/app.tsx
index 8f5a01b..1d6d828 100644
--- a/src/app.tsx
+++ b/src/app.tsx
@@ -17,13 +17,22 @@ export default function App() {
const [port, setPort] = useState(10747)
const [connected, setConnected] = useState(false)
const [connecting, setConnecting] = useState(false)
- const [viewState, setViewState] = useState({
+ const [aircraftPosition, setAircraftPosition] = useState({
bearing: 0,
longitude: 0.051536548427520756,
latitude: 51.50527121507392,
});
+
useEffect(() => {
+ const getSavedConnection = async () => {
+ const savedHost = await window.api.getHost();
+ if (savedHost) setHost(savedHost);
+ const savedPort = await window.api.getPort();
+ if (savedPort) setPort(savedPort);
+ connectAerowinx();
+ }
+
window.aerowinxApi.onConnected(() => {
console.log('Connected to Aerowinx');
setConnected(true);
@@ -49,11 +58,11 @@ export default function App() {
});
window.aerowinxApi.onQs121((data: Qs121) => {
- if(Object.values(data).some(v => Number.isNaN(v))) return;
- setViewState({...viewState, longitude: data.lon, latitude: data.lat, bearing: data.heading})
+ if (Object.values(data).some(v => Number.isNaN(v))) return;
+ setAircraftPosition({ ...aircraftPosition, longitude: data.lon, latitude: data.lat, bearing: data.heading })
});
- connectAerowinx();
+ getSavedConnection();
return () => {
window.aerowinxApi.removeListeners();
@@ -62,7 +71,7 @@ export default function App() {
}, [])
const connectAerowinx = () => {
- window.aerowinxApi.connect({host, port})
+ window.aerowinxApi.connect({ host, port })
setConnecting(true);
}
@@ -74,8 +83,7 @@ export default function App() {
return (
<>
+ />
>
)
}
\ No newline at end of file
diff --git a/src/components/Map.tsx b/src/components/Map.tsx
index 9308b56..167ed8f 100644
--- a/src/components/Map.tsx
+++ b/src/components/Map.tsx
@@ -1,4 +1,4 @@
-import { useState } from 'react';
+import { useEffect, useState } from 'react';
import { Map, Marker, ScaleControl, NavigationControl, FullscreenControl, ViewState } from 'react-map-gl/maplibre';
import { Button } from 'flowbite-react';
import 'maplibre-gl/dist/maplibre-gl.css';
@@ -14,30 +14,42 @@ type AeromapViewState = {
}
export default function AeroMap(
- { viewState, setViewState, defaultZoom, host, port, setHost, setPort, connecting, setConnecting, connected, connectAerowinx, disconnectAerowinx }:
- {
- viewState: AeromapViewState,
- setViewState: (viewState: React.SetStateAction) => void,
- defaultZoom: number,
- host: string,
- port: number,
- setHost: (host: React.SetStateAction) => void,
- setPort: (port: React.SetStateAction) => void,
- connecting: boolean,
- setConnecting: (isConnecting: React.SetStateAction) => void,
- connected: boolean,
- connectAerowinx: () => void,
- disconnectAerowinx: () => void
- }
+ { aircraftPosition, defaultZoom, host, port, setHost, setPort, connecting, setConnecting, connected, connectAerowinx, disconnectAerowinx }:
+ {
+ aircraftPosition: AeromapViewState,
+ defaultZoom: number,
+ host: string,
+ port: number,
+ setHost: (host: React.SetStateAction) => void,
+ setPort: (port: React.SetStateAction) => void,
+ connecting: boolean,
+ setConnecting: (isConnecting: React.SetStateAction) => void,
+ connected: boolean,
+ connectAerowinx: () => void,
+ disconnectAerowinx: () => void
+ }
) {
const [mapStyle, setMapStyle] = useState('openstreetmap');
+ const [viewState, setViewState] = useState(aircraftPosition);
const [zoom, setZoom] = useState(defaultZoom);
+ const [userControl, setUserControl] = useState(false);
+
+ useEffect(() => {
+ if (userControl) return;
+ setViewState(aircraftPosition);
+ }, [aircraftPosition]);
+
+ function backToCenter() {
+ setViewState(aircraftPosition);
+ setUserControl(false);
+ }
return (
diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx
index 18667cc..32a6bce 100644
--- a/src/components/Settings.tsx
+++ b/src/components/Settings.tsx
@@ -28,11 +28,13 @@ export function Settings(
const onChangeHost = (event: React.ChangeEvent) => {
const nextHost = event.target.value;
setHost(nextHost);
+ window.api.setHost(nextHost);
}
const onChangePort = (event: React.ChangeEvent) => {
const nextPort = Number(event.target.value);
setPort(nextPort);
+ window.api.setPort(nextPort);
}
const onChangeAutoConnect = () => {
diff --git a/src/lib/host-settings.js b/src/lib/host-settings.js
deleted file mode 100644
index a9b8240..0000000
--- a/src/lib/host-settings.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import { ipcMain } from 'electron';
-import settings from 'electron-settings';
-
-export const hostSettings = async () => {
- let host;
- let port;
-
- if (await settings.has('host')) {
- host = await settings.get('host');
- } else {
- settings.set('host', '1278.0.0.1');
- }
-
- if (await settings.has('port')) {
- port = await settings.get('port');
- } else {
- settings.set('port', '10747');
- }
-
- const setHost = async (state) => {
- await settings.set('host', state);
- host = state;
- };
-
- const setPort = async (state) => {
- await settings.set('port', state);
- port = state;
- };
-
- return {
- host,
- port,
- setHost,
- setPort,
- };
-};
\ No newline at end of file
diff --git a/src/main.ts b/src/main.ts
index bb11bfd..49917aa 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -3,7 +3,7 @@ import path from 'path';
import { createAerowinxConnection } from './lib/aerowinx-connection';
import { windowStateKeeper } from './lib/window-size';
import { alwaysOnTopStateKeeper } from './lib/always-on-top';
-import { hostSettings } from './lib/host-settings';
+import settings from 'electron-settings';
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) {
@@ -13,7 +13,6 @@ if (require('electron-squirrel-startup')) {
const createWindow = async () => {
const mainWindowStateKeeper = await windowStateKeeper('main');
const mainAlwaysOnTopStateKeeper = await alwaysOnTopStateKeeper('main');
- const mainHostSettings = await hostSettings();
// Create the browser window.
const mainWindow = new BrowserWindow({
@@ -40,7 +39,11 @@ const createWindow = async () => {
const setAlwaysOnTop = (event: IpcMainEvent, state: boolean) => {
mainAlwaysOnTopStateKeeper.setAlwaysOnTopState(state);
- mainWindow.setAlwaysOnTop(state);
+ if(state) {
+ mainWindow.setAlwaysOnTop(state, 'screen-saver');
+ } else {
+ mainWindow.setAlwaysOnTop(state, 'normal');
+ }
}
ipcMain.on('always-on-top:set', setAlwaysOnTop);
@@ -48,31 +51,11 @@ const createWindow = async () => {
return mainAlwaysOnTopStateKeeper.alwaysOnTopState;
});
- ipcMain.handle('host:get', async () => {
- return mainHostSettings.host;
- });
- ipcMain.handle('port:get', async () => {
- return mainHostSettings.port;
- });
-
- const setHost = (event: IpcMainEvent, arg: string) => {
- mainHostSettings.setHost(arg);
- }
- ipcMain.on('host:set', setHost);
- const setPort = (event: IpcMainEvent, arg: string) => {
- mainHostSettings.setPort(arg);
- }
- ipcMain.on('port:set', setPort);
-
createAerowinxConnection(mainWindow);
mainWindow.on('close', function () {
ipcMain.removeHandler('always-on-top:get');
ipcMain.removeListener('always-on-top:set', setAlwaysOnTop);
- ipcMain.removeHandler('host:get');
- ipcMain.removeListener('host:set', setHost);
- ipcMain.removeHandler('port:get');
- ipcMain.removeListener('port:set', setPort);
});
return mainWindow;
@@ -104,4 +87,15 @@ app.on('activate', () => {
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and import them here.
-
+ipcMain.handle('host:set', async (event, data) => {
+ await settings.set('host', data);
+});
+ipcMain.handle('host:get', async () => {
+ return await settings.get('host');
+});
+ipcMain.handle('port:set', async (event, data) => {
+ await settings.set('port', data);
+});
+ipcMain.handle('port:get', async () => {
+ return await settings.get('port');
+});
\ No newline at end of file
diff --git a/src/preload.ts b/src/preload.ts
index 20d8d06..6a91a34 100644
--- a/src/preload.ts
+++ b/src/preload.ts
@@ -6,6 +6,10 @@ import { contextBridge, ipcRenderer } from 'electron';
contextBridge.exposeInMainWorld('api', {
setAlwaysOnTop: (alwaysOnTop: boolean) => ipcRenderer.send('always-on-top:set', alwaysOnTop),
getAlwaysOnTop: () => ipcRenderer.invoke('always-on-top:get'),
+ setHost: (host: string) => ipcRenderer.invoke('host:set', host),
+ getHost: async (): Promise => ipcRenderer.invoke('host:get'),
+ setPort: (port: number) => ipcRenderer.invoke('port:set', port),
+ getPort: async (): Promise => ipcRenderer.invoke('port:get'),
})
contextBridge.exposeInMainWorld('aerowinxApi', {
diff --git a/src/types/index.d.ts b/src/types/index.d.ts
index 0cc19ec..18fcfde 100644
--- a/src/types/index.d.ts
+++ b/src/types/index.d.ts
@@ -5,6 +5,10 @@ declare global {
api: {
setAlwaysOnTop: (alwaysOnTop: boolean) => void,
getAlwaysOnTop: () => Promise,
+ setHost: (host: string) => void,
+ getHost: () => Promise,
+ setPort: (port: number) => void,
+ getPort: () => Promise,
},
aerowinxApi: {
connect: ({ host: string, port: number }) => void,