diff --git a/.github/workflows/build_appimage_bundle.yml b/.github/workflows/build_appimage_bundle.yml new file mode 100644 index 000000000..b1dca3fc0 --- /dev/null +++ b/.github/workflows/build_appimage_bundle.yml @@ -0,0 +1,117 @@ +name: Build and Release APPIMAGE Installer +on: [push] + +jobs: + build-and-release: + runs-on: ubuntu-latest + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Electron Builder + working-directory: gui + run: | + npm i + npm run build + + - name: LIST ALL FILES + run: ls -R + + - name: Install Linux dependencies + run: | + sudo apt install -y portaudio19-dev libhamlib-dev libhamlib-utils build-essential cmake python3-libhamlib2 patchelf + + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Build binaries + working-directory: modem + run: | + python3 -m nuitka --remove-output --assume-yes-for-downloads --follow-imports --include-data-dir=lib=lib --include-data-files=lib/codec2/*=lib/codec2/ --include-data-files=config.ini.example=config.ini --standalone server.py --output-filename=freedata-server + + - name: Prepare AppImage folder + run: | + mkdir -p $HOME/freedata-appimage + + - name: Copy GUI + run: | + cp -r gui/release/linux-unpacked/* $HOME/freedata-appimage/gui + + + - name: Copy server + run: | + cp -r modem/server.dist/* $HOME/freedata-appimage/server + + - name: Copy Icon + run: | + cp gui/build/icon.png $HOME/freedata-appimage/icon.png + + - name: Create Desktop shortcut + run: | + echo ' + # Create desktop file + echo "[Desktop Entry] + Type=Application + Name=FreeDATA + Icon=icon + Exec=AppRun + Categories=Utility ' > $HOME/freedata-appimage/FreeDATA.desktop + + - name: Create AppImage build script + run: | + echo '#!/bin/bash + # Navigate to the AppDir root; this ensures relative paths work as expected + cd "$(dirname "$(readlink -f "${0}")")" + + # check if config exists in ~/.config/FreeDATA/config.ini else create it + SERVER_CONFIG_FILE=~/.config/FreeDATA/config.ini + if test -f "$SERVER_CONFIG_FILE"; then + echo "$SERVER_CONFIG_FILE exists." + else + echo "$SERVER_CONFIG_FILE does not exist. Copying the default one" + mkdir ~/.config/FreeDATA + cp server.dist/config.ini $SERVER_CONFIG_FILE + fi + + export FREEDATA_CONFIG=$SERVER_CONFIG_FILE + + # Launch the main application executable from the linux-unpacked directory + ./linux-unpacked/freedata + + ' > $HOME/AppRun + chmod +x $HOME/freedata-appimage/AppRun + + - name: Download AppImage + run: | + wget https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage -O appimagetool-x86_64.AppImage + chmod +x appimagetool-x86_64.AppImage + + - name: Execute AppImage + run: | + ./appimagetool-x86_64.AppImage freedata-appimage/ + + - name: LIST ALL FILES + run: ls -R + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: 'FreeDATA-x86_64.AppImage' + path: ./$HOME/FreeDATA-x86_64.AppImage + + - name: Upload Installer to Release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/v') + with: + draft: true + files: ./$HOME/FreeDATA-x86_64.AppImage + tag_name: ${{ github.ref_name }} + name: 'FreeDATA-x86_64.AppImage' diff --git a/.github/workflows/build_server.yml b/.github/workflows/build_server.yml index 596129b6d..9b122edd9 100644 --- a/.github/workflows/build_server.yml +++ b/.github/workflows/build_server.yml @@ -48,7 +48,6 @@ jobs: brew install portaudio python -m pip install --upgrade pip pip3 install pyaudio - export PYTHONPATH=/Library/Frameworks/Python.framework/Versions/3.11/lib/:$PYTHONPATH - name: Install Python dependencies run: | diff --git a/.github/workflows/pip_package.yml b/.github/workflows/pip_package.yml new file mode 100644 index 000000000..2cae29915 --- /dev/null +++ b/.github/workflows/pip_package.yml @@ -0,0 +1,38 @@ +name: Deploy Python Package +on: + push: + tags: + - '*' + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install Linux dependencies + run: | + sudo apt install -y portaudio19-dev libhamlib-dev libhamlib-utils build-essential cmake python3-libhamlib2 patchelf + + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install wheel + + - name: Build package + run: | + python setup.py sdist bdist_wheel + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@v1.4.2 + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/gui/electron/main/index.ts b/gui/electron/main/index.ts index 112cca9bf..0b6005f61 100644 --- a/gui/electron/main/index.ts +++ b/gui/electron/main/index.ts @@ -111,11 +111,12 @@ app.whenReady().then(() => { //serverProcess = spawn(serverPath, [], { detached: true }); //serverProcess.unref(); // Allow the server process to continue running independently of the parent process // break; - //case "linux": - //serverPath = join(basePath, "freedata-server", "freedata-server.exe"); - //serverProcess = spawn(serverPath, [], { detached: true }); - //serverProcess.unref(); // Allow the server process to continue running independently of the parent process - // break; + case "linux": + serverPath = join(basePath, "server.dist", "freedata-server"); + console.log(`Starting server with path: ${serverPath}`); + serverProcess = spawn(serverPath, [], { detached: true }); + serverProcess.unref(); // Allow the server process to continue running independently of the parent process + break; case "win32": serverPath = join(basePath, "freedata-server", "freedata-server.exe"); console.log(`Starting server with path: ${serverPath}`); diff --git a/gui/package.json b/gui/package.json index 8cf5638d0..1ac0e6555 100644 --- a/gui/package.json +++ b/gui/package.json @@ -2,7 +2,7 @@ "name": "FreeDATA", "description": "FreeDATA Client application for connecting to FreeDATA server", "private": true, - "version": "0.14.5-alpha", + "version": "0.15.2-alpha", "main": "dist-electron/main/index.js", "scripts": { "start": "vite", diff --git a/gui/src/assets/waterfall/spectrum.js b/gui/src/assets/waterfall/spectrum.js index fb93bd617..11aadd24c 100644 --- a/gui/src/assets/waterfall/spectrum.js +++ b/gui/src/assets/waterfall/spectrum.js @@ -105,6 +105,8 @@ Spectrum.prototype.drawSpectrum = function () { var linePositionHigh = 178.4; //150 + bandwidth/20 var linePositionLow2 = 65; //150 - bandwith/20 var linePositionHigh2 = 235; //150 + bandwith/20 + var linePositionLow3 = 28.1; //150 - bandwith/20 + var linePositionHigh3 = 271.9; //150 + bandwith/20 this.ctx_wf.beginPath(); this.ctx_wf.moveTo(linePositionLow, 0); this.ctx_wf.lineTo(linePositionLow, height); @@ -114,6 +116,10 @@ Spectrum.prototype.drawSpectrum = function () { this.ctx_wf.lineTo(linePositionLow2, height); this.ctx_wf.moveTo(linePositionHigh2, 0); this.ctx_wf.lineTo(linePositionHigh2, height); + this.ctx_wf.moveTo(linePositionLow3, 0); + this.ctx_wf.lineTo(linePositionLow3, height); + this.ctx_wf.moveTo(linePositionHigh3, 0); + this.ctx_wf.lineTo(linePositionHigh3, height); this.ctx_wf.lineWidth = 1; this.ctx_wf.strokeStyle = "#C3C3C3"; this.ctx_wf.stroke(); @@ -454,7 +460,7 @@ export function Spectrum(id, options) { this.centerHz = options && options.centerHz ? options.centerHz : 1500; this.spanHz = options && options.spanHz ? options.spanHz : 0; this.wf_size = options && options.wf_size ? options.wf_size : 0; - this.wf_rows = options && options.wf_rows ? options.wf_rows : 1024; + this.wf_rows = options && options.wf_rows ? options.wf_rows : 512; this.spectrumPercent = options && options.spectrumPercent ? options.spectrumPercent : 0; this.spectrumPercentStep = diff --git a/gui/src/components/dynamic_components.vue b/gui/src/components/dynamic_components.vue index 6229187f4..e55a4a5c8 100644 --- a/gui/src/components/dynamic_components.vue +++ b/gui/src/components/dynamic_components.vue @@ -32,8 +32,7 @@ import grid_freq from "./grid/grid_frequency.vue"; import grid_beacon from "./grid/grid_beacon.vue"; import grid_mycall_small from "./grid/grid_mycall small.vue"; import grid_scatter from "./grid/grid_scatter.vue"; -import { stateDispatcher } from "../js/eventHandler"; -import { Scatter } from "vue-chartjs"; +import grid_stats_chart from "./grid/grid_stats_chart.vue"; let count = ref(0); let grid = null; // DO NOT use ref(null) as proxies GS will break all logic when comparing structures... see https://github.com/gridstack/gridstack.js/issues/2115 @@ -63,7 +62,8 @@ class gridWidget { this.id = id; } } -//Array of grid widgets, do not change array order as it'll affect saved configs +//Array of grid widgets +//Order can be changed so sorted correctly, but do not change ID as it'll affect saved configs const gridWidgets = [ new gridWidget( grid_activities, @@ -247,8 +247,16 @@ new gridWidget( "Stats", 19, ), - - //New new widget ID should be 20 + new gridWidget( + grid_stats_chart, + { x: 0, y: 114, w: 6, h: 30 }, + "Speed/SNR graph", + false, + true, + "Stats", + 20, + ), + //Next new widget ID should be 21 ]; diff --git a/gui/src/components/grid/grid_active_broadcasts_vert.vue b/gui/src/components/grid/grid_active_broadcasts_vert.vue index f1290fdc5..e04333c8a 100644 --- a/gui/src/components/grid/grid_active_broadcasts_vert.vue +++ b/gui/src/components/grid/grid_active_broadcasts_vert.vue @@ -15,11 +15,22 @@ function transmitPing() { function startStopBeacon() { if (state.beacon_state === true) { - setModemBeacon(false); + setModemBeacon(false, state.away_from_key); } else { - setModemBeacon(true); + setModemBeacon(true, state.away_from_key); } } + +function setAwayFromKey(){ + if (state.away_from_key === true) { + setModemBeacon(state.beacon_state, false); + } else { + setModemBeacon(state.beacon_state, true); + } + +} + + var dxcallPing = ref(""); window.addEventListener( "stationSelected", @@ -39,7 +50,7 @@ window.addEventListener(
-
+
- Ping + PING Station
+
+ +
+ +
+
+ +
+
Enable Beacon
-
-
- +
+ + +
+
diff --git a/gui/src/components/grid/grid_active_heard_stations.vue b/gui/src/components/grid/grid_active_heard_stations.vue index a1262e0fe..0c16721c8 100644 --- a/gui/src/components/grid/grid_active_heard_stations.vue +++ b/gui/src/components/grid/grid_active_heard_stations.vue @@ -34,9 +34,10 @@ function getMaidenheadDistance(dxGrid) { // } } -function pushToPing(origin) -{ - window.dispatchEvent(new CustomEvent("stationSelected", {bubbles:true, detail: origin })); +function pushToPing(origin) { + window.dispatchEvent( + new CustomEvent("stationSelected", { bubbles: true, detail: origin }), + ); }