[CodeFactor] Apply fixes

This commit is contained in:
codefactor-io 2023-10-22 08:12:00 +00:00
parent c39af3f830
commit 90401e7df5
No known key found for this signature in database
GPG key ID: B66B2D63282C190F
28 changed files with 1406 additions and 1482 deletions

View file

@ -1,10 +1,9 @@
import { app, BrowserWindow, shell, ipcMain } from 'electron'
import { release, platform } from 'node:os'
import { join } from 'node:path'
import { autoUpdater } from "electron-updater"
import { existsSync } from "fs"
import { spawn } from "child_process"
import { app, BrowserWindow, shell, ipcMain } from "electron";
import { release, platform } from "node:os";
import { join } from "node:path";
import { autoUpdater } from "electron-updater";
import { existsSync } from "fs";
import { spawn } from "child_process";
// The built directory structure
//
@ -16,22 +15,22 @@ import { spawn } from "child_process"
// ├─┬ dist
// │ └── index.html > Electron-Renderer
//
process.env.DIST_ELECTRON = join(__dirname, '..')
process.env.DIST = join(process.env.DIST_ELECTRON, '../dist')
process.env.DIST_ELECTRON = join(__dirname, "..");
process.env.DIST = join(process.env.DIST_ELECTRON, "../dist");
process.env.VITE_PUBLIC = process.env.VITE_DEV_SERVER_URL
? join(process.env.DIST_ELECTRON, '../public')
: process.env.DIST
? join(process.env.DIST_ELECTRON, "../public")
: process.env.DIST;
// Disable GPU Acceleration for Windows 7
if (release().startsWith('6.1')) app.disableHardwareAcceleration()
if (release().startsWith("6.1")) app.disableHardwareAcceleration();
// Set application name for Windows 10+ notifications
if (process.platform === 'win32') app.setAppUserModelId(app.getName())
if (process.platform === "win32") app.setAppUserModelId(app.getName());
if (!app.requestSingleInstanceLock()) {
close_sub_processes()
app.quit()
process.exit(0)
close_sub_processes();
app.quit();
process.exit(0);
}
// Remove electron security warnings
@ -41,18 +40,18 @@ if (!app.requestSingleInstanceLock()) {
// set daemon process var
var daemonProcess = null;
let win: BrowserWindow | null = null
let win: BrowserWindow | null = null;
// Here, you can also use other preload
const preload = join(__dirname, '../preload/index.js')
const url = process.env.VITE_DEV_SERVER_URL
const indexHtml = join(process.env.DIST, 'index.html')
const preload = join(__dirname, "../preload/index.js");
const url = process.env.VITE_DEV_SERVER_URL;
const indexHtml = join(process.env.DIST, "index.html");
async function createWindow() {
win = new BrowserWindow({
title: 'FreeDATA',
title: "FreeDATA",
width: 1200,
height: 670,
icon: join(process.env.VITE_PUBLIC, 'icon_cube_border.png'),
icon: join(process.env.VITE_PUBLIC, "icon_cube_border.png"),
autoHideMenuBar: true,
webPreferences: {
preload,
@ -64,29 +63,29 @@ async function createWindow() {
nodeIntegration: true,
contextIsolation: false,
},
})
});
if (process.env.VITE_DEV_SERVER_URL) { // electron-vite-vue#298
win.loadURL(url)
if (process.env.VITE_DEV_SERVER_URL) {
// electron-vite-vue#298
win.loadURL(url);
// Open devTool if the app is not packaged
win.webContents.openDevTools()
win.webContents.openDevTools();
} else {
win.loadFile(indexHtml)
win.loadFile(indexHtml);
}
// Test actively push message to the Electron-Renderer
win.webContents.on('did-finish-load', () => {
win?.webContents.send('main-process-message', new Date().toLocaleString())
})
win.webContents.on("did-finish-load", () => {
win?.webContents.send("main-process-message", new Date().toLocaleString());
});
// Make all links open with the browser, not with the application
win.webContents.setWindowOpenHandler(({ url }) => {
if (url.startsWith('https:')) shell.openExternal(url)
return { action: 'deny' }
})
if (url.startsWith("https:")) shell.openExternal(url);
return { action: "deny" };
});
// win.webContents.on('will-navigate', (event, url) => { }) #344
win.once("ready-to-show", () => {
//autoUpdater.logger = log.scope("updater");
//autoUpdater.channel = config.update_channel;
@ -95,14 +94,11 @@ async function createWindow() {
autoUpdater.checkForUpdatesAndNotify();
//autoUpdater.quitAndInstall();
});
}
//app.whenReady().then(
app.whenReady().then(() => {
createWindow()
createWindow();
//Generate daemon binary path
var daemonPath = "";
@ -114,11 +110,7 @@ createWindow()
break;
case "win32":
case "win64":
daemonPath = join(
process.resourcesPath,
"modem",
"freedata-daemon.exe",
);
daemonPath = join(process.resourcesPath, "modem", "freedata-daemon.exe");
break;
default:
console.log("Unhandled OS Platform: ", platform());
@ -156,59 +148,49 @@ createWindow()
console.log("Daemon binary doesn't exist--normal for dev environments.");
}
//)
//)
});
app.on("window-all-closed", () => {
win = null;
if (process.platform !== "darwin") app.quit(close_sub_processes());
});
app.on('window-all-closed', () => {
win = null
if (process.platform !== 'darwin') app.quit(
close_sub_processes()
)
})
app.on('second-instance', () => {
app.on("second-instance", () => {
if (win) {
// Focus on the main window if the user tried to open another
if (win.isMinimized()) win.restore()
win.focus()
if (win.isMinimized()) win.restore();
win.focus();
}
})
});
app.on('activate', () => {
const allWindows = BrowserWindow.getAllWindows()
app.on("activate", () => {
const allWindows = BrowserWindow.getAllWindows();
if (allWindows.length) {
allWindows[0].focus()
allWindows[0].focus();
} else {
createWindow()
createWindow();
}
})
});
// New window example arg: new windows url
ipcMain.handle('open-win', (_, arg) => {
ipcMain.handle("open-win", (_, arg) => {
const childWindow = new BrowserWindow({
webPreferences: {
preload,
nodeIntegration: true,
contextIsolation: false,
},
})
});
if (process.env.VITE_DEV_SERVER_URL) {
childWindow.loadURL(`${url}#${arg}`)
childWindow.loadURL(`${url}#${arg}`);
} else {
childWindow.loadFile(indexHtml, { hash: arg })
childWindow.loadFile(indexHtml, { hash: arg });
}
})
});
//restart and install udpate
//restart and install udpate
ipcMain.on("request-restart-and-install-update", (event, data) => {
close_sub_processes();
autoUpdater.quitAndInstall();
@ -275,7 +257,6 @@ autoUpdater.on("error", (error) => {
console.log("AUTO UPDATER : " + error);
});
function close_sub_processes() {
console.log("closing sub processes");
@ -307,4 +288,4 @@ function close_sub_processes() {
} catch (e) {
console.log(e);
}
}
}

View file

@ -1,34 +1,34 @@
import { ipcRenderer } from "electron"
import { autoUpdater } from "electron-updater"
import { ipcRenderer } from "electron";
import { autoUpdater } from "electron-updater";
function domReady(condition: DocumentReadyState[] = ['complete', 'interactive']) {
function domReady(
condition: DocumentReadyState[] = ["complete", "interactive"],
) {
return new Promise((resolve) => {
if (condition.includes(document.readyState)) {
resolve(true)
resolve(true);
} else {
document.addEventListener('readystatechange', () => {
document.addEventListener("readystatechange", () => {
if (condition.includes(document.readyState)) {
resolve(true)
resolve(true);
}
})
});
}
})
});
}
const safeDOM = {
append(parent: HTMLElement, child: HTMLElement) {
if (!Array.from(parent.children).find(e => e === child)) {
return parent.appendChild(child)
if (!Array.from(parent.children).find((e) => e === child)) {
return parent.appendChild(child);
}
},
remove(parent: HTMLElement, child: HTMLElement) {
if (Array.from(parent.children).find(e => e === child)) {
return parent.removeChild(child)
if (Array.from(parent.children).find((e) => e === child)) {
return parent.removeChild(child);
}
},
}
};
/**
* https://tobiasahlin.com/spinkit
@ -37,7 +37,7 @@ const safeDOM = {
* https://matejkustec.github.io/SpinThatShit
*/
function useLoading() {
const className = `loaders-css__square-spin`
const className = `loaders-css__square-spin`;
const styleContent = `
@keyframes square-spin {
0% {
@ -82,55 +82,48 @@ function useLoading() {
background: #282c34;
z-index: 99999;
}
`
const oStyle = document.createElement('style')
const oDiv = document.createElement('div')
`;
const oStyle = document.createElement("style");
const oDiv = document.createElement("div");
oStyle.id = 'app-loading-style'
oStyle.innerHTML = styleContent
oDiv.className = 'app-loading-wrap'
oDiv.innerHTML = `<div class="${className}"><div></div></div>`
oStyle.id = "app-loading-style";
oStyle.innerHTML = styleContent;
oDiv.className = "app-loading-wrap";
oDiv.innerHTML = `<div class="${className}"><div></div></div>`;
return {
appendLoading() {
safeDOM.append(document.head, oStyle)
safeDOM.append(document.body, oDiv)
safeDOM.append(document.head, oStyle);
safeDOM.append(document.body, oDiv);
},
removeLoading() {
safeDOM.remove(document.head, oStyle)
safeDOM.remove(document.body, oDiv)
safeDOM.remove(document.head, oStyle);
safeDOM.remove(document.body, oDiv);
},
}
};
}
// ----------------------------------------------------------------------
const { appendLoading, removeLoading } = useLoading()
domReady().then(appendLoading)
const { appendLoading, removeLoading } = useLoading();
domReady().then(appendLoading);
window.onmessage = (ev) => {
ev.data.payload === 'removeLoading' && removeLoading()
}
setTimeout(removeLoading, 4999)
ev.data.payload === "removeLoading" && removeLoading();
};
setTimeout(removeLoading, 4999);
window.addEventListener("DOMContentLoaded", () => {
// we are using this area for implementing the electron runUpdater
// we need access to DOM for displaying updater results in GUI
// close app, update and restart
// we are using this area for implementing the electron runUpdater
// we need access to DOM for displaying updater results in GUI
// close app, update and restart
document
.getElementById("update_and_install")
.addEventListener("click", () => {
ipcRenderer.send("request-restart-and-install-update");
});
})
});
// IPC ACTION FOR AUTO UPDATER
ipcRenderer.on("action-updater", (event, arg) => {
@ -181,11 +174,12 @@ ipcRenderer.on("action-updater", (event, arg) => {
//autoUpdater.quitAndInstall();
}
if (arg.status == "update-not-available") {
document.getElementById("updater_last_version").innerHTML = arg.info.releaseName
document.getElementById("updater_last_update").innerHTML = arg.info.releaseDate
document.getElementById("updater_release_notes").innerHTML = arg.info.releaseNotes
document.getElementById("updater_last_version").innerHTML =
arg.info.releaseName;
document.getElementById("updater_last_update").innerHTML =
arg.info.releaseDate;
document.getElementById("updater_release_notes").innerHTML =
arg.info.releaseNotes;
document.getElementById("updater_status").innerHTML =
'<i class="bi bi-check2-square ms-1 me-1" style="color: white;"></i>';

View file

@ -14,29 +14,30 @@ const state = useStateStore(pinia);
import { useChatStore } from "../store/chatStore.js";
const chat = useChatStore(pinia);
import {getNewMessagesByDXCallsign, resetIsNewMessage} from '../js/chatHandler'
import {
getNewMessagesByDXCallsign,
resetIsNewMessage,
} from "../js/chatHandler";
import chat_conversations_entry from "./chat_conversations_entry.vue";
function chatSelected(callsign) {
chat.selectedCallsign = callsign.toUpperCase();
// scroll message container to bottom
var messageBody = document.getElementById("message-container");
if (messageBody != null ) {
if (messageBody != null) {
// needs sensible defaults
messageBody.scrollTop = messageBody.scrollHeight - messageBody.clientHeight;
}
if (getNewMessagesByDXCallsign(callsign)[1] > 0){
let messageArray = getNewMessagesByDXCallsign(callsign)[2]
console.log(messageArray)
if (getNewMessagesByDXCallsign(callsign)[1] > 0) {
let messageArray = getNewMessagesByDXCallsign(callsign)[2];
console.log(messageArray);
for (const key in messageArray){
resetIsNewMessage(messageArray[key].uuid, false)
}
for (const key in messageArray) {
resetIsNewMessage(messageArray[key].uuid, false);
}
}
try {
@ -58,7 +59,7 @@ function chatSelected(callsign) {
<template v-for="(item, key) in chat.callsign_list" :key="item.dxcallsign">
<a
class="list-group-item list-group-item-action border-0 border-bottom rounded-0"
:class="{ active: key == 0}"
:class="{ active: key == 0 }"
:id="`list-chat-list-${item}`"
data-bs-toggle="list"
:href="`#list-${item}-messages`"
@ -66,15 +67,15 @@ function chatSelected(callsign) {
aria-controls="list-{{item}}-messages"
@click="chatSelected(item)"
>
<div class="row">
<div class="col-9">{{ item }}
<span class="badge rounded-pill bg-danger" v-if="getNewMessagesByDXCallsign(item)[1] > 0">
{{getNewMessagesByDXCallsign(item)[1]}} new messages
<div class="col-9">
{{ item }}
<span
class="badge rounded-pill bg-danger"
v-if="getNewMessagesByDXCallsign(item)[1] > 0"
>
{{ getNewMessagesByDXCallsign(item)[1] }} new messages
</span>
</div>
<div class="col-3">
<button

View file

@ -57,17 +57,13 @@ function getDateTime(timestampRaw) {
</div>
<div v-if="item.type === 'beacon' && item.status === 'received'">
<!-- {{ item }} -->
<!-- {{ item }} -->
</div>
<div v-if="item.type === 'ping'">
{{ item.snr }} dB
ping received
</div>
<div v-if="item.type === 'ping'">{{ item.snr }} dB ping received</div>
<div v-if="item.type === 'ping-ack'">
{{ item.snr }} dB
ping-ack received
{{ item.snr }} dB ping-ack received
</div>
<div v-if="item.type === 'transmit'">

View file

@ -23,8 +23,7 @@
<!-- Delete button outside of the card -->
<div class="col-auto">
<button
<button
class="btn btn-outline-secondary border-0 me-1"
@click="showMessageInfo"
data-bs-target="#messageInfoModal"
@ -49,42 +48,42 @@
</template>
<script>
import { deleteMessageFromDB, requestMessageInfo, getMessageAttachment } from "../js/chatHandler";
import {atob_FD} from "../js/freedata"
import {
deleteMessageFromDB,
requestMessageInfo,
getMessageAttachment,
} from "../js/chatHandler";
import { atob_FD } from "../js/freedata";
// pinia store setup
import { setActivePinia } from "pinia";
import pinia from "../store/index";
setActivePinia(pinia);
import { saveAs } from 'file-saver';
import { saveAs } from "file-saver";
import { useChatStore } from "../store/chatStore.js";
const chat = useChatStore(pinia);
export default {
props: {
message: Object,
},
methods: {
async downloadAttachment() {
async downloadAttachment() {
try {
// reset file store
chat.downloadFileFromDB = [];
const attachment = await getMessageAttachment(this.message._id);
const blob = new Blob([atob_FD(attachment[2])], { type: `${attachment[1]};charset=utf-8` });
const blob = new Blob([atob_FD(attachment[2])], {
type: `${attachment[1]};charset=utf-8`,
});
window.focus();
saveAs(blob, attachment[0]);
} catch (error) {
console.error("Failed to download attachment:", error);
}
},
},
computed: {
getFileContent() {
@ -112,10 +111,10 @@ async downloadAttachment() {
}
},
showMessageInfo() {
requestMessageInfo(this.message._id);
//let infoModal = Modal.getOrCreateInstance(document.getElementById('messageInfoModal'))
//console.log(this.infoModal)
//this.infoModal.show()
requestMessageInfo(this.message._id);
//let infoModal = Modal.getOrCreateInstance(document.getElementById('messageInfoModal'))
//console.log(this.infoModal)
//this.infoModal.show()
},
deleteMessage() {
deleteMessageFromDB(this.message._id);

View file

@ -2,8 +2,6 @@
<div class="row justify-content-end mb-2">
<!-- control area -->
<div class="col-auto p-0 m-0">
<button
v-if="getFileContent['filesize'] !== 0"
class="btn btn-outline-secondary border-0 me-1"
@ -12,7 +10,6 @@
<i class="bi bi-download"></i>
</button>
<button
class="btn btn-outline-secondary border-0 me-1"
@click="repeatMessage"
@ -74,19 +71,12 @@
</div>
</div>
</div>
</template>
<script>
import { Modal } from "bootstrap";
import { onMounted, ref } from "vue";
import {atob_FD} from "../js/freedata"
import { atob_FD } from "../js/freedata";
import {
repeatMessageTransmission,
@ -95,40 +85,35 @@ import {
getMessageAttachment,
} from "../js/chatHandler";
// pinia store setup
import { setActivePinia } from "pinia";
import pinia from "../store/index";
setActivePinia(pinia);
import { saveAs } from 'file-saver';
import { saveAs } from "file-saver";
import { useChatStore } from "../store/chatStore.js";
const chat = useChatStore(pinia);
export default {
props: {
message: Object,
},
methods: {
async downloadAttachment() {
async downloadAttachment() {
try {
// reset file store
chat.downloadFileFromDB = [];
const attachment = await getMessageAttachment(this.message._id);
const blob = new Blob([atob_FD(attachment[2])], { type: `${attachment[1]};charset=utf-8` });
const blob = new Blob([atob_FD(attachment[2])], {
type: `${attachment[1]};charset=utf-8`,
});
saveAs(blob, attachment[0]);
} catch (error) {
console.error("Failed to download attachment:", error);
}
},
},
computed: {
getFileContent() {
@ -162,20 +147,16 @@ async downloadAttachment() {
repeatMessageTransmission(this.message._id);
},
deleteMessage() {
deleteMessageFromDB(this.message._id);
},
showMessageInfo() {
requestMessageInfo(this.message._id);
//let infoModal = Modal.getOrCreateInstance(document.getElementById('messageInfoModal'))
//console.log(this.infoModal)
//this.infoModal.show()
requestMessageInfo(this.message._id);
//let infoModal = Modal.getOrCreateInstance(document.getElementById('messageInfoModal'))
//console.log(this.infoModal)
//this.infoModal.show()
},
getDateTime() {
var datetime = new Date(this.message.timestamp * 1000).toLocaleString(
navigator.language,

View file

@ -16,9 +16,7 @@ const state = useStateStore(pinia);
import { useChatStore } from "../store/chatStore.js";
const chat = useChatStore(pinia);
import {getRxBuffer} from '../js/sock.js'
import { getRxBuffer } from "../js/sock.js";
import {
Chart as ChartJS,
@ -34,11 +32,9 @@ import {
import { Line, Scatter, Bar } from "vue-chartjs";
import { ref, computed } from "vue";
import annotationPlugin from 'chartjs-plugin-annotation';
const newChatCall=ref(null);
import annotationPlugin from "chartjs-plugin-annotation";
const newChatCall = ref(null);
ChartJS.register(
CategoryScale,
@ -48,11 +44,9 @@ ChartJS.register(
Tooltip,
Legend,
BarElement,
annotationPlugin
annotationPlugin,
);
var beaconHistogramOptions = {
type: "bar",
bezierCurve: false, //remove curves from your plot
@ -68,13 +62,13 @@ var beaconHistogramOptions = {
annotation: {
annotations: [
{
type: 'line',
mode: 'horizontal',
scaleID: 'y',
type: "line",
mode: "horizontal",
scaleID: "y",
value: 0,
borderColor: 'darkgrey', // Set the color to dark grey for the zero line
borderColor: "darkgrey", // Set the color to dark grey for the zero line
borderWidth: 0.5, // Set the line width
}
},
],
},
},
@ -121,15 +115,15 @@ try {
const beaconHistogramData = computed(() => ({
labels: chat.beaconLabelArray,
datasets: [
{ data: chat.beaconDataArray, tension: 0.1, borderColor: "rgb(0, 255, 0)",
backgroundColor: function(context) {
var value = context.dataset.data[context.dataIndex];
return value >= 0 ? 'green' : 'red';
},
{
data: chat.beaconDataArray,
tension: 0.1,
borderColor: "rgb(0, 255, 0)",
backgroundColor: function (context) {
var value = context.dataset.data[context.dataIndex];
return value >= 0 ? "green" : "red";
},
},
],
}));
@ -138,17 +132,12 @@ function newChat(obj) {
let callsign = this.newChatCall.value;
callsign = callsign.toUpperCase();
chat.callsign_list.add(callsign);
this.newChatCall.value="";
this.newChatCall.value = "";
}
function syncWithModem(){
getRxBuffer()
function syncWithModem() {
getRxBuffer();
}
</script>
<template>
@ -163,7 +152,7 @@ getRxBuffer()
style="text-transform: uppercase"
placeholder="callsign"
@keypress.enter="newChat()"
ref="newChatCall"
ref="newChatCall"
/>
<button
class="btn btn-sm btn-outline-success"
@ -180,40 +169,35 @@ getRxBuffer()
<div class="col-5 ms-2 p-0">
<!-- right side of chat nav bar-->
<div class="input-group mb-0 p-0 w-50">
<button type="button" class="btn btn-outline-secondary" disabled>
Beacons
</button>
<div class="input-group mb-0 p-0 w-50 ">
<button type="button" class="btn btn-outline-secondary" disabled>
Beacons
</button>
<div class="form-floating border border-secondary-subtle border-1 rounded-end">
<Bar
:data="beaconHistogramData"
:options="beaconHistogramOptions"
width="300"
height="50"
/>
</div>
</div>
</div>
<div
class="form-floating border border-secondary-subtle border-1 rounded-end"
>
<Bar
:data="beaconHistogramData"
:options="beaconHistogramOptions"
width="300"
height="50"
/>
</div>
</div>
</div>
<div class="col-2 ms-2 p-0">
<div class="input-group mb-0 p-0 ">
<button type="button" class="btn btn-outline-secondary" @click="syncWithModem()">
Modem Sync
</button>
</div>
</div>
<div class="input-group mb-0 p-0">
<button
type="button"
class="btn btn-outline-secondary"
@click="syncWithModem()"
>
Modem Sync
</button>
</div>
</div>
</div>
</div>
</nav>

File diff suppressed because it is too large Load diff

View file

@ -167,17 +167,10 @@ const scatterChartData = computed(() => ({
},
],
}));
</script>
<script lang="ts">
import {initWaterfall} from "../js/waterfallHandler.js"
import { initWaterfall } from "../js/waterfallHandler.js";
export default {
mounted() {
@ -186,16 +179,13 @@ export default {
//const myElement = this.$refs.waterfall; // Access the DOM element with ref
// init waterfall
initWaterfall()
initWaterfall();
},
}
};
</script>
<template>
<div class="card mb-1" style="height: calc(var(--variable-height) - 20px);">
<div class="card mb-1" style="height: calc(var(--variable-height) - 20px)">
<div class="card-header p-1">
<div class="container">
<div class="row">
@ -242,7 +232,6 @@ export default {
</div>
</div>
<div class="btn-group" role="group" aria-label="Busy indicators">
<button
class="btn btn-sm ms-1 p-1 disabled"
type="button"
@ -252,7 +241,8 @@ export default {
data-bs-html="true"
v-bind:class="{
'btn-warning': state.getChannelBusySlotState(0) === true,
'btn-outline-secondary': state.getChannelBusySlotState(0) === false,
'btn-outline-secondary':
state.getChannelBusySlotState(0) === false,
}"
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
>
@ -268,7 +258,8 @@ export default {
data-bs-html="true"
v-bind:class="{
'btn-warning': state.getChannelBusySlotState(1) === true,
'btn-outline-secondary': state.getChannelBusySlotState(1) === false,
'btn-outline-secondary':
state.getChannelBusySlotState(1) === false,
}"
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
>
@ -284,7 +275,8 @@ export default {
data-bs-html="true"
v-bind:class="{
'btn-warning': state.getChannelBusySlotState(2) === true,
'btn-outline-secondary': state.getChannelBusySlotState(2) === false,
'btn-outline-secondary':
state.getChannelBusySlotState(2) === false,
}"
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
>
@ -300,7 +292,8 @@ export default {
data-bs-html="true"
v-bind:class="{
'btn-warning': state.getChannelBusySlotState(3) === true,
'btn-outline-secondary': state.getChannelBusySlotState(3) === false,
'btn-outline-secondary':
state.getChannelBusySlotState(3) === false,
}"
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
>
@ -316,7 +309,8 @@ export default {
data-bs-html="true"
v-bind:class="{
'btn-warning': state.getChannelBusySlotState(4) === true,
'btn-outline-secondary': state.getChannelBusySlotState(4) === false,
'btn-outline-secondary':
state.getChannelBusySlotState(4) === false,
}"
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
>
@ -367,7 +361,7 @@ export default {
<canvas
ref="waterfall"
id="waterfall"
style="position: relative; z-index: 2;"
style="position: relative; z-index: 2"
class="force-gpu h-100 w-100"
></canvas>
</div>

View file

@ -1,12 +1,10 @@
<script setup lang="ts">
import { setActivePinia } from "pinia";
import pinia from "../store/index";
setActivePinia(pinia);
import { useStateStore } from "../store/stateStore.js";
const state = useStateStore(pinia);
</script>
<template>
@ -26,7 +24,7 @@ const state = useStateStore(pinia);
id="ptt_state"
type="button"
title="Rig PTT state"
style="pointer-events: auto;"
style="pointer-events: auto"
disabled
>
<i class="bi bi-broadcast-pin" style="font-size: 0.8rem"></i>
@ -46,7 +44,7 @@ const state = useStateStore(pinia);
}"
title="Modem state"
disabled
style="pointer-events: auto;"
style="pointer-events: auto"
>
<i class="bi bi-cpu" style="font-size: 0.8rem"></i>
</button>
@ -64,7 +62,7 @@ const state = useStateStore(pinia);
'bg-warning': state.arq_session_state === 'connected',
}"
disabled
style="pointer-events: auto;"
style="pointer-events: auto"
title="Session state"
>
<i class="bi bi-arrow-left-right" style="font-size: 0.8rem"></i>
@ -80,7 +78,7 @@ const state = useStateStore(pinia);
'bg-warning': state.arq_state === 'True',
}"
disabled
style="pointer-events: auto;"
style="pointer-events: auto"
>
<i class="bi bi-file-earmark-binary" style="font-size: 0.8rem"></i>
</button>
@ -110,7 +108,7 @@ const state = useStateStore(pinia);
'btn-warning': state.channel_busy === 'True',
'btn-secondary': state.channel_busy === 'False',
}"
style="pointer-events: auto;"
style="pointer-events: auto"
title="Channel busy"
>
<i class="bi bi-hourglass"></i>
@ -122,9 +120,9 @@ const state = useStateStore(pinia);
class="btn btn-sm btn-secondary me-4 disabled"
type="button"
title="What's the frequency, Kenneth?"
style=" pointer-events: auto;"
style="pointer-events: auto"
>
{{ parseInt(state.frequency) / 1000 }} KHz
{{ parseInt(state.frequency) / 1000 }} KHz
</button>
</div>
@ -219,7 +217,9 @@ const state = useStateStore(pinia);
aria-valuemin="0"
aria-valuemax="100"
></div>
<p class="justify-content-center m-0 d-flex position-absolute w-100 text-dark">
<p
class="justify-content-center m-0 d-flex position-absolute w-100 text-dark"
>
{{ state.arq_seconds_until_finish }}s left
</p>
</div>
@ -248,4 +248,4 @@ const state = useStateStore(pinia);
</div>
</nav>
</template>
ww
ww

View file

@ -1,5 +1,4 @@
<script setup lang="ts">
import { setActivePinia } from "pinia";
import pinia from "../store/index";
setActivePinia(pinia);
@ -10,8 +9,10 @@ const state = useStateStore(pinia);
import { useChatStore } from "../store/chatStore.js";
const chat = useChatStore(pinia);
import { deleteChatByCallsign, getNewMessagesByDXCallsign } from "../js/chatHandler";
import {
deleteChatByCallsign,
getNewMessagesByDXCallsign,
} from "../js/chatHandler";
import { sendTestFrame, setTxAudioLevel } from "../js/sock.js";
@ -36,8 +37,8 @@ import {
LineElement,
Title,
Tooltip,
Legend
} from 'chart.js'
Legend,
} from "chart.js";
import { Line } from "vue-chartjs";
import { ref, computed } from "vue";
@ -48,113 +49,172 @@ ChartJS.register(
LineElement,
Title,
Tooltip,
Legend
)
Legend,
);
</script>
<template>
<!-- updater release notes-->
<div
class="modal fade"
ref="modalEle"
id="updaterReleaseNotes"
tabindex="-1"
aria-hidden="true"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<span class="input-group-text" id="updater_last_version"></span>
<span class="input-group-text ms-1" id="updater_last_update"></span>
<!-- updater release notes-->
<div class="modal fade" ref="modalEle" id="updaterReleaseNotes" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<span class="input-group-text" id="updater_last_version"></span>
<span class="input-group-text ms-1" id="updater_last_update"></span>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
<div class="modal-dialog modal-dialog-scrollable">
<div class="" id="updater_release_notes"></div>
</div>
</div>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="modal-dialog modal-dialog-scrollable">
<div class="" id="updater_release_notes"></div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<div class="modal-footer">
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal"
>
Close
</button>
</div>
</div>
</div>
</div>
</div>
<!-- delete chat modal -->
<div class="modal fade" ref="modalEle" id="deleteChatModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="deleteChatModalLabel">Sub menu for: {{chat.selectedCallsign}}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1">Total Messages</span>
<span class="input-group-text" id="basic-addon1">{{getNewMessagesByDXCallsign(chat.selectedCallsign)[0]}}</span>
<!-- delete chat modal -->
<div
class="modal fade"
ref="modalEle"
id="deleteChatModal"
tabindex="-1"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="deleteChatModalLabel">
Sub menu for: {{ chat.selectedCallsign }}
</h1>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1"
>Total Messages</span
>
<span class="input-group-text" id="basic-addon1">{{
getNewMessagesByDXCallsign(chat.selectedCallsign)[0]
}}</span>
</div>
<div class="input-group mb-3">
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1">New Messages</span>
<span class="input-group-text" id="basic-addon1">{{getNewMessagesByDXCallsign(chat.selectedCallsign)[1]}}</span>
<span class="input-group-text" id="basic-addon1">{{
getNewMessagesByDXCallsign(chat.selectedCallsign)[1]
}}</span>
</div>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal"
>
Close
</button>
<button
type="button"
class="btn btn-danger"
@click="deleteChat"
data-bs-dismiss="modal"
>
Delete Chat
</button>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-danger" @click="deleteChat" data-bs-dismiss="modal">Delete Chat</button>
</div>
</div>
</div>
</div>
<!-- Message Info Modal -->
<div
class="modal fade"
ref="modalEle"
id="messageInfoModal"
tabindex="-1"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="messageInfoModalLabel">
{{ chat.selectedMessageObject["uuid"] }}
</h1>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
{{ chat.selectedMessageObject }}
<!-- Message Info Modal -->
<div class="modal fade" ref="modalEle" id="messageInfoModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="messageInfoModalLabel">{{chat.selectedMessageObject["uuid"]}}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
{{chat.selectedMessageObject}}
<div class="input-group mb-3">
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1">Status</span>
<span class="input-group-text" id="basic-addon1">{{chat.selectedMessageObject["status"]}}</span>
</div>
<span class="input-group-text" id="basic-addon1">{{
chat.selectedMessageObject["status"]
}}</span>
</div>
<div class="input-group mb-3">
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1">Attempts</span>
<span class="input-group-text" id="basic-addon1">{{chat.selectedMessageObject["attempt"]}}</span>
</div>
<span class="input-group-text" id="basic-addon1">{{
chat.selectedMessageObject["attempt"]
}}</span>
</div>
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1">Bytes per Minute</span>
<span class="input-group-text" id="basic-addon1">{{chat.selectedMessageObject["bytesperminute"]}}</span>
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1"
>Bytes per Minute</span
>
<span class="input-group-text" id="basic-addon1">{{
chat.selectedMessageObject["bytesperminute"]
}}</span>
</div>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal"
>
Close
</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<!-- HELP MODALS AUDIO -->
<div
@ -757,7 +817,11 @@ ChartJS.register(
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title">
<button type="button" class="btn btn-sm btn-outline-secondary" @click="tuneAudio">
<button
type="button"
class="btn btn-sm btn-outline-secondary"
@click="tuneAudio"
>
Tune
</button>
</h5>

View file

@ -17,7 +17,6 @@ const settings = useSettingsStore(pinia);
</div>
<div class="col-3">
<strong class="fs-5">Updater</strong>
</div>
<div class="col-7">
<div class="progress w-100 ms-1 m-1">

View file

@ -15,8 +15,8 @@ import settings_exp from "./settings_exp.vue";
>
<div class="container">
<div class="badge text-bg-warning ms-3">
<i class="bi bi-exclamation-triangle"></i> Please restart the modem after
changing settings!
<i class="bi bi-exclamation-triangle"></i> Please restart the modem
after changing settings!
</div>
<!-- SETTINGS Nav tabs -->
<ul class="nav nav-tabs" id="myTab" role="tablist">

View file

@ -100,7 +100,6 @@ function saveSettings() {
v-model="settings.enable_auto_retry"
true-value="True"
false-value="False"
/>
</div>
</label>

View file

@ -94,7 +94,12 @@ function saveSettings() {
<label class="input-group-text w-50" for="inputGroupFile02"
>Received files folder</label
>
<input type="text" class="form-control w-50" id="received_files_folder" disabled/>
<input
type="text"
class="form-control w-50"
id="received_files_folder"
disabled
/>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text w-50">Update channel</span>

View file

@ -43,36 +43,32 @@ function saveSettings() {
/>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px"
>Rigctld remote ip</span
>
<input
type="text"
class="form-control"
placeholder="rigctld IP"
id="hamlib_rigctld_ip"
aria-label="Device IP"
v-model="settings.hamlib_rigctld_ip"
/>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Rigctld remote ip</span>
<input
type="text"
class="form-control"
placeholder="rigctld IP"
id="hamlib_rigctld_ip"
aria-label="Device IP"
v-model="settings.hamlib_rigctld_ip"
/>
</div>
<div class="input-group input-group-sm mb-1">
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px"
>Rigctld remote port</span
>
<input
type="text"
class="form-control"
placeholder="rigctld port"
id="hamlib_rigctld_port"
aria-label="Device Port"
v-model="settings.hamlib_rigctld_port"
/>
<input
type="text"
class="form-control"
placeholder="rigctld port"
id="hamlib_rigctld_port"
aria-label="Device Port"
v-model="settings.hamlib_rigctld_port"
/>
</div>
<hr class="m-2" />
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px"> Radio model </span>

View file

@ -17,14 +17,11 @@ const state = useStateStore(pinia);
import { useSettingsStore } from "../store/settingsStore.js";
const settings = useSettingsStore(pinia);
import { sendMessage, sendBroadcastChannel } from "./sock.js";
import { displayToast } from "./popupHandler.js";
//const FD = require("./src/js/freedata.js");
import {btoa_FD} from "./freedata.js"
import { btoa_FD } from "./freedata.js";
// split character
const split_char = "0;1;";
@ -61,8 +58,7 @@ interface messageDefaultObject {
};
}
interface beaconDefaultObject{
interface beaconDefaultObject {
command: string;
is_new: boolean;
_id: string;
@ -94,37 +90,36 @@ PouchDB.plugin(require("pouchdb-find"));
PouchDB.plugin(require("pouchdb-upsert"));
// https://stackoverflow.com/a/26227660
if(typeof process.env["APPDATA"] !== "undefined"){
var appDataFolder = process.env["APPDATA"]
console.log(appDataFolder)
if (typeof process.env["APPDATA"] !== "undefined") {
var appDataFolder = process.env["APPDATA"];
console.log(appDataFolder);
} else {
var appDataFolder: string;
var appDataFolder: string;
switch (process.platform) {
case "darwin":
appDataFolder = process.env["HOME"] + "/Library/Application Support";
console.log(appDataFolder);
break;
case "linux":
appDataFolder = process.env["HOME"] + "/.config";
console.log(appDataFolder);
break;
case "win32":
appDataFolder = "undefined";
break;
default:
appDataFolder = "undefined";
break;
}
switch (process.platform) {
case "darwin":
appDataFolder = process.env["HOME"] + "/Library/Application Support";
console.log(appDataFolder);
break;
case "linux":
appDataFolder = process.env["HOME"] + "/.config";
console.log(appDataFolder);
break;
case "win32":
appDataFolder = "undefined";
break;
default:
appDataFolder = "undefined";
break;
}
}
console.log("loading chat database...")
console.log("appdata folder:" + appDataFolder)
console.log("loading chat database...");
console.log("appdata folder:" + appDataFolder);
var configFolder = path.join(appDataFolder, "FreeDATA");
console.log("config folder:" + configFolder)
console.log("config folder:" + configFolder);
var chatDB = path.join(configFolder, "chatDB");
console.log("database path:" + chatDB)
console.log("database path:" + chatDB);
var db = new PouchDB(chatDB);
@ -135,8 +130,7 @@ var db = new PouchDB(chatDB);
/* -------- RUN A DATABASE CLEANUP ON STARTUP */
//dbClean()
updateAllChat(true)
updateAllChat(true);
// create callsign set for storing unique callsigns
chat.callsign_list = new Set();
@ -147,9 +141,9 @@ export function newBroadcast(broadcastChannel, chatmessage) {
var frames = "";
var data = "";
var file = "";
var filetype = "text";
var filename = "";
var file = "";
var filetype = "text";
var filename = "";
var file_checksum = ""; //crc32(file).toString(16).toUpperCase();
var checksum = "";
@ -167,37 +161,35 @@ export function newBroadcast(broadcastChannel, chatmessage) {
// slice uuid for reducing overhead
uuid = uuid.slice(-4);
let newChatObj: messageDefaultObject = {
command: "broadcast",
hmac_signed: false,
percent: 0,
bytesperminute: 0, // You need to assign a value here
is_new: false,
_id: uuid,
timestamp: timestamp,
dxcallsign: broadcastChannel,
dxgrid: "null",
msg: chatmessage,
checksum: file_checksum,
type: message_type,
status: "transmitting",
attempt: 1,
uuid: uuid,
duration: 0,
nacks: 0,
speed_list: "null",
_attachments: {
[filename]: {
content_type: filetype,
data: btoa_FD(file),
},
},
};
let newChatObj: messageDefaultObject = {
command: "broadcast",
hmac_signed: false,
percent: 0,
bytesperminute: 0, // You need to assign a value here
is_new: false,
_id: uuid,
timestamp: timestamp,
dxcallsign: broadcastChannel,
dxgrid: "null",
msg: chatmessage,
checksum: file_checksum,
type: message_type,
status: "transmitting",
attempt: 1,
uuid: uuid,
duration: 0,
nacks: 0,
speed_list: "null",
_attachments: {
[filename]: {
content_type: filetype,
data: btoa_FD(file),
}
}
};
//sendMessage(newChatObj)
sendBroadcastChannel(newChatObj)
//sendMessage(newChatObj)
sendBroadcastChannel(newChatObj);
addObjToDatabase(newChatObj);
}
@ -216,7 +208,7 @@ export function newMessage(
var data = "";
var filename = "";
var filetype = "";
var file=""
var file = "";
if (typeof chatFile !== "undefined") {
file = chatFile;
filetype = chatFileType;
@ -242,33 +234,32 @@ export function newMessage(
// slice uuid for reducing overhead
uuid = uuid.slice(-8);
let newChatObj: messageDefaultObject = {
command: "msg",
hmac_signed: false,
percent: 0,
bytesperminute: 0, // You need to assign a value here
is_new: false,
_id: uuid,
timestamp: timestamp,
dxcallsign: dxcallsign,
dxgrid: "null",
msg: chatmessage,
checksum: file_checksum,
type: message_type,
status: "transmitting",
attempt: 1,
uuid: uuid,
duration: 0,
nacks: 0,
speed_list: "null",
_attachments: {
[filename]: {
content_type: filetype,
data: btoa_FD(file)
}
}
};
let newChatObj: messageDefaultObject = {
command: "msg",
hmac_signed: false,
percent: 0,
bytesperminute: 0, // You need to assign a value here
is_new: false,
_id: uuid,
timestamp: timestamp,
dxcallsign: dxcallsign,
dxgrid: "null",
msg: chatmessage,
checksum: file_checksum,
type: message_type,
status: "transmitting",
attempt: 1,
uuid: uuid,
duration: 0,
nacks: 0,
speed_list: "null",
_attachments: {
[filename]: {
content_type: filetype,
data: btoa_FD(file),
},
},
};
sendMessage(newChatObj);
addObjToDatabase(newChatObj);
@ -288,7 +279,9 @@ function sortChatList() {
}
reorderedData[dxcallsign].push(obj);
reorderedData[dxcallsign] = reorderedData[dxcallsign].sort(sortByProperty("timestamp"));
reorderedData[dxcallsign] = reorderedData[dxcallsign].sort(
sortByProperty("timestamp"),
);
}
});
//console.log(reorderedData["2LS-0"])
@ -296,17 +289,14 @@ function sortChatList() {
}
//https://medium.com/@asadise/sorting-a-json-array-according-one-property-in-javascript-18b1d22cd9e9
function sortByProperty(property){
return function(a,b){
if(a[property] > b[property])
return 1;
else if(a[property] < b[property])
return -1;
return 0;
}
}
function sortByProperty(property) {
return function (a, b) {
if (a[property] > b[property]) return 1;
else if (a[property] < b[property]) return -1;
return 0;
};
}
export function getMessageAttachment(id) {
return new Promise(async (resolve, reject) => {
@ -333,28 +323,29 @@ export function getMessageAttachment(id) {
});
}
//repeat a message
export function repeatMessageTransmission(id) {
// 1. get message object by ID
// 2. Upsert Attempts
// 3. send message
db.find({
db.find({
selector: {
_id: id,
},
}).then(function (result){
console.log(result)
let obj = result.docs[0]
console.log(obj)
obj.attempt += 1
databaseUpsert(obj.uuid, "attempt", obj.attempt);
updateUnsortedChatListEntry(obj.uuid, "attempt", obj.attempt);
sendMessage(obj)
}).catch(function (err) {
console.log(err);
});
})
.then(function (result) {
console.log(result);
let obj = result.docs[0];
console.log(obj);
obj.attempt += 1;
databaseUpsert(obj.uuid, "attempt", obj.attempt);
updateUnsortedChatListEntry(obj.uuid, "attempt", obj.attempt);
sendMessage(obj);
})
.catch(function (err) {
console.log(err);
});
}
// delete a message from databse and gui
@ -374,7 +365,6 @@ export function deleteMessageFromDB(id) {
chat.sorted_chat_list = sortChatList();
}
//Function to clean old beacons and optimize database
async function dbClean() {
//Only keep the most x latest days of beacons
@ -384,7 +374,6 @@ async function dbClean() {
(Date.now() - beaconKeep * 24 * 60 * 60 * 1000) / 1000,
);
//Items to purge from database
var purgeFilter = [
{ type: "beacon" },
@ -404,7 +393,7 @@ async function dbClean() {
//console.log("Purging " + result.docs.length + " beacons received before " + timestampPurge);
itemCount = result.docs.length;
result.docs.forEach(async function (item) {
await deleteMessageFromDB(item._id)
await deleteMessageFromDB(item._id);
});
})
.catch(function (err) {
@ -415,20 +404,13 @@ async function dbClean() {
//Too slow on older/slower machines
//await db.compact();
let message = "Database maintenance is complete";
displayToast("info", "bi bi-info-circle", message, 5000);
let message = "Database maintenance is complete"
displayToast("info", "bi bi-info-circle", message, 5000);
message = "Removed "+itemCount+" items from database"
displayToast("info", "bi bi-info-circle", message, 5000);
message = "Removed " + itemCount + " items from database";
displayToast("info", "bi bi-info-circle", message, 5000);
}
// function to update transmission status
export function updateTransmissionStatus(obj) {
// update database entries
@ -436,23 +418,19 @@ export function updateTransmissionStatus(obj) {
databaseUpsert(obj.uuid, "bytesperminute", obj.bytesperminute);
databaseUpsert(obj.uuid, "status", obj.status);
// update screen rendering / messages
updateUnsortedChatListEntry(obj.uuid, "percent", obj.percent);
updateUnsortedChatListEntry(obj.uuid, "bytesperminute", obj.bytesperminute);
updateUnsortedChatListEntry(obj.uuid, "status", obj.status);
}
export function updateUnsortedChatListEntry(uuid, object, value) {
var data = getFromUnsortedChatListByUUID(uuid)
if(data){
var data = getFromUnsortedChatListByUUID(uuid);
if (data) {
data[object] = value;
console.log("Entry updated:", data[object]);
chat.sorted_chat_list = sortChatList();
return data;
}
/*
@ -470,43 +448,39 @@ export function updateUnsortedChatListEntry(uuid, object, value) {
return null; // Return null if not found
}
function getFromUnsortedChatListByUUID(uuid){
for (const entry of chat.unsorted_chat_list) {
if (entry.uuid === uuid) {
return entry;
}
function getFromUnsortedChatListByUUID(uuid) {
for (const entry of chat.unsorted_chat_list) {
if (entry.uuid === uuid) {
return entry;
}
return false;
}
return false;
}
export function getNewMessagesByDXCallsign(dxcallsign): [number, number, any]{
let new_counter = 0
let total_counter = 0
let item_array = []
if (typeof dxcallsign !== 'undefined'){
for (const key in chat.sorted_chat_list[dxcallsign]){
//console.log(chat.sorted_chat_list[dxcallsign][key])
//item_array.push(chat.sorted_chat_list[dxcallsign][key])
if(chat.sorted_chat_list[dxcallsign][key].is_new){
item_array.push(chat.sorted_chat_list[dxcallsign][key])
new_counter += 1
export function getNewMessagesByDXCallsign(dxcallsign): [number, number, any] {
let new_counter = 0;
let total_counter = 0;
let item_array = [];
if (typeof dxcallsign !== "undefined") {
for (const key in chat.sorted_chat_list[dxcallsign]) {
//console.log(chat.sorted_chat_list[dxcallsign][key])
//item_array.push(chat.sorted_chat_list[dxcallsign][key])
if (chat.sorted_chat_list[dxcallsign][key].is_new) {
item_array.push(chat.sorted_chat_list[dxcallsign][key]);
new_counter += 1;
}
total_counter += 1
total_counter += 1;
}
}
return [total_counter, new_counter, item_array];
}
return [total_counter, new_counter, item_array];
export function resetIsNewMessage(uuid, value) {
databaseUpsert(uuid, "is_new", value);
updateUnsortedChatListEntry(uuid, "is_new", value);
}
export function resetIsNewMessage(uuid, value){
databaseUpsert(uuid, "is_new", value)
updateUnsortedChatListEntry(uuid, "is_new", value);
}
export function databaseUpsert(id, object, value) {
db.upsert(id, function (doc) {
if (!doc[object]) {
@ -527,70 +501,61 @@ export function databaseUpsert(id, object, value) {
// function for fetching all messages from chat / updating chat
export async function updateAllChat(cleanup) {
// run cleanup if requested
if (cleanup) {
await dbClean()
}
let indexFields = [
{dxcallsign: "asc"},
{timestamp: "asc"}
]
// run cleanup if requested
if (cleanup) {
await dbClean();
}
let indexFields = [{ dxcallsign: "asc" }, { timestamp: "asc" }];
let filter = {
selector: {
$and: [
{ dxcallsign: { $exists: true } },
{ timestamp: { $exists: true } },
//{ $or: chat.chat_filter },
],
},
sort: [{ dxcallsign: "asc" }, { timestamp: "asc" }],
selector: {
$and: [
{ dxcallsign: { $exists: true } },
{ timestamp: { $exists: true } },
//{ $or: chat.chat_filter },
],
},
sort: [{ dxcallsign: "asc" }, { timestamp: "asc" }],
};
//"{ dxcallsign: \"asc\" }, { timestamp: \"asc\" }"
await createIndex(indexFields);
getFromDBByFilter(filter)
.then(function (result) {
for (var item of (result as any).docs) {
const dxcallsign = item.dxcallsign;
// Check if dxcallsign already exists as a property in the result object
if (!chat.sorted_beacon_list[dxcallsign]) {
// If not, initialize it with an empty array for snr values
chat.sorted_beacon_list[dxcallsign] = {
dxcallsign,
snr: [],
timestamp: [],
};
chat.callsign_list.add(dxcallsign);
}
//"{ dxcallsign: \"asc\" }, { timestamp: \"asc\" }"
await createIndex(indexFields);
getFromDBByFilter(filter)
.then(function (result) {
for (var item of (result as any).docs) {
const dxcallsign = item.dxcallsign;
// Check if dxcallsign already exists as a property in the result object
if (!chat.sorted_beacon_list[dxcallsign]) {
// If not, initialize it with an empty array for snr values
chat.sorted_beacon_list[dxcallsign] = {
dxcallsign,
snr: [],
timestamp: [],
};
chat.callsign_list.add(dxcallsign);
}
if (item.type === "beacon") {
//console.log(item);
if (item.type === "beacon") {
//console.log(item);
// TODO: sort beacon list .... maybe a part for a separate function
const jsonData = [item];
// Process each JSON item step by step
jsonData.forEach((jsonitem) => {
const { snr, timestamp } = item;
// TODO: sort beacon list .... maybe a part for a separate function
const jsonData = [item];
// Push the snr value to the corresponding dxcallsign's snr array
chat.sorted_beacon_list[dxcallsign].snr.push(snr);
chat.sorted_beacon_list[dxcallsign].timestamp.push(timestamp);
});
} else {
chat.unsorted_chat_list.push(item);
chat.sorted_chat_list = sortChatList();
}
}
})
.catch(function (err) {
console.log(err);
});
// Process each JSON item step by step
jsonData.forEach((jsonitem) => {
const { snr, timestamp } = item;
// Push the snr value to the corresponding dxcallsign's snr array
chat.sorted_beacon_list[dxcallsign].snr.push(snr);
chat.sorted_beacon_list[dxcallsign].timestamp.push(timestamp);
});
} else {
chat.unsorted_chat_list.push(item);
chat.sorted_chat_list = sortChatList();
}
}
})
.catch(function (err) {
console.log(err);
});
}
function addObjToDatabase(newobj) {
@ -610,12 +575,10 @@ function addObjToDatabase(newobj) {
console.log("new database entry");
console.log(response);
if (newobj.command === "msg") {
chat.unsorted_chat_list.push(newobj);
chat.sorted_chat_list = sortChatList();
}
})
.catch(function (err) {
console.log(err);
@ -624,11 +587,8 @@ function addObjToDatabase(newobj) {
// try upserting status in case we tried sending a message to our selfes
databaseUpsert(newobj.uuid, "status", newobj.status);
updateUnsortedChatListEntry(newobj.uuid, "status", newobj.status);
});
/*
// upsert footer ...
@ -659,7 +619,7 @@ function createChatIndex() {
"is_new",
"nacks",
"duration",
"speed_list"
"speed_list",
],
},
})
@ -681,8 +641,6 @@ export function deleteChatByCallsign(callsign) {
deleteFromDatabaseByCallsign(callsign);
}
function deleteFromDatabaseByCallsign(callsign) {
db.find({
selector: {
@ -730,18 +688,18 @@ export function newBeaconReceived(obj) {
"mycallsign": "DJ2LS-0"
}
*/
let newChatObj: beaconDefaultObject = {
command: "beacon",
is_new: false,
_id: obj["uuid"],
timestamp: obj["timestamp"],
dxcallsign: obj["dxcallsign"],
dxgrid: obj["dxgrid"],
type: "beacon",
status: obj["beacon"],
uuid: obj["uuid"],
snr: obj["snr"], // adding the new field
};
let newChatObj: beaconDefaultObject = {
command: "beacon",
is_new: false,
_id: obj["uuid"],
timestamp: obj["timestamp"],
dxcallsign: obj["dxcallsign"],
dxgrid: obj["dxgrid"],
type: "beacon",
status: obj["beacon"],
uuid: obj["uuid"],
snr: obj["snr"], // adding the new field
};
addObjToDatabase(newChatObj);
@ -769,13 +727,11 @@ let newChatObj: beaconDefaultObject = {
});
// check if auto retry enabled
console.log("-----------------------------------------")
console.log(settings.enable_auto_retry.toUpperCase())
if (settings.enable_auto_retry.toUpperCase() == "TRUE") {
console.log("-----------------------------------------");
console.log(settings.enable_auto_retry.toUpperCase());
if (settings.enable_auto_retry.toUpperCase() == "TRUE") {
checkForWaitingMessages(dxcallsign);
}
}
// function for handling a received message
@ -857,33 +813,32 @@ export function newMessageReceived(message, protocol) {
*/
console.log(protocol);
let newChatObj: messageDefaultObject = {
command: "msg",
hmac_signed: protocol["hmac_signed"],
percent: 100,
bytesperminute: protocol["bytesperminute"],
is_new: true,
_id: message[3],
timestamp: message[4],
dxcallsign: protocol["dxcallsign"],
dxgrid: protocol["dxgrid"],
msg: message[5],
checksum: message[2],
type: protocol["status"],
status: protocol["status"],
attempt: 1,
uuid: message[3],
duration: protocol["duration"],
nacks: protocol["nacks"],
speed_list: protocol["speed_list"],
_attachments: {
[message[6]]: {
content_type: message[7],
data: btoa_FD(message[8])
}
}
};
let newChatObj: messageDefaultObject = {
command: "msg",
hmac_signed: protocol["hmac_signed"],
percent: 100,
bytesperminute: protocol["bytesperminute"],
is_new: true,
_id: message[3],
timestamp: message[4],
dxcallsign: protocol["dxcallsign"],
dxgrid: protocol["dxgrid"],
msg: message[5],
checksum: message[2],
type: protocol["status"],
status: protocol["status"],
attempt: 1,
uuid: message[3],
duration: protocol["duration"],
nacks: protocol["nacks"],
speed_list: protocol["speed_list"],
_attachments: {
[message[6]]: {
content_type: message[7],
data: btoa_FD(message[8]),
},
},
};
// some tweaks for broadcasts
if (protocol.fec == "broadcast") {
@ -906,31 +861,26 @@ export function setStateSuccess() {
state.arq_seconds_until_timeout_percent = 100;
}
export function requestMessageInfo(id){
console.log(id)
// id and uuid are the same
var data = getFromUnsortedChatListByUUID(id)
console.log(data)
chat.selectedMessageObject = data
export function requestMessageInfo(id) {
console.log(id);
// id and uuid are the same
var data = getFromUnsortedChatListByUUID(id);
console.log(data);
chat.selectedMessageObject = data;
}
async function createIndex(myIndexFields)
{
db.createIndex({
index: {
fields: myIndexFields,
},
})
.catch(err => {
console.log(err);
});
async function createIndex(myIndexFields) {
db.createIndex({
index: {
fields: myIndexFields,
},
}).catch((err) => {
console.log(err);
});
}
async function getFromDBByFilter(filter) {
/*
async function getFromDBByFilter(filter) {
/*
USAGE:
let filter = {
@ -951,54 +901,53 @@ getFromDBByFilter(filter)
});
*/
return new Promise((resolve, reject) => {
return db.find(filter)
.then(result => {
console.log(result);
resolve(result);
})
.catch(err => {
console.log(err);
reject(err);
})})
return new Promise((resolve, reject) => {
return db
.find(filter)
.then((result) => {
console.log(result);
resolve(result);
})
.catch((err) => {
console.log(err);
reject(err);
});
});
}
async function checkForWaitingMessages(dxcall) {
let filter = {
let filter = {
selector: {
dxcallsign: dxcall,
type: "transmit",
status: "failed",
//attempt: { $lt: parseInt(config.max_retry_attempts) }
},
}
};
getFromDBByFilter(filter)
.then(result => {
// @ts-expect-error
let message = "Found " + result.docs.length + " waiting messages for " + dxcall
getFromDBByFilter(filter)
.then((result) => {
// @ts-expect-error
let message =
"Found " + result.docs.length + " waiting messages for " + dxcall;
console.log(message);
displayToast("info", "bi bi-info-circle", message, 5000);
console.log(message);
displayToast("info", "bi bi-info-circle", message, 5000);
// handle result
// @ts-expect-error
if (result.docs.length > 0) {
// only want to process the first available item object, then return
// this ensures, we are only sending one message at once
// @ts-expect-error
// @ts-expect-error
if (result.docs[0].attempt < settings.max_retry_attempts) {
// @ts-expect-error
repeatMessageTransmission(result.docs[0].uuid)
// @ts-expect-error
repeatMessageTransmission(result.docs[0].uuid);
}
return;
}
})
.catch(err => {
console.log(err)
});
}
})
.catch((err) => {
console.log(err);
});
}

View file

@ -116,14 +116,13 @@ daemon.on("data", function (socketdata) {
stackoverflow.com questions 9070700 nodejs-net-createserver-large-amount-of-data-coming-in
*/
socketdata = socketchunk.join("\n") + socketdata.toString("utf8"); //append incoming data to socketchunk
//socketdata = socketdata.toString("utf8"); // convert data to string
socketdata = socketchunk.join("\n") + socketdata.toString("utf8"); //append incoming data to socketchunk
//socketdata = socketdata.toString("utf8"); // convert data to string
//socketchunk += socketdata; // append data to buffer so we can stick long data together
// check if we received begin and end of json data
if (socketdata.startsWith('{"') && socketdata.endsWith('"}\n')) {
var data = "";
// split data into chunks if we received multiple commands
@ -151,25 +150,19 @@ daemon.on("data", function (socketdata) {
}
}
console.log(data)
console.log(data);
if (data["command"] == "daemon_state") {
// update audio devices by putting them to audio store
audioStore.inputDevices = data["input_devices"];
audioStore.outputDevices = data["output_devices"];
settings.serial_devices = data["serial_devices"];
state.python_version = data["python_version"]
state.modem_version = data["version"]
state.python_version = data["python_version"];
state.modem_version = data["version"];
state.modem_running_state = data["daemon_state"][0]["status"];
state.rigctld_started = data["rigctld_state"][0]["status"];
//state.rigctld_process = data["daemon_state"][0]["rigctld_process"];
}
if (data["command"] == "test_hamlib") {
let Data = {
hamlib_result: data["result"],
@ -246,7 +239,8 @@ export function startModem() {
// STOP Modem
//exports.stopModem = function () {
export function stopModem() {
var command = '{"type" : "set", "command": "stop_modem" , "parameter": "---" }';
var command =
'{"type" : "set", "command": "stop_modem" , "parameter": "---" }';
writeDaemonCommand(command);
}
@ -289,44 +283,38 @@ function testHamlib(
}
export function startRigctld() {
var json_command = JSON.stringify({
type: "set",
command: "start_rigctld",
parameter: [
{
hamlib_deviceid: settings.hamlib_deviceid,
hamlib_deviceport: settings.hamlib_deviceport,
hamlib_stop_bits: settings.hamlib_stop_bits,
hamlib_data_bits: settings.hamlib_data_bits,
hamlib_handshake: settings.hamlib_handshake,
hamlib_serialspeed: settings.hamlib_serialspeed,
hamlib_dtrstate: settings.hamlib_dtrstate,
hamlib_pttprotocol: settings.hamlib_pttprotocol,
hamlib_ptt_port: settings.hamlib_ptt_port,
hamlib_dcd: settings.hamlib_dcd,
hamlbib_serialspeed_ptt: settings.hamlib_serialspeed,
hamlib_rigctld_port: settings.hamlib_rigctld_port,
hamlib_rigctld_ip: settings.hamlib_rigctld_ip,
hamlib_rigctld_path: settings.hamlib_rigctld_path,
hamlib_rigctld_server_port: settings.hamlib_rigctld_server_port,
hamlib_rigctld_custom_args: settings.hamlib_rigctld_custom_args
hamlib_deviceid: settings.hamlib_deviceid,
hamlib_deviceport: settings.hamlib_deviceport,
hamlib_stop_bits: settings.hamlib_stop_bits,
hamlib_data_bits: settings.hamlib_data_bits,
hamlib_handshake: settings.hamlib_handshake,
hamlib_serialspeed: settings.hamlib_serialspeed,
hamlib_dtrstate: settings.hamlib_dtrstate,
hamlib_pttprotocol: settings.hamlib_pttprotocol,
hamlib_ptt_port: settings.hamlib_ptt_port,
hamlib_dcd: settings.hamlib_dcd,
hamlbib_serialspeed_ptt: settings.hamlib_serialspeed,
hamlib_rigctld_port: settings.hamlib_rigctld_port,
hamlib_rigctld_ip: settings.hamlib_rigctld_ip,
hamlib_rigctld_path: settings.hamlib_rigctld_path,
hamlib_rigctld_server_port: settings.hamlib_rigctld_server_port,
hamlib_rigctld_custom_args: settings.hamlib_rigctld_custom_args,
},
],
});
console.log(json_command);
writeDaemonCommand(json_command);
}
export function stopRigctld(){
export function stopRigctld() {
let command = '{"type" : "set", "command": "stop_rigctld"}';
writeDaemonCommand(command);
}
//Save myCall
function saveMyCall(callsign) {
//exports.saveMyCall = function (callsign) {
@ -344,5 +332,3 @@ function saveMyGrid(grid) {
'{"type" : "set", "command": "mygrid" , "parameter": "' + grid + '"}';
writeDaemonCommand(command);
}

View file

@ -6,24 +6,24 @@ const fs = require("fs");
* @returns base64 encoded string
*/
export function btoa_FD(data) {
//exports.btoa_FD = function (data) {
//exports.btoa_FD = function (data) {
return Buffer.from(data, "utf-8").toString("base64");
};
}
/**
* ASCII to Binary replacement
* @param {string} data in base64 encoding
* @returns utf-8 normal/usual string
*/
export function atob_FD(data) {
//exports.atob_FD = function (data) {
//exports.atob_FD = function (data) {
return Buffer.from(data, "base64").toString("utf-8");
};
}
/**
* UTF8 to ASCII btoa
* @param {string} data in base64 encoding
* @returns base64 bota compatible data for use in browser
*/
export function atob(data) {
//exports.atob = function (data) {
//exports.atob = function (data) {
return window.btoa(Buffer.from(data, "base64").toString("utf8"));
};
}

View file

@ -15,43 +15,40 @@ import { useSettingsStore } from "../store/settingsStore.js";
const settings = useSettingsStore(pinia);
// ---------------------------------
console.log(process.env)
if(typeof process.env["APPDATA"] !== "undefined"){
var appDataFolder = process.env["APPDATA"]
console.log(appDataFolder)
console.log(process.env);
if (typeof process.env["APPDATA"] !== "undefined") {
var appDataFolder = process.env["APPDATA"];
console.log(appDataFolder);
} else {
switch (process.platform) {
case "darwin":
var appDataFolder = process.env["HOME"] + "/Library/Application Support";
console.log(appDataFolder)
switch (process.platform) {
case "darwin":
var appDataFolder = process.env["HOME"] + "/Library/Application Support";
console.log(appDataFolder);
break;
case "linux":
var appDataFolder = process.env["HOME"] + "/.config";
console.log(appDataFolder)
break;
case "linux":
var appDataFolder = process.env["HOME"] + "/.config";
console.log(appDataFolder);
break;
case "linux":
var appDataFolder = "undefined";
break;
case "win32":
var appDataFolder = "undefined";
break;
default:
var appDataFolder = "undefined";
break;
}
break;
case "linux":
var appDataFolder = "undefined";
break;
case "win32":
var appDataFolder = "undefined";
break;
default:
var appDataFolder = "undefined";
break;
}
}
var configFolder = path.join(appDataFolder, "FreeDATA");
var configPath = path.join(configFolder, "config.json");
console.log(appDataFolder)
console.log(configFolder)
console.log(configPath)
console.log(appDataFolder);
console.log(configFolder);
console.log(configPath);
// create config folder if not exists
if (!fs.existsSync(configFolder)) {

View file

@ -1,11 +1,10 @@
var net = require("net");
const path = require("path");
//const FD = require("./src/js/freedata.js");
import {atob_FD, btoa_FD} from "./freedata"
import { atob_FD, btoa_FD } from "./freedata";
//import FD from './freedata.js';
import {addDataToWaterfall} from "../js/waterfallHandler.js"
import { addDataToWaterfall } from "../js/waterfallHandler.js";
import {
newMessageReceived,
@ -167,7 +166,7 @@ client.on("data", function (socketdata) {
continue;
}
}
//console.log(data)
//console.log(data)
if (data["command"] == "modem_state") {
//console.log(data)
// set length of RX Buffer to global variable
@ -186,9 +185,7 @@ client.on("data", function (socketdata) {
stateStore.channel_busy = data["channel_busy"];
stateStore.channel_busy_slot = data["channel_busy_slot"];
addDataToWaterfall(JSON.parse(data["fft"]))
addDataToWaterfall(JSON.parse(data["fft"]));
if (data["scatter"].length > 0) {
stateStore.scatter = data["scatter"];
@ -253,7 +250,7 @@ client.on("data", function (socketdata) {
arq_rx_frame_n_bursts: data["arq_rx_frame_n_bursts"],
arq_rx_n_current_arq_frame: data["arq_rx_n_current_arq_frame"],
arq_n_arq_frames_per_data_frame:
data["arq_n_arq_frames_per_data_frame"],
data["arq_n_arq_frames_per_data_frame"],
arq_bytes_per_minute: data["arq_bytes_per_minute"],
arq_compression_factor: data["arq_compression_factor"],
routing_table: data["routing_table"],
@ -272,7 +269,10 @@ client.on("data", function (socketdata) {
if (data["freedata"] == "modem-message") {
// break early if we received a dummy callsign
// thats a kind of hotfix, as long as the modem isnt handling this better
if (data["dxcallsign"] == "AA0AA-0" || data["dxcallsign"] == "ZZ9YY-0") {
if (
data["dxcallsign"] == "AA0AA-0" ||
data["dxcallsign"] == "ZZ9YY-0"
) {
break;
}
@ -334,7 +334,12 @@ client.on("data", function (socketdata) {
switch (data["beacon"]) {
case "transmitting":
// BEACON TRANSMITTING
displayToast("success", "bi-broadcast-pin", "Transmitting beacon", 5000);
displayToast(
"success",
"bi-broadcast-pin",
"Transmitting beacon",
5000,
);
break;
case "received":
@ -357,14 +362,20 @@ client.on("data", function (socketdata) {
case "received":
// PING RECEIVED
message =
"Ping request from " + data["dxcallsign"] + " | " + data["dxgrid"];
"Ping request from " +
data["dxcallsign"] +
" | " +
data["dxgrid"];
displayToast("success", "bi-arrow-right-short", message, 5000);
break;
case "acknowledge":
// PING ACKNOWLEDGE
message =
"Received ping-ack from " + data["dxcallsign"] + " | " + data["dxgrid"];
"Received ping-ack from " +
data["dxcallsign"] +
" | " +
data["dxgrid"];
displayToast("success", "bi-arrow-left-right", message, 5000);
break;
}
@ -485,7 +496,6 @@ client.on("data", function (socketdata) {
}
}
}
}
//finally delete message buffer
@ -596,24 +606,22 @@ function sendFile(
// Send Message
export function sendMessage(obj) {
let dxcallsign = obj.dxcallsign;
let checksum = obj.checksum;
let uuid = obj.uuid;
let command = obj.command;
let dxcallsign = obj.dxcallsign
let checksum = obj.checksum
let uuid = obj.uuid
let command = obj.command
let filename = Object.keys(obj._attachments)[0];
//let filetype = filename.split(".")[1]
let filetype = obj._attachments[filename].content_type;
let file = obj._attachments[filename].data;
let filename = Object.keys(obj._attachments)[0]
//let filetype = filename.split(".")[1]
let filetype = obj._attachments[filename].content_type
let file = obj._attachments[filename].data
//console.log(obj._attachments)
//console.log(filename)
//console.log(filetype)
//console.log(file)
//console.log(obj._attachments)
//console.log(filename)
//console.log(filetype)
//console.log(file)
let data_with_attachment =
let data_with_attachment =
obj.timestamp +
split_char +
obj.msg +
@ -764,8 +772,7 @@ export function stopTransmission() {
export function getRxBuffer() {
var command = '{"type" : "get", "command" : "rx_buffer"}';
writeTncCommand(command);
writeTncCommand(command);
}
// START BEACON
@ -827,12 +834,11 @@ export function sendFecIsWriting(mycallsign) {
// SEND FEC TO BROADCASTCHANNEL
//export function sendBroadcastChannel(channel, data_out, uuid) {
export function sendBroadcastChannel(obj) {
let checksum = obj.checksum;
let command = obj.command;
let uuid = obj.uuid;
let channel = obj.dxcallsign
let data_out = obj.msg
let channel = obj.dxcallsign;
let data_out = obj.msg;
let data = btoa_FD(
"m" +

View file

@ -1,5 +1,4 @@
import {Spectrum} from "../assets/waterfall/spectrum.js"
import { Spectrum } from "../assets/waterfall/spectrum.js";
import { setActivePinia } from "pinia";
import pinia from "../store/index";
@ -8,27 +7,23 @@ setActivePinia(pinia);
import { useSettingsStore } from "../store/settingsStore.js";
const settings = useSettingsStore(pinia);
var spectrum = new Object();
export function initWaterfall() {
spectrum = new Spectrum("waterfall", {
spectrumPercent: 0,
wf_rows: 192, //Assuming 1 row = 1 pixe1, 192 is the height of the spectrum container
});
var spectrum = new Object
export function initWaterfall(){
spectrum = new Spectrum("waterfall", {
spectrumPercent: 0,
wf_rows: 192, //Assuming 1 row = 1 pixe1, 192 is the height of the spectrum container
});
console.log(settings.wftheme)
spectrum.setColorMap(settings.wftheme);
console.log(settings.wftheme);
spectrum.setColorMap(settings.wftheme);
}
export function addDataToWaterfall(data){
//console.log(spectrum)
try {
spectrum.addData(data);
} catch (e) {
//console.log(e);
}
}
export function addDataToWaterfall(data) {
//console.log(spectrum)
try {
spectrum.addData(data);
} catch (e) {
//console.log(e);
}
}

View file

@ -1,33 +1,29 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import {loadSettings} from './js/settingsHandler'
import './styles.css'
import { createApp } from "vue";
import { createPinia } from "pinia";
import { loadSettings } from "./js/settingsHandler";
import "./styles.css";
// Import all of Bootstrap's JS
//import * as bootstrap from 'bootstrap'
import 'bootstrap/dist/js/bootstrap.bundle.min.js'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-icons/font/bootstrap-icons.css'
import "bootstrap/dist/js/bootstrap.bundle.min.js";
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap-icons/font/bootstrap-icons.css";
// Import our custom CSS
//import './scss/styles.scss'
import App from './App.vue'
const app = createApp(App)
import App from "./App.vue";
const app = createApp(App);
//.mount('#app').$nextTick(() => postMessage({ payload: 'removeLoading' }, '*'))
const pinia = createPinia()
app.mount('#app')
const pinia = createPinia();
app.mount("#app");
app.use(pinia)
loadSettings()
app.use(pinia);
loadSettings();
//import './js/settingsHandler.js'
import './js/daemon'
import './js/sock.js'
import "./js/daemon";
import "./js/sock.js";
//import './js/settingsHandler.js'

View file

@ -12,19 +12,17 @@ export const useAudioStore = defineStore("audioStore", () => {
var inputDevices = ref([{ id: 0, name: "no input devices" }]);
var outputDevices = ref([{ id: 0, name: "no output devices" }]);
var startupInputDevice = ref(0)
var startupOutputDevice = ref(0)
var startupInputDevice = ref(0);
var startupOutputDevice = ref(0);
function getInputDevices() {
var html = "";
for (var key in inputDevices.value) {
let selected = ''
if (inputDevices.value[key]["name"] == settings.rx_audio){
selected = "selected"
let selected = "";
if (inputDevices.value[key]["name"] == settings.rx_audio) {
selected = "selected";
} else {
selected = ''
selected = "";
}
html += `<option value=${inputDevices.value[key]["id"]} ${selected}>${inputDevices.value[key]["name"]}</option>`;
@ -35,17 +33,23 @@ export const useAudioStore = defineStore("audioStore", () => {
function getOutputDevices() {
var html = "";
for (var key in outputDevices.value) {
let selected = ''
if (outputDevices.value[key]["name"] == settings.tx_audio){
selected = "selected"
let selected = "";
if (outputDevices.value[key]["name"] == settings.tx_audio) {
selected = "selected";
} else {
selected = ''
selected = "";
}
html += `<option value=${outputDevices.value[key]["id"]} ${selected}>${outputDevices.value[key]["name"]}</option>`;
}
return html;
}
return { inputDevices, outputDevices, getInputDevices, getOutputDevices, startupInputDevice, startupOutputDevice };
return {
inputDevices,
outputDevices,
getInputDevices,
getOutputDevices,
startupInputDevice,
startupOutputDevice,
};
});

View file

@ -16,31 +16,31 @@ export const useChatStore = defineStore("chatStore", () => {
var selectedCallsign = ref();
// we need a default value in our ref because of our message info modal
var selectedMessageObject = ref({
"command": "msg",
"hmac_signed": false,
"percent": 0,
"is_new": false,
"_id": "2ead6698",
"timestamp": 1697289795,
"dxcallsign": "DJ2LS-0",
"dxgrid": "null",
"msg": "test",
"checksum": "",
"type": "transmit",
"status": "transmitting",
"attempt": 1,
"uuid": "2ead6698",
"duration": 0,
"nacks": 0,
"speed_list": "null",
"_attachments": {
"": {
"content_type": "text",
"data": ""
}
}
});
var inputText = ref('');
command: "msg",
hmac_signed: false,
percent: 0,
is_new: false,
_id: "2ead6698",
timestamp: 1697289795,
dxcallsign: "DJ2LS-0",
dxgrid: "null",
msg: "test",
checksum: "",
type: "transmit",
status: "transmitting",
attempt: 1,
uuid: "2ead6698",
duration: 0,
nacks: 0,
speed_list: "null",
_attachments: {
"": {
content_type: "text",
data: "",
},
},
});
var inputText = ref("");
var inputFile = ref();
var inputFileName = ref();
var inputFileType = ref();
@ -62,8 +62,6 @@ export const useChatStore = defineStore("chatStore", () => {
var beaconDataArray = ref([]);
var beaconLabelArray = ref([]);
return {
selectedCallsign,
selectedMessageObject,

View file

@ -3,8 +3,8 @@ import { ref } from "vue";
export const useSettingsStore = defineStore("settingsStore", () => {
// audio
var tx_audio = ref()
var rx_audio = ref()
var tx_audio = ref();
var rx_audio = ref();
// network
var modem_host = ref("127.0.0.1");
@ -77,19 +77,19 @@ export const useSettingsStore = defineStore("settingsStore", () => {
var enable_mesh_features = ref("False");
var serial_devices = ref();
function getSerialDevices() {
if (this.hamlib_deviceport == "ignore")
var html = '<option value ="ignore" selected>None - (use custom options for hamlib)</option>';
var html =
'<option value ="ignore" selected>None - (use custom options for hamlib)</option>';
else
var html = '<option value ="ignore">None - (use custom options for hamlib)</option>';
var html =
'<option value ="ignore">None - (use custom options for hamlib)</option>';
for (var key in serial_devices.value) {
let selected = ''
if (serial_devices.value[key]["port"] == this. hamlib_deviceport){
selected = "selected"
let selected = "";
if (serial_devices.value[key]["port"] == this.hamlib_deviceport) {
selected = "selected";
} else {
selected = ''
selected = "";
}
html += `<option value="${serial_devices.value[key]["port"]}" ${selected}>${serial_devices.value[key]["port"]} - ${serial_devices.value[key]["description"]}</option>`;
@ -223,6 +223,6 @@ export const useSettingsStore = defineStore("settingsStore", () => {
tx_audio,
rx_audio,
getSerialDevices,
serial_devices
serial_devices,
};
});

View file

@ -59,24 +59,24 @@ export const useStateStore = defineStore("stateStore", () => {
var python_version = ref();
var modem_version = ref();
function getChannelBusySlotState(slot){
function getChannelBusySlotState(slot) {
const slot_state = channel_busy_slot.value;
if (typeof slot_state !== 'undefined') {
if (typeof slot_state !== "undefined") {
// Replace 'False' with 'false' to match JavaScript's boolean representation
const string = slot_state.replace(/False/g, 'false').replace(/True/g, 'true');
const string = slot_state
.replace(/False/g, "false")
.replace(/True/g, "true");
// Parse the string to get an array
const arr = JSON.parse(string);
return arr[slot]
return arr[slot];
} else {
// Handle the undefined case
return false;
}
}
}
function updateTncState(state) {
modem_connection.value = state;
@ -175,6 +175,6 @@ function getChannelBusySlotState(slot){
rigctld_started,
rigctld_process,
python_version,
modem_version
modem_version,
};
});

View file

@ -1,18 +1,18 @@
import { rmSync } from 'node:fs'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import electron from 'vite-plugin-electron'
import renderer from 'vite-plugin-electron-renderer'
import { notBundle } from 'vite-plugin-electron/plugin'
import pkg from './package.json'
import { rmSync } from "node:fs";
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import electron from "vite-plugin-electron";
import renderer from "vite-plugin-electron-renderer";
import { notBundle } from "vite-plugin-electron/plugin";
import pkg from "./package.json";
// https://vitejs.dev/config/
export default defineConfig(({ command }) => {
rmSync('dist-electron', { recursive: true, force: true })
rmSync("dist-electron", { recursive: true, force: true });
const isServe = command === 'serve'
const isBuild = command === 'build'
const sourcemap = isServe || !!process.env.VSCODE_DEBUG
const isServe = command === "serve";
const isBuild = command === "build";
const sourcemap = isServe || !!process.env.VSCODE_DEBUG;
return {
plugins: [
@ -20,25 +20,29 @@ export default defineConfig(({ command }) => {
electron([
{
// Main process entry file of the Electron App.
entry: 'electron/main/index.ts',
entry: "electron/main/index.ts",
onstart({ startup }) {
if (process.env.VSCODE_DEBUG) {
console.log(/* For `.vscode/.debug.script.mjs` */'[startup] Electron App')
console.log(
/* For `.vscode/.debug.script.mjs` */ "[startup] Electron App",
);
} else {
startup()
startup();
}
},
vite: {
build: {
sourcemap,
minify: isBuild,
outDir: 'dist-electron/main',
outDir: "dist-electron/main",
rollupOptions: {
// Some third-party Node.js libraries may not be built correctly by Vite, especially `C/C++` addons,
// we can use `external` to exclude them to ensure they work correctly.
// Others need to put them in `dependencies` to ensure they are collected into `app.asar` after the app is built.
// Of course, this is not absolute, just this way is relatively simple. :)
external: Object.keys('dependencies' in pkg ? pkg.dependencies : {}),
external: Object.keys(
"dependencies" in pkg ? pkg.dependencies : {},
),
},
},
plugins: [
@ -49,40 +53,42 @@ export default defineConfig(({ command }) => {
},
},
{
entry: 'electron/preload/index.ts',
entry: "electron/preload/index.ts",
onstart({ reload }) {
// Notify the Renderer process to reload the page when the Preload scripts build is complete,
// instead of restarting the entire Electron App.
reload()
reload();
},
vite: {
build: {
sourcemap: sourcemap ? 'inline' : undefined, // #332
sourcemap: sourcemap ? "inline" : undefined, // #332
minify: isBuild,
outDir: 'dist-electron/preload',
outDir: "dist-electron/preload",
rollupOptions: {
external: Object.keys('dependencies' in pkg ? pkg.dependencies : {}),
external: Object.keys(
"dependencies" in pkg ? pkg.dependencies : {},
),
},
},
plugins: [
isServe && notBundle(),
],
plugins: [isServe && notBundle()],
},
}
},
]),
// Use Node.js API in the Renderer process
renderer(),
],
server: process.env.VSCODE_DEBUG && (() => {
const url = new URL(pkg.debug.env.VITE_DEV_SERVER_URL)
return {
host: url.hostname,
port: +url.port,
}
})(),
define: {
'import.meta.env.PACKAGE_VERSION':JSON.stringify(pkg.version)
},
server:
process.env.VSCODE_DEBUG &&
(() => {
const url = new URL(pkg.debug.env.VITE_DEV_SERVER_URL);
return {
host: url.hostname,
port: +url.port,
};
})(),
define: {
"import.meta.env.PACKAGE_VERSION": JSON.stringify(pkg.version),
},
clearScreen: false,
}
})
};
});