Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
DJ2LS 2023-12-10 09:59:09 +01:00
commit 6980aa4e2f
9 changed files with 108 additions and 59 deletions

View file

@ -14,7 +14,7 @@ function startStopRecordAudio() {
</script> </script>
<template> <template>
<div class="card w-100 h-100"> <div class="card w-100 h-100">
<div class="card-header"> <div class="card-header p-0">
<div class="dropdown"> <div class="dropdown">
<button <button
class="btn btn-sm btn-outline-secondary dropdown-toggle" class="btn btn-sm btn-outline-secondary dropdown-toggle"
@ -42,7 +42,7 @@ function startStopRecordAudio() {
</ul> </ul>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-body pt-0 pb-0">
<div class="container-wide"> <div class="container-wide">
<div class="row"> <div class="row">
<div class="col-lg-6"> <div class="col-lg-6">

View file

@ -1,10 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue";
import { setActivePinia } from "pinia"; import { setActivePinia } from "pinia";
import pinia from "../../store/index"; import pinia from "../../store/index";
setActivePinia(pinia); setActivePinia(pinia);
import { settingsStore as settings} from "../../store/settingsStore.js"; import { settingsStore as settings } from "../../store/settingsStore.js";
import { useStateStore } from "../../store/stateStore.js"; import { useStateStore } from "../../store/stateStore.js";
const state = useStateStore(pinia); const state = useStateStore(pinia);
@ -12,21 +12,21 @@ const state = useStateStore(pinia);
import { sendModemCQ, sendModemPing, setModemBeacon } from "../../js/api.js"; import { sendModemCQ, sendModemPing, setModemBeacon } from "../../js/api.js";
function transmitPing() { function transmitPing() {
sendModemPing((<HTMLInputElement>document.getElementById("dxCall")).value); sendModemPing(dxcallPing.value.toUpperCase());
} }
function startStopBeacon() { function startStopBeacon() {
if (state.beacon_state === true) { if (state.beacon_state === true) {
setModemBeacon(false); setModemBeacon(false);
} } else {
else {
setModemBeacon(true); setModemBeacon(true);
} }
} }
var dxcallPing = ref("");
</script> </script>
<template> <template>
<div class="card h-100"> <div class="card h-100">
<div class="card-header"> <div class="card-header p-0">
<div> <div>
<div> <div>
<i class="bi bi-broadcast" style="font-size: 1.2rem"></i>&nbsp; <i class="bi bi-broadcast" style="font-size: 1.2rem"></i>&nbsp;
@ -34,9 +34,9 @@ function startStopBeacon() {
</div> </div>
</div> </div>
</div> </div>
<div class="card-body overflow-auto"> <div class="card-body overflow-auto p-0">
<div>
<div> <div>
<div >
<div class="input-group input-group-sm mb-0"> <div class="input-group input-group-sm mb-0">
<input <input
type="text" type="text"
@ -44,10 +44,10 @@ function startStopBeacon() {
style="max-width: 6rem; text-transform: uppercase" style="max-width: 6rem; text-transform: uppercase"
placeholder="DXcall" placeholder="DXcall"
pattern="[A-Z]*" pattern="[A-Z]*"
id="dxCall"
maxlength="11" maxlength="11"
aria-label="Input group" aria-label="Input group"
aria-describedby="btnGroupAddon" aria-describedby="btnGroupAddon"
v-model="dxcallPing"
/> />
<button <button
class="btn btn-sm btn-outline-secondary ms-1" class="btn btn-sm btn-outline-secondary ms-1"

View file

@ -38,12 +38,12 @@ function getMaidenheadDistance(dxGrid) {
<template> <template>
<div class="card h-100"> <div class="card h-100">
<!--325px--> <!--325px-->
<div class="card-header"> <div class="card-header p-0">
<i class="bi bi-list-columns-reverse" style="font-size: 1rem"></i>&nbsp; <i class="bi bi-list-columns-reverse" style="font-size: 1.2rem"></i>&nbsp;
<strong>Heard stations</strong> <strong>Heard stations</strong>
</div> </div>
<div class="card-body overflow-auto"> <div class="card-body overflow-auto p-0">
<div class="table-responsive"> <div class="table-responsive">
<!-- START OF TABLE FOR HEARD STATIONS --> <!-- START OF TABLE FOR HEARD STATIONS -->
<table class="table table-sm table-striped" id="tblHeardStationList"> <table class="table table-sm table-striped" id="tblHeardStationList">

View file

@ -37,13 +37,12 @@ function getMaidenheadDistance(dxGrid) {
</script> </script>
<template> <template>
<div class="card h-100"> <div class="card h-100">
<!--325px--> <div class="card-header p-0">
<div class="card-header"> <i class="bi bi-list-columns-reverse" style="font-size: 1.2rem"></i>&nbsp;
<i class="bi bi-list-columns-reverse" style="font-size: 1rem"></i>&nbsp;
<strong>Heard stations</strong> <strong>Heard stations</strong>
</div> </div>
<div class="card-body overflow-auto"> <div class="card-body overflow-auto p-0">
<div class="table-responsive"> <div class="table-responsive">
<!-- START OF TABLE FOR HEARD STATIONS --> <!-- START OF TABLE FOR HEARD STATIONS -->
<table class="table table-sm table-striped" id="tblHeardStationList"> <table class="table table-sm table-striped" id="tblHeardStationList">

View file

@ -26,12 +26,12 @@ function set_hamlib_rf_level() {
<template> <template>
<div class="card h-100"> <div class="card h-100">
<div class="card-header"> <div class="card-header p-0">
<i class="bi bi-house-door" style="font-size: 1.2rem"></i>&nbsp; <i class="bi bi-house-door" style="font-size: 1.2rem"></i>&nbsp;
<strong>Radio control</strong> <strong>Radio control</strong>
</div> </div>
<div class="card-body overflow-auto"> <div class="card-body overflow-auto p-0">
<div class="input-group input-group-sm bottom-0 m-0"> <div class="input-group input-group-sm bottom-0 m-0">
<div class="me-2"> <div class="me-2">
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">

View file

@ -1,7 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
// @ts-nocheck // @ts-nocheck
// reason for no check is, that we have some mixing of typescript and chart js which seems to be not to be fixed that easy // reason for no check is, that we have some mixing of typescript and chart js which seems to be not to be fixed that easy
import { initWaterfall } from "../../js/waterfallHandler.js"; import { ref, computed, onMounted } from "vue";
import { initWaterfall, setColormap } from "../../js/waterfallHandler.js";
import { setActivePinia } from "pinia"; import { setActivePinia } from "pinia";
import pinia from "../../store/index"; import pinia from "../../store/index";
setActivePinia(pinia); setActivePinia(pinia);
@ -22,21 +23,21 @@ import {
Legend, Legend,
} from "chart.js"; } from "chart.js";
import { Line, Scatter } from "vue-chartjs"; import { Line, Scatter } from "vue-chartjs";
import { computed, onMounted } from "vue";
function selectStatsControl(obj) { const localSpectrumView = ref("waterfall");
switch (obj.delegateTarget.id) { function selectStatsControl(item) {
case "list-waterfall-list": switch (item) {
settings.local.spectrum = "waterfall"; case "wf":
localSpectrumView.value = "waterfall";
break; break;
case "list-scatter-list": case "scatter":
settings.local.spectrum = "scatter"; localSpectrumView.value = "scatter";
break; break;
case "list-chart-list": case "chart":
settings.local.spectrum = "chart"; localSpectrumView.value = "chart";
break; break;
default: default:
settings.local.spectrum = "waterfall"; localSpectrumView.value = "waterfall";
} }
//saveSettingsToFile(); //saveSettingsToFile();
} }
@ -181,12 +182,13 @@ onMounted(() => {
}, },
false, false,
); );
setColormap(settings.local.wf_theme.valueOf);
}); });
</script> </script>
<template> <template>
<div class="card h-100"> <div class="card h-100">
<div class="card-header"> <div class="card-header p-1">
<div class="btn-group" role="group"> <div class="btn-group" role="group">
<div <div
class="list-group bg-body-tertiary list-group-horizontal" class="list-group bg-body-tertiary list-group-horizontal"
@ -195,39 +197,33 @@ onMounted(() => {
> >
<a <a
class="py-0 list-group-item list-group-item-dark list-group-item-action" class="py-0 list-group-item list-group-item-dark list-group-item-action"
id="list-waterfall-list"
data-bs-toggle="list" data-bs-toggle="list"
href="#list-waterfall"
role="tab" role="tab"
aria-controls="list-waterfall" aria-controls="list-waterfall"
v-bind:class="{ v-bind:class="{
active: settings.local.spectrum === 'waterfall', active: localSpectrumView == 'waterfall',
}" }"
@click="selectStatsControl($event)" @click="selectStatsControl('wf')"
><strong><i class="bi bi-water"></i></strong ><strong><i class="bi bi-water"></i></strong
></a> ></a>
<a <a
class="py-0 list-group-item list-group-item-dark list-group-item-action" class="py-0 list-group-item list-group-item-dark list-group-item-action"
id="list-scatter-list"
data-bs-toggle="list" data-bs-toggle="list"
href="#list-scatter"
role="tab" role="tab"
aria-controls="list-scatter" aria-controls="list-scatter"
v-bind:class="{ v-bind:class="{
active: settings.local.spectrum === 'scatter', active: localSpectrumView == 'scatter',
}" }"
@click="selectStatsControl($event)" @click="selectStatsControl('scatter')"
><strong><i class="bi bi-border-outer"></i></strong ><strong><i class="bi bi-border-outer"></i></strong
></a> ></a>
<a <a
class="py-0 list-group-item list-group-item-dark list-group-item-action" class="py-0 list-group-item list-group-item-dark list-group-item-action"
id="list-chart-list"
data-bs-toggle="list" data-bs-toggle="list"
href="#list-chart"
role="tab" role="tab"
aria-controls="list-chart" aria-controls="list-chart"
v-bind:class="{ active: settings.local.spectrum === 'chart' }" v-bind:class="{ active: localSpectrumView == 'chart' }"
@click="selectStatsControl($event)" @click="selectStatsControl('chart')"
><strong><i class="bi bi-graph-up-arrow"></i></strong ><strong><i class="bi bi-graph-up-arrow"></i></strong
></a> ></a>
</div> </div>
@ -330,34 +326,31 @@ onMounted(() => {
</button> </button>
</div> </div>
</div> </div>
<div class="card-body w-100 h-100 overflow-auto"> <div class="card-body w-100 h-100 overflow-auto p-2">
<div class="tab-content h-100 w-100" id="nav-stats-tabContent"> <div class="tab-content h-100 w-100" id="nav-stats-tabContent">
<div <div
class="tab-pane fade h-100 w-100" class="tab-pane fade h-100 w-100"
v-bind:class="{ v-bind:class="{
'show active': settings.local.spectrum === 'waterfall', 'show active': localSpectrumView == 'waterfall',
}" }"
id="list-waterfall"
role="stats_tabpanel" role="stats_tabpanel"
aria-labelledby="list-waterfall-list" aria-labelledby="list-waterfall-list"
> >
<canvas id="waterfall-grid" class="force-gpu"></canvas> <canvas id="waterfall-grid" class="force-gpu"></canvas>
</div> </div>
<div <div
class="tab-pane fade" class="tab-pane fade h-100 w-100"
v-bind:class="{ v-bind:class="{
'show active': settings.local.spectrum === 'scatter', 'show active': localSpectrumView == 'scatter',
}" }"
id="list-scatter"
role="tabpanel" role="tabpanel"
aria-labelledby="list-scatter-list" aria-labelledby="list-scatter-list"
> >
<Scatter :data="scatterChartData" :options="scatterChartOptions" /> <Scatter :data="scatterChartData" :options="scatterChartOptions" />
</div> </div>
<div <div
class="tab-pane fade" class="tab-pane fade h-100 w-100"
v-bind:class="{ 'show active': settings.local.spectrum === 'chart' }" v-bind:class="{ 'show active': localSpectrumView == 'chart' }"
id="list-chart"
role="tabpanel" role="tabpanel"
aria-labelledby="list-chart-list" aria-labelledby="list-chart-list"
> >

View file

@ -24,10 +24,11 @@ function getDateTime(timestampRaw) {
</script> </script>
<template> <template>
<div class="card h-100"> <div class="card h-100">
<div class="card-header"> <div class="card-header p-0">
<i class="bi bi-card-list" style="font-size: 1.2rem"></i>&nbsp;
<strong>Activity</strong> <strong>Activity</strong>
</div> </div>
<div class="card-body overflow-auto" style="align-items: start"> <div class="card-body overflow-auto m-0 p-0" style="align-items: start">
<div v-for="item in state.activities" :key="item[0]"> <div v-for="item in state.activities" :key="item[0]">
<h6 style="text-align: start" class="mb-0"> <h6 style="text-align: start" class="mb-0">
{{ item[1].origin }} - {{ item[1].origin }} -

View file

@ -1,4 +1,8 @@
import { settingsStore as settings } from "../store/settingsStore.js"; import { settingsStore as settings } from "../store/settingsStore.js";
import {
validateCallsignWithSSID,
validateCallsignWithoutSSID,
} from "./freedata";
function buildURL(params, endpoint) { function buildURL(params, endpoint) {
const url = "http://" + params.host + ":" + params.port + endpoint; const url = "http://" + params.host + ":" + params.port + endpoint;
@ -72,6 +76,15 @@ export function sendModemCQ() {
} }
export function sendModemPing(dxcall) { export function sendModemPing(dxcall) {
if (
validateCallsignWithSSID(dxcall) === false &&
validateCallsignWithoutSSID(dxcall) === true
) {
dxcall = String(dxcall).toUpperCase().trim();
dxcall = dxcall + "-0";
}
dxcall = String(dxcall).toUpperCase().trim();
if (validateCallsignWithSSID(dxcall))
return apiPost("/modem/ping_ping", { dxcall: dxcall }); return apiPost("/modem/ping_ping", { dxcall: dxcall });
} }

View file

@ -54,3 +54,46 @@ export function sortByPropertyDesc(property) {
return 0; return 0;
}; };
} }
/**
* Validate a call sign with ssid
* @param {string} callsign callsign to check
* @returns true or false if callsign appears to be valid with an SSID
*/
export function validateCallsignWithSSID(callsign: string) {
var patt = new RegExp("^[A-Z,a-z]+[0-9][A-Z,a-z]*-(1[0-5]|[0-9])$");
if (
callsign === undefined ||
callsign === "" ||
patt.test(callsign) === false
) {
console.error(
"Call sign given is not in correct format or missing; callsign passed is: " +
callsign,
);
return false;
}
return true;
}
/**
* Validate/check if a call sign has an SSID
* @param {string} callsign callsign to check
* @returns true or false if callsign appears to be valid without an SSID
*/
export function validateCallsignWithoutSSID(callsign: string) {
var patt = new RegExp("^[A-Za-z]+[0-9][A-Za-z]+$");
if (
callsign === undefined ||
callsign === "" ||
patt.test(callsign) === false
) {
console.error(
"Call sign given is not in correct format or missing; callsign passed is: " +
callsign,
);
return false;
}
return true;
}