introduced store for serial and audio devices for fixing audio related problems

This commit is contained in:
DJ2LS 2024-03-04 11:36:44 +01:00
parent 0240c6cd1d
commit eeb72faf83
11 changed files with 190 additions and 226 deletions

View File

@ -42,8 +42,6 @@ InstallDirRegKey HKCU "Software\FreeDATA" "Install_Dir"
; Language (you can choose and configure the language(s) you want)
!insertmacro MUI_LANGUAGE "English"
!define StartMenuFolder "FreeDATA"
; Installer Sections
Section "FreeData Server" SEC01
@ -67,13 +65,13 @@ doneBackup:
WriteUninstaller "$INSTDIR\Uninstall.exe"
; Create a Start Menu directory
CreateDirectory "$COMMON_STARTMENU\${StartMenuFolder}"
CreateDirectory "$SMPROGRAMS\FreeDATA"
; Create shortcut in the Start Menu directory
CreateShortCut "$COMMON_STARTMENU\${StartMenuFolder}\FreeDATA Server.lnk" "$INSTDIR\freedata-server\freedata-server.exe"
CreateShortCut "$SMPROGRAMS\FreeDATA\FreeDATA Server.lnk" "$INSTDIR\freedata-server\freedata-server.exe"
; Create an Uninstall shortcut
CreateShortCut "$COMMON_STARTMENU\${StartMenuFolder}\Uninstall FreeDATA.lnk" "$INSTDIR\Uninstall.exe"
CreateShortCut "$SMPROGRAMS\FreeDATA\Uninstall FreeDATA.lnk" "$INSTDIR\Uninstall.exe"
; Backup "config.ini" before overwriting files
@ -101,10 +99,10 @@ Section "FreeData x64 GUI" SEC02
CreateShortCut "$DESKTOP\FreeDATA GUI.lnk" "$INSTDIR\freedata-gui\freedata.exe"
; Create a start menu shortcut
CreateShortCut "$COMMON_STARTMENU\${StartMenuFolder}\FreeDATA GUI.lnk" "$INSTDIR\freedata-gui\freedata.exe"
CreateShortCut "$SMPROGRAMS\FreeDATA\FreeDATA GUI.lnk" "$INSTDIR\freedata-gui\freedata.exe"
; Create an Uninstall shortcut
CreateShortCut "$COMMON_STARTMENU\${StartMenuFolder}\Uninstall FreeDATA.lnk" "$INSTDIR\Uninstall.exe"
CreateShortCut "$SMPROGRAMS\FreeDATA\Uninstall FreeDATA.lnk" "$INSTDIR\Uninstall.exe"
SectionEnd
@ -123,8 +121,8 @@ Section "Uninstall"
Delete "$DESKTOP\FreeDATA GUI.lnk"
; Remove Start Menu shortcuts
Delete "$COMMON_STARTMENU\${StartMenuFolder}\*.*"
RMDir "$COMMON_STARTMENU\${StartMenuFolder}"
Delete "$SMPROGRAMS\FreeDATA\*.*"
RMDir "$SMPROGRAMS\FreeDATA"
; Attempt to delete the uninstaller itself
Delete $EXEPATH

View File

@ -22,15 +22,9 @@ import Dynamic_components from "./dynamic_components.vue";
import { getFreedataMessages } from "../js/api";
import { getRemote } from "../store/settingsStore.js";
import { loadAudioDevices, loadSerialDevices } from "../js/deviceFormHelper";
import { loadAllData } from "../js/eventHandler";
function getAllSettings(){
getRemote()
loadAudioDevices()
loadSerialDevices()
}
</script>
<template>
@ -57,7 +51,7 @@ function getAllSettings(){
id="main-list-tab"
role="tablist"
style="margin-top: 100px"
@click="getAllSettings"
@click="loadAllData"
>
<main_modem_healthcheck />
@ -122,7 +116,7 @@ function getAllSettings(){
role="tab"
aria-controls="list-settings"
title="Settings"
@click="getAllSettings"
@click="loadAllData"
><i class="bi bi-gear-wide-connected h3"></i
></a>
</div>

View File

@ -9,11 +9,16 @@ setActivePinia(pinia);
import { settingsStore as settings, onChange } from "../store/settingsStore.js";
import { sendModemCQ } from "../js/api.js";
import { loadAudioDevices } from "../js/deviceFormHelper";
import { useStateStore } from "../store/stateStore.js";
const state = useStateStore(pinia);
import { useAudioStore } from "../store/audioStore";
const audioStore = useAudioStore();
import { useSerialStore } from "../store/serialStore";
const serialStore = useSerialStore();
import {
getVersion,
setConfig,
@ -21,8 +26,8 @@ import {
stopModem,
getModemState,
} from "../js/api";
import { audioInputOptions, audioOutputOptions } from "../js/deviceFormHelper";
import { serialDeviceOptions } from "../js/deviceFormHelper";
const version = import.meta.env.PACKAGE_VERSION;
@ -34,6 +39,8 @@ onMounted(() => {
new Modal("#modemCheck", {}).show();
});
function getModemStateLocal() {
// Returns active/inactive if modem is running for modem status label
if (state.is_modem_running == true) return "Active";
@ -205,74 +212,26 @@ function testHamlib() {
<!-- Audio Input Device -->
<div class="input-group input-group-sm mb-1">
<label class="input-group-text w-50"
>Audio Input device</label
>
<button
type="button"
id="stopModem"
class="btn btn-sm btn-secondary"
data-bs-toggle="tooltip"
data-bs-trigger="hover"
data-bs-html="false"
title="Refresh audio devices"
@click="loadAudioDevices"
>
<i class="bi bi-arrow-clockwise"></i>
</button>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
@change="onChange"
v-model="settings.remote.AUDIO.input_device"
>
<option
v-for="option in audioInputOptions()"
v-bind:value="option.id"
>
{{ option.name }} [{{ option.api }}]
</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<label class="input-group-text w-50">Audio Input device</label>
<select class="form-select form-select-sm" aria-label=".form-select-sm" @change="onChange" v-model="settings.remote.AUDIO.input_device">
<option v-for="device in audioStore.audioInputs" :value="device.id">
{{ device.name }} [{{ device.api }}]
</option>
</select>
</div>
<!-- Audio Output Device -->
<div class="input-group input-group-sm mb-1">
<label class="input-group-text w-50"
>Audio Output device</label
>
<div class="input-group input-group-sm mb-1">
<label class="input-group-text w-50">Audio Output device</label>
<select class="form-select form-select-sm" aria-label=".form-select-sm" @change="onChange" v-model="settings.remote.AUDIO.output_device">
<option v-for="device in audioStore.audioOutputs" :value="device.id">
{{ device.name }} [{{ device.api }}]
</option>
</select>
</div>
<button
type="button"
id="stopModem"
class="btn btn-sm btn-secondary"
data-bs-toggle="tooltip"
data-bs-trigger="hover"
data-bs-html="false"
title="Refresh audio devices"
@click="loadAudioDevices"
>
<i class="bi bi-arrow-clockwise"></i>
</button>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
@change="onChange"
v-model="settings.remote.AUDIO.output_device"
>
<option
v-for="option in audioOutputOptions()"
v-bind:value="option.id"
>
{{ option.name }} [{{ option.api }}]
</option>
</select>
</div>
</div>
</div>
</div>
@ -340,21 +299,15 @@ function testHamlib() {
>Radio port</span
>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_deviceport"
style="width: 7rem"
@change="onChange"
v-model="settings.remote.RADIO.serial_port"
>
<option
v-for="option in serialDeviceOptions()"
v-bind:value="option.port"
>
{{ option.description }}
</option>
</select>
<select @change="onChange" v-model="settings.remote.RADIO.serial_port" class="form-select form-select-sm">
<option v-for="device in serialStore.serialDevices" :value="device.port" :key="device.port">
{{ device.description }}
</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">

View File

@ -1,6 +1,8 @@
<script setup lang="ts">
import { settingsStore as settings, onChange } from "../store/settingsStore.js";
import { serialDeviceOptions } from "../js/deviceFormHelper";
import { useSerialStore } from "../store/serialStore";
const serialStore = useSerialStore();
</script>
<template>
@ -333,21 +335,23 @@ import { serialDeviceOptions } from "../js/deviceFormHelper";
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Radio port</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_deviceport"
style="width: 7rem"
@change="onChange"
v-model="settings.remote.RADIO.serial_port"
>
<option
v-for="option in serialDeviceOptions()"
v-bind:value="option.port"
>
{{ option.description }}
</option>
</select>
<select @change="onChange" v-model="settings.remote.RADIO.serial_port" class="form-select form-select-sm">
<option v-for="device in serialStore.serialDevices" :value="device.port" :key="device.port">
{{ device.description }}
</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
@ -422,20 +426,18 @@ import { serialDeviceOptions } from "../js/deviceFormHelper";
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">PTT device port</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_ptt_port"
@change="onChange"
v-model="settings.remote.RADIO.ptt_port"
>
<option
v-for="option in serialDeviceOptions()"
v-bind:value="option.port"
>
{{ option.description }}
</option>
</select>
<select @change="onChange" v-model="settings.remote.RADIO.ptt_port" class="form-select form-select-sm">
<option v-for="device in serialStore.serialDevices" :value="device.port" :key="device.port">
{{ device.description }}
</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">PTT type</span>

View File

@ -6,7 +6,12 @@ import { useStateStore } from "../store/stateStore.js";
const state = useStateStore(pinia);
import { startModem, stopModem } from "../js/api.js";
import { audioInputOptions, audioOutputOptions } from "../js/deviceFormHelper";
import { useAudioStore } from "../store/audioStore";
const audioStore = useAudioStore();
</script>
<template>
@ -65,35 +70,31 @@ import { audioInputOptions, audioOutputOptions } from "../js/deviceFormHelper";
/>
</div>
<!-- Audio Input Device -->
<!-- Audio Input Device -->
<div class="input-group input-group-sm mb-1">
<label class="input-group-text w-50">Audio Input device</label>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
@change="onChange"
v-model="settings.remote.AUDIO.input_device"
>
<option v-for="option in audioInputOptions()" v-bind:value="option.id">
{{ option.name }} [{{ option.api }}]
<select class="form-select form-select-sm" aria-label=".form-select-sm" @change="onChange" v-model="settings.remote.AUDIO.input_device">
<option v-for="device in audioStore.audioInputs" :value="device.id">
{{ device.name }} [{{ device.api }}]
</option>
</select>
</div>
<!-- Audio Output Device -->
<!-- Audio Output Device -->
<div class="input-group input-group-sm mb-1">
<label class="input-group-text w-50">Audio Output device</label>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
@change="onChange"
v-model="settings.remote.AUDIO.output_device"
>
<option v-for="option in audioOutputOptions()" v-bind:value="option.id">
{{ option.name }} [{{ option.api }}]
<select class="form-select form-select-sm" aria-label=".form-select-sm" @change="onChange" v-model="settings.remote.AUDIO.output_device">
<option v-for="device in audioStore.audioOutputs" :value="device.id">
{{ device.name }} [{{ device.api }}]
</option>
</select>
</div>
<!-- Audio rx level-->
<div class="input-group input-group-sm mb-1">
<span class="input-group-text w-25">RX Audio Level</span>

View File

@ -1,6 +1,5 @@
<script setup lang="ts">
import { settingsStore as settings, onChange } from "../store/settingsStore.js";
import { serialDeviceOptions } from "../js/deviceFormHelper";
</script>
<template>

View File

@ -1,53 +0,0 @@
import { getAudioDevices, getSerialDevices } from "./api";
let audioDevices = await getAudioDevices();
let serialDevices = await getSerialDevices();
//Dummy device data sent if unable to get devices from modem to prevent GUI crash
const skel = JSON.parse(`
[{
"api": "MME",
"id": "0000",
"name": "No devices received from modem",
"native_index": 0
}]`);
export function loadAudioDevices() {
getAudioDevices().then((devices) => {
audioDevices = devices;
});
}
export function loadSerialDevices() {
getSerialDevices().then((devices) => {
serialDevices = devices;
});
}
export function audioInputOptions() {
if (audioDevices === undefined) {
return skel;
}
return audioDevices.in;
}
export function audioOutputOptions() {
if (audioDevices === undefined) {
return skel;
}
return audioDevices.out;
}
export function serialDeviceOptions() {
//Return ignore option if no serialDevices
if (serialDevices === undefined)
return [{ description: "-- ignore --", port: "ignore" }];
if (serialDevices.findIndex((device) => device.port == "ignore") == -1) {
//Add an ignore option for rig and ptt for transceivers that don't require them
serialDevices.push({ description: "-- ignore --", port: "ignore" });
}
return serialDevices;
}

View File

@ -11,11 +11,15 @@ import { displayToast } from "./popupHandler";
import {
getFreedataMessages,
getModemState,
getAudioDevices,
} from "./api";
import { processFreedataMessages } from "./messagesHandler.ts";
import { processRadioStatus } from "./radioHandler.ts";
import { loadAudioDevices, loadSerialDevices } from "./deviceFormHelper.ts";
import { useAudioStore } from "../store/audioStore";
const audioStore = useAudioStore();
import { useSerialStore } from "../store/serialStore";
const serialStore = useSerialStore();
// ----------------- init pinia stores -------------
import { setActivePinia } from "pinia";
@ -29,6 +33,19 @@ import {
getRemote,
} from "../store/settingsStore.js";
export function loadAllData(){
getModemState();
getRemote();
getOverallHealth();
audioStore.loadAudioDevices();
serialStore.loadSerialDevices();
getFreedataMessages();
processFreedataMessages();
processRadioStatus();
}
export function connectionFailed(endpoint, event) {
stateStore.modem_connection = "disconnected";
}
@ -94,12 +111,7 @@ export function eventDispatcher(data) {
switch (data["modem"]) {
case "started":
displayToast("success", "bi-arrow-left-right", "Modem started", 5000);
getModemState();
getRemote();
loadAudioDevices();
loadSerialDevices();
getFreedataMessages();
processRadioStatus();
loadAllData();
return;
case "stopped":
@ -108,12 +120,7 @@ export function eventDispatcher(data) {
case "restarted":
displayToast("secondary", "bi-bootstrap-reboot", "Modem restarted", 5000);
getModemState();
getRemote();
loadAudioDevices();
loadSerialDevices();
getFreedataMessages();
processRadioStatus();
loadAllData();
return;
case "failed":
@ -135,13 +142,7 @@ export function eventDispatcher(data) {
stateStore.modem_connection = "connected";
getModemState();
getOverallHealth();
loadAudioDevices();
loadSerialDevices();
getFreedataMessages();
processFreedataMessages();
processRadioStatus();
loadAllData();
return;

View File

@ -32,12 +32,9 @@ const tooltipList = [...tooltipTriggerList].map(
import { getRemote } from "./store/settingsStore";
import { initConnections } from "./js/event_sock.js";
import { getModemState } from "./js/api";
import { loadAudioDevices, loadSerialDevices } from "./js/deviceFormHelper";
getRemote().then(() => {
initConnections();
loadAudioDevices();
loadSerialDevices();
getModemState();
});

View File

@ -0,0 +1,37 @@
import { defineStore } from "pinia";
import { getAudioDevices } from "../js/api";
import { ref } from "vue";
// Define skel fallback data
const skel = [{
"api": "ERR",
"id": "0000",
"name": "No devices received from modem",
"native_index": 0
}];
export const useAudioStore = defineStore("audioStore", () => {
const audioInputs = ref([]);
const audioOutputs = ref([]);
const loadAudioDevices = async () => {
try {
const devices = await getAudioDevices();
// Check if devices are valid and have entries, otherwise use skel
audioInputs.value = devices && devices.in.length > 0 ? devices.in : skel;
audioOutputs.value = devices && devices.out.length > 0 ? devices.out : skel;
} catch (error) {
console.error("Failed to load audio devices:", error);
// Use skel as fallback in case of error
audioInputs.value = skel;
audioOutputs.value = skel;
}
};
return {
audioInputs,
audioOutputs,
loadAudioDevices,
};
});

View File

@ -0,0 +1,35 @@
import { defineStore } from "pinia";
import { getSerialDevices } from "../js/api"; // Make sure this points to the correct file
import { ref } from "vue";
// Define "skel" fallback data for serial devices
const skelSerial = [{
"description": "No devices received from modem",
"port": "ignore" // Using "ignore" as a placeholder value
}];
export const useSerialStore = defineStore("serialStore", () => {
const serialDevices = ref([]);
const loadSerialDevices = async () => {
try {
const devices = await getSerialDevices();
// Check if devices are valid and have entries, otherwise use skelSerial
serialDevices.value = devices && devices.length > 0 ? devices : skelSerial;
} catch (error) {
console.error("Failed to load serial devices:", error);
// Use skelSerial as fallback in case of error
serialDevices.value = skelSerial;
}
// Ensure the "-- ignore --" option is always available
if (!serialDevices.value.some(device => device.port === "ignore")) {
serialDevices.value.push({ description: "-- ignore --", port: "ignore" });
}
};
return {
serialDevices,
loadSerialDevices,
};
});