mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
[CodeFactor] Apply fixes
This commit is contained in:
parent
c39af3f830
commit
90401e7df5
|
@ -1,10 +1,9 @@
|
||||||
import { app, BrowserWindow, shell, ipcMain } from 'electron'
|
import { app, BrowserWindow, shell, ipcMain } from "electron";
|
||||||
import { release, platform } from 'node:os'
|
import { release, platform } from "node:os";
|
||||||
import { join } from 'node:path'
|
import { join } from "node:path";
|
||||||
import { autoUpdater } from "electron-updater"
|
import { autoUpdater } from "electron-updater";
|
||||||
import { existsSync } from "fs"
|
import { existsSync } from "fs";
|
||||||
import { spawn } from "child_process"
|
import { spawn } from "child_process";
|
||||||
|
|
||||||
|
|
||||||
// The built directory structure
|
// The built directory structure
|
||||||
//
|
//
|
||||||
|
@ -16,22 +15,22 @@ import { spawn } from "child_process"
|
||||||
// ├─┬ dist
|
// ├─┬ dist
|
||||||
// │ └── index.html > Electron-Renderer
|
// │ └── index.html > Electron-Renderer
|
||||||
//
|
//
|
||||||
process.env.DIST_ELECTRON = join(__dirname, '..')
|
process.env.DIST_ELECTRON = join(__dirname, "..");
|
||||||
process.env.DIST = join(process.env.DIST_ELECTRON, '../dist')
|
process.env.DIST = join(process.env.DIST_ELECTRON, "../dist");
|
||||||
process.env.VITE_PUBLIC = process.env.VITE_DEV_SERVER_URL
|
process.env.VITE_PUBLIC = process.env.VITE_DEV_SERVER_URL
|
||||||
? join(process.env.DIST_ELECTRON, '../public')
|
? join(process.env.DIST_ELECTRON, "../public")
|
||||||
: process.env.DIST
|
: process.env.DIST;
|
||||||
|
|
||||||
// Disable GPU Acceleration for Windows 7
|
// 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
|
// 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()) {
|
if (!app.requestSingleInstanceLock()) {
|
||||||
close_sub_processes()
|
close_sub_processes();
|
||||||
app.quit()
|
app.quit();
|
||||||
process.exit(0)
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove electron security warnings
|
// Remove electron security warnings
|
||||||
|
@ -41,18 +40,18 @@ if (!app.requestSingleInstanceLock()) {
|
||||||
|
|
||||||
// set daemon process var
|
// set daemon process var
|
||||||
var daemonProcess = null;
|
var daemonProcess = null;
|
||||||
let win: BrowserWindow | null = null
|
let win: BrowserWindow | null = null;
|
||||||
// Here, you can also use other preload
|
// Here, you can also use other preload
|
||||||
const preload = join(__dirname, '../preload/index.js')
|
const preload = join(__dirname, "../preload/index.js");
|
||||||
const url = process.env.VITE_DEV_SERVER_URL
|
const url = process.env.VITE_DEV_SERVER_URL;
|
||||||
const indexHtml = join(process.env.DIST, 'index.html')
|
const indexHtml = join(process.env.DIST, "index.html");
|
||||||
|
|
||||||
async function createWindow() {
|
async function createWindow() {
|
||||||
win = new BrowserWindow({
|
win = new BrowserWindow({
|
||||||
title: 'FreeDATA',
|
title: "FreeDATA",
|
||||||
width: 1200,
|
width: 1200,
|
||||||
height: 670,
|
height: 670,
|
||||||
icon: join(process.env.VITE_PUBLIC, 'icon_cube_border.png'),
|
icon: join(process.env.VITE_PUBLIC, "icon_cube_border.png"),
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
preload,
|
preload,
|
||||||
|
@ -64,29 +63,29 @@ async function createWindow() {
|
||||||
nodeIntegration: true,
|
nodeIntegration: true,
|
||||||
contextIsolation: false,
|
contextIsolation: false,
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
if (process.env.VITE_DEV_SERVER_URL) { // electron-vite-vue#298
|
if (process.env.VITE_DEV_SERVER_URL) {
|
||||||
win.loadURL(url)
|
// electron-vite-vue#298
|
||||||
|
win.loadURL(url);
|
||||||
// Open devTool if the app is not packaged
|
// Open devTool if the app is not packaged
|
||||||
win.webContents.openDevTools()
|
win.webContents.openDevTools();
|
||||||
} else {
|
} else {
|
||||||
win.loadFile(indexHtml)
|
win.loadFile(indexHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test actively push message to the Electron-Renderer
|
// Test actively push message to the Electron-Renderer
|
||||||
win.webContents.on('did-finish-load', () => {
|
win.webContents.on("did-finish-load", () => {
|
||||||
win?.webContents.send('main-process-message', new Date().toLocaleString())
|
win?.webContents.send("main-process-message", new Date().toLocaleString());
|
||||||
})
|
});
|
||||||
|
|
||||||
// Make all links open with the browser, not with the application
|
// Make all links open with the browser, not with the application
|
||||||
win.webContents.setWindowOpenHandler(({ url }) => {
|
win.webContents.setWindowOpenHandler(({ url }) => {
|
||||||
if (url.startsWith('https:')) shell.openExternal(url)
|
if (url.startsWith("https:")) shell.openExternal(url);
|
||||||
return { action: 'deny' }
|
return { action: "deny" };
|
||||||
})
|
});
|
||||||
// win.webContents.on('will-navigate', (event, url) => { }) #344
|
// win.webContents.on('will-navigate', (event, url) => { }) #344
|
||||||
|
|
||||||
|
|
||||||
win.once("ready-to-show", () => {
|
win.once("ready-to-show", () => {
|
||||||
//autoUpdater.logger = log.scope("updater");
|
//autoUpdater.logger = log.scope("updater");
|
||||||
//autoUpdater.channel = config.update_channel;
|
//autoUpdater.channel = config.update_channel;
|
||||||
|
@ -95,14 +94,11 @@ async function createWindow() {
|
||||||
autoUpdater.checkForUpdatesAndNotify();
|
autoUpdater.checkForUpdatesAndNotify();
|
||||||
//autoUpdater.quitAndInstall();
|
//autoUpdater.quitAndInstall();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//app.whenReady().then(
|
//app.whenReady().then(
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
|
createWindow();
|
||||||
createWindow()
|
|
||||||
|
|
||||||
//Generate daemon binary path
|
//Generate daemon binary path
|
||||||
var daemonPath = "";
|
var daemonPath = "";
|
||||||
|
@ -114,11 +110,7 @@ createWindow()
|
||||||
break;
|
break;
|
||||||
case "win32":
|
case "win32":
|
||||||
case "win64":
|
case "win64":
|
||||||
daemonPath = join(
|
daemonPath = join(process.resourcesPath, "modem", "freedata-daemon.exe");
|
||||||
process.resourcesPath,
|
|
||||||
"modem",
|
|
||||||
"freedata-daemon.exe",
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log("Unhandled OS Platform: ", platform());
|
console.log("Unhandled OS Platform: ", platform());
|
||||||
|
@ -156,59 +148,49 @@ createWindow()
|
||||||
console.log("Daemon binary doesn't exist--normal for dev environments.");
|
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', () => {
|
app.on("second-instance", () => {
|
||||||
win = null
|
|
||||||
if (process.platform !== 'darwin') app.quit(
|
|
||||||
close_sub_processes()
|
|
||||||
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
app.on('second-instance', () => {
|
|
||||||
if (win) {
|
if (win) {
|
||||||
// Focus on the main window if the user tried to open another
|
// Focus on the main window if the user tried to open another
|
||||||
if (win.isMinimized()) win.restore()
|
if (win.isMinimized()) win.restore();
|
||||||
win.focus()
|
win.focus();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
app.on('activate', () => {
|
app.on("activate", () => {
|
||||||
const allWindows = BrowserWindow.getAllWindows()
|
const allWindows = BrowserWindow.getAllWindows();
|
||||||
if (allWindows.length) {
|
if (allWindows.length) {
|
||||||
allWindows[0].focus()
|
allWindows[0].focus();
|
||||||
} else {
|
} else {
|
||||||
createWindow()
|
createWindow();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
// New window example arg: new windows url
|
// New window example arg: new windows url
|
||||||
ipcMain.handle('open-win', (_, arg) => {
|
ipcMain.handle("open-win", (_, arg) => {
|
||||||
const childWindow = new BrowserWindow({
|
const childWindow = new BrowserWindow({
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
preload,
|
preload,
|
||||||
nodeIntegration: true,
|
nodeIntegration: true,
|
||||||
contextIsolation: false,
|
contextIsolation: false,
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
if (process.env.VITE_DEV_SERVER_URL) {
|
if (process.env.VITE_DEV_SERVER_URL) {
|
||||||
childWindow.loadURL(`${url}#${arg}`)
|
childWindow.loadURL(`${url}#${arg}`);
|
||||||
} else {
|
} 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) => {
|
ipcMain.on("request-restart-and-install-update", (event, data) => {
|
||||||
close_sub_processes();
|
close_sub_processes();
|
||||||
autoUpdater.quitAndInstall();
|
autoUpdater.quitAndInstall();
|
||||||
|
@ -275,7 +257,6 @@ autoUpdater.on("error", (error) => {
|
||||||
console.log("AUTO UPDATER : " + error);
|
console.log("AUTO UPDATER : " + error);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function close_sub_processes() {
|
function close_sub_processes() {
|
||||||
console.log("closing sub processes");
|
console.log("closing sub processes");
|
||||||
|
|
||||||
|
@ -307,4 +288,4 @@ function close_sub_processes() {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,34 @@
|
||||||
import { ipcRenderer } from "electron"
|
import { ipcRenderer } from "electron";
|
||||||
import { autoUpdater } from "electron-updater"
|
import { autoUpdater } from "electron-updater";
|
||||||
|
|
||||||
|
function domReady(
|
||||||
|
condition: DocumentReadyState[] = ["complete", "interactive"],
|
||||||
function domReady(condition: DocumentReadyState[] = ['complete', 'interactive']) {
|
) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
if (condition.includes(document.readyState)) {
|
if (condition.includes(document.readyState)) {
|
||||||
resolve(true)
|
resolve(true);
|
||||||
} else {
|
} else {
|
||||||
document.addEventListener('readystatechange', () => {
|
document.addEventListener("readystatechange", () => {
|
||||||
if (condition.includes(document.readyState)) {
|
if (condition.includes(document.readyState)) {
|
||||||
resolve(true)
|
resolve(true);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const safeDOM = {
|
const safeDOM = {
|
||||||
append(parent: HTMLElement, child: HTMLElement) {
|
append(parent: HTMLElement, child: HTMLElement) {
|
||||||
if (!Array.from(parent.children).find(e => e === child)) {
|
if (!Array.from(parent.children).find((e) => e === child)) {
|
||||||
return parent.appendChild(child)
|
return parent.appendChild(child);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
remove(parent: HTMLElement, child: HTMLElement) {
|
remove(parent: HTMLElement, child: HTMLElement) {
|
||||||
if (Array.from(parent.children).find(e => e === child)) {
|
if (Array.from(parent.children).find((e) => e === child)) {
|
||||||
return parent.removeChild(child)
|
return parent.removeChild(child);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://tobiasahlin.com/spinkit
|
* https://tobiasahlin.com/spinkit
|
||||||
|
@ -37,7 +37,7 @@ const safeDOM = {
|
||||||
* https://matejkustec.github.io/SpinThatShit
|
* https://matejkustec.github.io/SpinThatShit
|
||||||
*/
|
*/
|
||||||
function useLoading() {
|
function useLoading() {
|
||||||
const className = `loaders-css__square-spin`
|
const className = `loaders-css__square-spin`;
|
||||||
const styleContent = `
|
const styleContent = `
|
||||||
@keyframes square-spin {
|
@keyframes square-spin {
|
||||||
0% {
|
0% {
|
||||||
|
@ -82,55 +82,48 @@ function useLoading() {
|
||||||
background: #282c34;
|
background: #282c34;
|
||||||
z-index: 99999;
|
z-index: 99999;
|
||||||
}
|
}
|
||||||
`
|
`;
|
||||||
const oStyle = document.createElement('style')
|
const oStyle = document.createElement("style");
|
||||||
const oDiv = document.createElement('div')
|
const oDiv = document.createElement("div");
|
||||||
|
|
||||||
oStyle.id = 'app-loading-style'
|
oStyle.id = "app-loading-style";
|
||||||
oStyle.innerHTML = styleContent
|
oStyle.innerHTML = styleContent;
|
||||||
oDiv.className = 'app-loading-wrap'
|
oDiv.className = "app-loading-wrap";
|
||||||
oDiv.innerHTML = `<div class="${className}"><div></div></div>`
|
oDiv.innerHTML = `<div class="${className}"><div></div></div>`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
appendLoading() {
|
appendLoading() {
|
||||||
safeDOM.append(document.head, oStyle)
|
safeDOM.append(document.head, oStyle);
|
||||||
safeDOM.append(document.body, oDiv)
|
safeDOM.append(document.body, oDiv);
|
||||||
},
|
},
|
||||||
removeLoading() {
|
removeLoading() {
|
||||||
safeDOM.remove(document.head, oStyle)
|
safeDOM.remove(document.head, oStyle);
|
||||||
safeDOM.remove(document.body, oDiv)
|
safeDOM.remove(document.body, oDiv);
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
const { appendLoading, removeLoading } = useLoading()
|
const { appendLoading, removeLoading } = useLoading();
|
||||||
domReady().then(appendLoading)
|
domReady().then(appendLoading);
|
||||||
|
|
||||||
|
|
||||||
window.onmessage = (ev) => {
|
window.onmessage = (ev) => {
|
||||||
ev.data.payload === 'removeLoading' && removeLoading()
|
ev.data.payload === "removeLoading" && removeLoading();
|
||||||
}
|
};
|
||||||
|
|
||||||
setTimeout(removeLoading, 4999)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
setTimeout(removeLoading, 4999);
|
||||||
|
|
||||||
window.addEventListener("DOMContentLoaded", () => {
|
window.addEventListener("DOMContentLoaded", () => {
|
||||||
// we are using this area for implementing the electron runUpdater
|
// we are using this area for implementing the electron runUpdater
|
||||||
// we need access to DOM for displaying updater results in GUI
|
// we need access to DOM for displaying updater results in GUI
|
||||||
// close app, update and restart
|
// close app, update and restart
|
||||||
document
|
document
|
||||||
.getElementById("update_and_install")
|
.getElementById("update_and_install")
|
||||||
.addEventListener("click", () => {
|
.addEventListener("click", () => {
|
||||||
ipcRenderer.send("request-restart-and-install-update");
|
ipcRenderer.send("request-restart-and-install-update");
|
||||||
});
|
});
|
||||||
|
});
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
// IPC ACTION FOR AUTO UPDATER
|
// IPC ACTION FOR AUTO UPDATER
|
||||||
ipcRenderer.on("action-updater", (event, arg) => {
|
ipcRenderer.on("action-updater", (event, arg) => {
|
||||||
|
@ -181,11 +174,12 @@ ipcRenderer.on("action-updater", (event, arg) => {
|
||||||
//autoUpdater.quitAndInstall();
|
//autoUpdater.quitAndInstall();
|
||||||
}
|
}
|
||||||
if (arg.status == "update-not-available") {
|
if (arg.status == "update-not-available") {
|
||||||
|
document.getElementById("updater_last_version").innerHTML =
|
||||||
document.getElementById("updater_last_version").innerHTML = arg.info.releaseName
|
arg.info.releaseName;
|
||||||
document.getElementById("updater_last_update").innerHTML = arg.info.releaseDate
|
document.getElementById("updater_last_update").innerHTML =
|
||||||
document.getElementById("updater_release_notes").innerHTML = arg.info.releaseNotes
|
arg.info.releaseDate;
|
||||||
|
document.getElementById("updater_release_notes").innerHTML =
|
||||||
|
arg.info.releaseNotes;
|
||||||
|
|
||||||
document.getElementById("updater_status").innerHTML =
|
document.getElementById("updater_status").innerHTML =
|
||||||
'<i class="bi bi-check2-square ms-1 me-1" style="color: white;"></i>';
|
'<i class="bi bi-check2-square ms-1 me-1" style="color: white;"></i>';
|
||||||
|
|
|
@ -14,29 +14,30 @@ const state = useStateStore(pinia);
|
||||||
import { useChatStore } from "../store/chatStore.js";
|
import { useChatStore } from "../store/chatStore.js";
|
||||||
const chat = useChatStore(pinia);
|
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";
|
import chat_conversations_entry from "./chat_conversations_entry.vue";
|
||||||
|
|
||||||
|
|
||||||
function chatSelected(callsign) {
|
function chatSelected(callsign) {
|
||||||
chat.selectedCallsign = callsign.toUpperCase();
|
chat.selectedCallsign = callsign.toUpperCase();
|
||||||
|
|
||||||
// scroll message container to bottom
|
// scroll message container to bottom
|
||||||
var messageBody = document.getElementById("message-container");
|
var messageBody = document.getElementById("message-container");
|
||||||
if (messageBody != null ) {
|
if (messageBody != null) {
|
||||||
// needs sensible defaults
|
// needs sensible defaults
|
||||||
messageBody.scrollTop = messageBody.scrollHeight - messageBody.clientHeight;
|
messageBody.scrollTop = messageBody.scrollHeight - messageBody.clientHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getNewMessagesByDXCallsign(callsign)[1] > 0){
|
if (getNewMessagesByDXCallsign(callsign)[1] > 0) {
|
||||||
let messageArray = getNewMessagesByDXCallsign(callsign)[2]
|
let messageArray = getNewMessagesByDXCallsign(callsign)[2];
|
||||||
console.log(messageArray)
|
console.log(messageArray);
|
||||||
|
|
||||||
for (const key in messageArray){
|
for (const key in messageArray) {
|
||||||
resetIsNewMessage(messageArray[key].uuid, false)
|
resetIsNewMessage(messageArray[key].uuid, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -58,7 +59,7 @@ function chatSelected(callsign) {
|
||||||
<template v-for="(item, key) in chat.callsign_list" :key="item.dxcallsign">
|
<template v-for="(item, key) in chat.callsign_list" :key="item.dxcallsign">
|
||||||
<a
|
<a
|
||||||
class="list-group-item list-group-item-action border-0 border-bottom rounded-0"
|
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}`"
|
:id="`list-chat-list-${item}`"
|
||||||
data-bs-toggle="list"
|
data-bs-toggle="list"
|
||||||
:href="`#list-${item}-messages`"
|
:href="`#list-${item}-messages`"
|
||||||
|
@ -66,15 +67,15 @@ function chatSelected(callsign) {
|
||||||
aria-controls="list-{{item}}-messages"
|
aria-controls="list-{{item}}-messages"
|
||||||
@click="chatSelected(item)"
|
@click="chatSelected(item)"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-9">{{ item }}
|
<div class="col-9">
|
||||||
<span class="badge rounded-pill bg-danger" v-if="getNewMessagesByDXCallsign(item)[1] > 0">
|
{{ item }}
|
||||||
{{getNewMessagesByDXCallsign(item)[1]}} new messages
|
<span
|
||||||
|
class="badge rounded-pill bg-danger"
|
||||||
|
v-if="getNewMessagesByDXCallsign(item)[1] > 0"
|
||||||
|
>
|
||||||
|
{{ getNewMessagesByDXCallsign(item)[1] }} new messages
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<button
|
<button
|
||||||
|
|
|
@ -57,17 +57,13 @@ function getDateTime(timestampRaw) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="item.type === 'beacon' && item.status === 'received'">
|
<div v-if="item.type === 'beacon' && item.status === 'received'">
|
||||||
<!-- {{ item }} -->
|
<!-- {{ item }} -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="item.type === 'ping'">
|
<div v-if="item.type === 'ping'">{{ item.snr }} dB ping received</div>
|
||||||
{{ item.snr }} dB
|
|
||||||
ping received
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="item.type === 'ping-ack'">
|
<div v-if="item.type === 'ping-ack'">
|
||||||
{{ item.snr }} dB
|
{{ item.snr }} dB ping-ack received
|
||||||
ping-ack received
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="item.type === 'transmit'">
|
<div v-if="item.type === 'transmit'">
|
||||||
|
|
|
@ -23,8 +23,7 @@
|
||||||
|
|
||||||
<!-- Delete button outside of the card -->
|
<!-- Delete button outside of the card -->
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
|
<button
|
||||||
<button
|
|
||||||
class="btn btn-outline-secondary border-0 me-1"
|
class="btn btn-outline-secondary border-0 me-1"
|
||||||
@click="showMessageInfo"
|
@click="showMessageInfo"
|
||||||
data-bs-target="#messageInfoModal"
|
data-bs-target="#messageInfoModal"
|
||||||
|
@ -49,42 +48,42 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { deleteMessageFromDB, requestMessageInfo, getMessageAttachment } from "../js/chatHandler";
|
import {
|
||||||
import {atob_FD} from "../js/freedata"
|
deleteMessageFromDB,
|
||||||
|
requestMessageInfo,
|
||||||
|
getMessageAttachment,
|
||||||
|
} from "../js/chatHandler";
|
||||||
|
import { atob_FD } from "../js/freedata";
|
||||||
|
|
||||||
// pinia store setup
|
// pinia store setup
|
||||||
import { setActivePinia } from "pinia";
|
import { setActivePinia } from "pinia";
|
||||||
import pinia from "../store/index";
|
import pinia from "../store/index";
|
||||||
setActivePinia(pinia);
|
setActivePinia(pinia);
|
||||||
import { saveAs } from 'file-saver';
|
import { saveAs } from "file-saver";
|
||||||
|
|
||||||
import { useChatStore } from "../store/chatStore.js";
|
import { useChatStore } from "../store/chatStore.js";
|
||||||
const chat = useChatStore(pinia);
|
const chat = useChatStore(pinia);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
message: Object,
|
message: Object,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async downloadAttachment() {
|
||||||
async downloadAttachment() {
|
|
||||||
try {
|
try {
|
||||||
// reset file store
|
// reset file store
|
||||||
chat.downloadFileFromDB = [];
|
chat.downloadFileFromDB = [];
|
||||||
|
|
||||||
const attachment = await getMessageAttachment(this.message._id);
|
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();
|
window.focus();
|
||||||
saveAs(blob, attachment[0]);
|
saveAs(blob, attachment[0]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to download attachment:", error);
|
console.error("Failed to download attachment:", error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
getFileContent() {
|
getFileContent() {
|
||||||
|
@ -112,10 +111,10 @@ async downloadAttachment() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
showMessageInfo() {
|
showMessageInfo() {
|
||||||
requestMessageInfo(this.message._id);
|
requestMessageInfo(this.message._id);
|
||||||
//let infoModal = Modal.getOrCreateInstance(document.getElementById('messageInfoModal'))
|
//let infoModal = Modal.getOrCreateInstance(document.getElementById('messageInfoModal'))
|
||||||
//console.log(this.infoModal)
|
//console.log(this.infoModal)
|
||||||
//this.infoModal.show()
|
//this.infoModal.show()
|
||||||
},
|
},
|
||||||
deleteMessage() {
|
deleteMessage() {
|
||||||
deleteMessageFromDB(this.message._id);
|
deleteMessageFromDB(this.message._id);
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
<div class="row justify-content-end mb-2">
|
<div class="row justify-content-end mb-2">
|
||||||
<!-- control area -->
|
<!-- control area -->
|
||||||
<div class="col-auto p-0 m-0">
|
<div class="col-auto p-0 m-0">
|
||||||
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
v-if="getFileContent['filesize'] !== 0"
|
v-if="getFileContent['filesize'] !== 0"
|
||||||
class="btn btn-outline-secondary border-0 me-1"
|
class="btn btn-outline-secondary border-0 me-1"
|
||||||
|
@ -12,7 +10,6 @@
|
||||||
<i class="bi bi-download"></i>
|
<i class="bi bi-download"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn btn-outline-secondary border-0 me-1"
|
class="btn btn-outline-secondary border-0 me-1"
|
||||||
@click="repeatMessage"
|
@click="repeatMessage"
|
||||||
|
@ -74,19 +71,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import { Modal } from "bootstrap";
|
import { Modal } from "bootstrap";
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import {atob_FD} from "../js/freedata"
|
import { atob_FD } from "../js/freedata";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
repeatMessageTransmission,
|
repeatMessageTransmission,
|
||||||
|
@ -95,40 +85,35 @@ import {
|
||||||
getMessageAttachment,
|
getMessageAttachment,
|
||||||
} from "../js/chatHandler";
|
} from "../js/chatHandler";
|
||||||
|
|
||||||
|
|
||||||
// pinia store setup
|
// pinia store setup
|
||||||
import { setActivePinia } from "pinia";
|
import { setActivePinia } from "pinia";
|
||||||
import pinia from "../store/index";
|
import pinia from "../store/index";
|
||||||
setActivePinia(pinia);
|
setActivePinia(pinia);
|
||||||
import { saveAs } from 'file-saver';
|
import { saveAs } from "file-saver";
|
||||||
|
|
||||||
import { useChatStore } from "../store/chatStore.js";
|
import { useChatStore } from "../store/chatStore.js";
|
||||||
const chat = useChatStore(pinia);
|
const chat = useChatStore(pinia);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
message: Object,
|
message: Object,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
async downloadAttachment() {
|
||||||
async downloadAttachment() {
|
|
||||||
try {
|
try {
|
||||||
// reset file store
|
// reset file store
|
||||||
chat.downloadFileFromDB = [];
|
chat.downloadFileFromDB = [];
|
||||||
|
|
||||||
const attachment = await getMessageAttachment(this.message._id);
|
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]);
|
saveAs(blob, attachment[0]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to download attachment:", error);
|
console.error("Failed to download attachment:", error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
getFileContent() {
|
getFileContent() {
|
||||||
|
@ -162,20 +147,16 @@ async downloadAttachment() {
|
||||||
repeatMessageTransmission(this.message._id);
|
repeatMessageTransmission(this.message._id);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
deleteMessage() {
|
deleteMessage() {
|
||||||
deleteMessageFromDB(this.message._id);
|
deleteMessageFromDB(this.message._id);
|
||||||
},
|
},
|
||||||
showMessageInfo() {
|
showMessageInfo() {
|
||||||
requestMessageInfo(this.message._id);
|
requestMessageInfo(this.message._id);
|
||||||
//let infoModal = Modal.getOrCreateInstance(document.getElementById('messageInfoModal'))
|
//let infoModal = Modal.getOrCreateInstance(document.getElementById('messageInfoModal'))
|
||||||
//console.log(this.infoModal)
|
//console.log(this.infoModal)
|
||||||
//this.infoModal.show()
|
//this.infoModal.show()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
getDateTime() {
|
getDateTime() {
|
||||||
var datetime = new Date(this.message.timestamp * 1000).toLocaleString(
|
var datetime = new Date(this.message.timestamp * 1000).toLocaleString(
|
||||||
navigator.language,
|
navigator.language,
|
||||||
|
|
|
@ -16,9 +16,7 @@ const state = useStateStore(pinia);
|
||||||
import { useChatStore } from "../store/chatStore.js";
|
import { useChatStore } from "../store/chatStore.js";
|
||||||
const chat = useChatStore(pinia);
|
const chat = useChatStore(pinia);
|
||||||
|
|
||||||
import {getRxBuffer} from '../js/sock.js'
|
import { getRxBuffer } from "../js/sock.js";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Chart as ChartJS,
|
Chart as ChartJS,
|
||||||
|
@ -34,11 +32,9 @@ import {
|
||||||
|
|
||||||
import { Line, Scatter, Bar } from "vue-chartjs";
|
import { Line, Scatter, Bar } from "vue-chartjs";
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed } from "vue";
|
||||||
import annotationPlugin from 'chartjs-plugin-annotation';
|
import annotationPlugin from "chartjs-plugin-annotation";
|
||||||
|
|
||||||
const newChatCall=ref(null);
|
|
||||||
|
|
||||||
|
|
||||||
|
const newChatCall = ref(null);
|
||||||
|
|
||||||
ChartJS.register(
|
ChartJS.register(
|
||||||
CategoryScale,
|
CategoryScale,
|
||||||
|
@ -48,11 +44,9 @@ ChartJS.register(
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Legend,
|
Legend,
|
||||||
BarElement,
|
BarElement,
|
||||||
annotationPlugin
|
annotationPlugin,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var beaconHistogramOptions = {
|
var beaconHistogramOptions = {
|
||||||
type: "bar",
|
type: "bar",
|
||||||
bezierCurve: false, //remove curves from your plot
|
bezierCurve: false, //remove curves from your plot
|
||||||
|
@ -68,13 +62,13 @@ var beaconHistogramOptions = {
|
||||||
annotation: {
|
annotation: {
|
||||||
annotations: [
|
annotations: [
|
||||||
{
|
{
|
||||||
type: 'line',
|
type: "line",
|
||||||
mode: 'horizontal',
|
mode: "horizontal",
|
||||||
scaleID: 'y',
|
scaleID: "y",
|
||||||
value: 0,
|
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
|
borderWidth: 0.5, // Set the line width
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -121,15 +115,15 @@ try {
|
||||||
const beaconHistogramData = computed(() => ({
|
const beaconHistogramData = computed(() => ({
|
||||||
labels: chat.beaconLabelArray,
|
labels: chat.beaconLabelArray,
|
||||||
datasets: [
|
datasets: [
|
||||||
{ data: chat.beaconDataArray, tension: 0.1, borderColor: "rgb(0, 255, 0)",
|
{
|
||||||
|
data: chat.beaconDataArray,
|
||||||
backgroundColor: function(context) {
|
tension: 0.1,
|
||||||
var value = context.dataset.data[context.dataIndex];
|
borderColor: "rgb(0, 255, 0)",
|
||||||
return value >= 0 ? 'green' : 'red';
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
let callsign = this.newChatCall.value;
|
||||||
callsign = callsign.toUpperCase();
|
callsign = callsign.toUpperCase();
|
||||||
chat.callsign_list.add(callsign);
|
chat.callsign_list.add(callsign);
|
||||||
this.newChatCall.value="";
|
this.newChatCall.value = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function syncWithModem() {
|
||||||
function syncWithModem(){
|
getRxBuffer();
|
||||||
|
|
||||||
getRxBuffer()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -163,7 +152,7 @@ getRxBuffer()
|
||||||
style="text-transform: uppercase"
|
style="text-transform: uppercase"
|
||||||
placeholder="callsign"
|
placeholder="callsign"
|
||||||
@keypress.enter="newChat()"
|
@keypress.enter="newChat()"
|
||||||
ref="newChatCall"
|
ref="newChatCall"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-outline-success"
|
class="btn btn-sm btn-outline-success"
|
||||||
|
@ -180,40 +169,35 @@ getRxBuffer()
|
||||||
<div class="col-5 ms-2 p-0">
|
<div class="col-5 ms-2 p-0">
|
||||||
<!-- right side of chat nav bar-->
|
<!-- 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 ">
|
<div
|
||||||
|
class="form-floating border border-secondary-subtle border-1 rounded-end"
|
||||||
|
>
|
||||||
<button type="button" class="btn btn-outline-secondary" disabled>
|
<Bar
|
||||||
Beacons
|
:data="beaconHistogramData"
|
||||||
</button>
|
:options="beaconHistogramOptions"
|
||||||
|
width="300"
|
||||||
<div class="form-floating border border-secondary-subtle border-1 rounded-end">
|
height="50"
|
||||||
|
/>
|
||||||
<Bar
|
</div>
|
||||||
:data="beaconHistogramData"
|
</div>
|
||||||
:options="beaconHistogramOptions"
|
</div>
|
||||||
width="300"
|
|
||||||
height="50"
|
|
||||||
|
|
||||||
/>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-2 ms-2 p-0">
|
<div class="col-2 ms-2 p-0">
|
||||||
|
<div class="input-group mb-0 p-0">
|
||||||
<div class="input-group mb-0 p-0 ">
|
<button
|
||||||
|
type="button"
|
||||||
<button type="button" class="btn btn-outline-secondary" @click="syncWithModem()">
|
class="btn btn-outline-secondary"
|
||||||
Modem Sync
|
@click="syncWithModem()"
|
||||||
</button>
|
>
|
||||||
</div>
|
Modem Sync
|
||||||
</div>
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -167,17 +167,10 @@ const scatterChartData = computed(() => ({
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { initWaterfall } from "../js/waterfallHandler.js";
|
||||||
import {initWaterfall} from "../js/waterfallHandler.js"
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -186,16 +179,13 @@ export default {
|
||||||
//const myElement = this.$refs.waterfall; // Access the DOM element with ref
|
//const myElement = this.$refs.waterfall; // Access the DOM element with ref
|
||||||
|
|
||||||
// init waterfall
|
// init waterfall
|
||||||
initWaterfall()
|
initWaterfall();
|
||||||
|
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<template>
|
<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="card-header p-1">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -242,7 +232,6 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group" role="group" aria-label="Busy indicators">
|
<div class="btn-group" role="group" aria-label="Busy indicators">
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm ms-1 p-1 disabled"
|
class="btn btn-sm ms-1 p-1 disabled"
|
||||||
type="button"
|
type="button"
|
||||||
|
@ -252,7 +241,8 @@ export default {
|
||||||
data-bs-html="true"
|
data-bs-html="true"
|
||||||
v-bind:class="{
|
v-bind:class="{
|
||||||
'btn-warning': state.getChannelBusySlotState(0) === true,
|
'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>"
|
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"
|
data-bs-html="true"
|
||||||
v-bind:class="{
|
v-bind:class="{
|
||||||
'btn-warning': state.getChannelBusySlotState(1) === true,
|
'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>"
|
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"
|
data-bs-html="true"
|
||||||
v-bind:class="{
|
v-bind:class="{
|
||||||
'btn-warning': state.getChannelBusySlotState(2) === true,
|
'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>"
|
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"
|
data-bs-html="true"
|
||||||
v-bind:class="{
|
v-bind:class="{
|
||||||
'btn-warning': state.getChannelBusySlotState(3) === true,
|
'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>"
|
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"
|
data-bs-html="true"
|
||||||
v-bind:class="{
|
v-bind:class="{
|
||||||
'btn-warning': state.getChannelBusySlotState(4) === true,
|
'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>"
|
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
|
||||||
>
|
>
|
||||||
|
@ -367,7 +361,7 @@ export default {
|
||||||
<canvas
|
<canvas
|
||||||
ref="waterfall"
|
ref="waterfall"
|
||||||
id="waterfall"
|
id="waterfall"
|
||||||
style="position: relative; z-index: 2;"
|
style="position: relative; z-index: 2"
|
||||||
class="force-gpu h-100 w-100"
|
class="force-gpu h-100 w-100"
|
||||||
></canvas>
|
></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
||||||
import { setActivePinia } from "pinia";
|
import { setActivePinia } from "pinia";
|
||||||
import pinia from "../store/index";
|
import pinia from "../store/index";
|
||||||
setActivePinia(pinia);
|
setActivePinia(pinia);
|
||||||
|
|
||||||
import { useStateStore } from "../store/stateStore.js";
|
import { useStateStore } from "../store/stateStore.js";
|
||||||
const state = useStateStore(pinia);
|
const state = useStateStore(pinia);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -26,7 +24,7 @@ const state = useStateStore(pinia);
|
||||||
id="ptt_state"
|
id="ptt_state"
|
||||||
type="button"
|
type="button"
|
||||||
title="Rig PTT state"
|
title="Rig PTT state"
|
||||||
style="pointer-events: auto;"
|
style="pointer-events: auto"
|
||||||
disabled
|
disabled
|
||||||
>
|
>
|
||||||
<i class="bi bi-broadcast-pin" style="font-size: 0.8rem"></i>
|
<i class="bi bi-broadcast-pin" style="font-size: 0.8rem"></i>
|
||||||
|
@ -46,7 +44,7 @@ const state = useStateStore(pinia);
|
||||||
}"
|
}"
|
||||||
title="Modem state"
|
title="Modem state"
|
||||||
disabled
|
disabled
|
||||||
style="pointer-events: auto;"
|
style="pointer-events: auto"
|
||||||
>
|
>
|
||||||
<i class="bi bi-cpu" style="font-size: 0.8rem"></i>
|
<i class="bi bi-cpu" style="font-size: 0.8rem"></i>
|
||||||
</button>
|
</button>
|
||||||
|
@ -64,7 +62,7 @@ const state = useStateStore(pinia);
|
||||||
'bg-warning': state.arq_session_state === 'connected',
|
'bg-warning': state.arq_session_state === 'connected',
|
||||||
}"
|
}"
|
||||||
disabled
|
disabled
|
||||||
style="pointer-events: auto;"
|
style="pointer-events: auto"
|
||||||
title="Session state"
|
title="Session state"
|
||||||
>
|
>
|
||||||
<i class="bi bi-arrow-left-right" style="font-size: 0.8rem"></i>
|
<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',
|
'bg-warning': state.arq_state === 'True',
|
||||||
}"
|
}"
|
||||||
disabled
|
disabled
|
||||||
style="pointer-events: auto;"
|
style="pointer-events: auto"
|
||||||
>
|
>
|
||||||
<i class="bi bi-file-earmark-binary" style="font-size: 0.8rem"></i>
|
<i class="bi bi-file-earmark-binary" style="font-size: 0.8rem"></i>
|
||||||
</button>
|
</button>
|
||||||
|
@ -110,7 +108,7 @@ const state = useStateStore(pinia);
|
||||||
'btn-warning': state.channel_busy === 'True',
|
'btn-warning': state.channel_busy === 'True',
|
||||||
'btn-secondary': state.channel_busy === 'False',
|
'btn-secondary': state.channel_busy === 'False',
|
||||||
}"
|
}"
|
||||||
style="pointer-events: auto;"
|
style="pointer-events: auto"
|
||||||
title="Channel busy"
|
title="Channel busy"
|
||||||
>
|
>
|
||||||
<i class="bi bi-hourglass"></i>
|
<i class="bi bi-hourglass"></i>
|
||||||
|
@ -122,9 +120,9 @@ const state = useStateStore(pinia);
|
||||||
class="btn btn-sm btn-secondary me-4 disabled"
|
class="btn btn-sm btn-secondary me-4 disabled"
|
||||||
type="button"
|
type="button"
|
||||||
title="What's the frequency, Kenneth?"
|
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>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -219,7 +217,9 @@ const state = useStateStore(pinia);
|
||||||
aria-valuemin="0"
|
aria-valuemin="0"
|
||||||
aria-valuemax="100"
|
aria-valuemax="100"
|
||||||
></div>
|
></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
|
{{ state.arq_seconds_until_finish }}s left
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -248,4 +248,4 @@ const state = useStateStore(pinia);
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
ww
|
ww
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
||||||
import { setActivePinia } from "pinia";
|
import { setActivePinia } from "pinia";
|
||||||
import pinia from "../store/index";
|
import pinia from "../store/index";
|
||||||
setActivePinia(pinia);
|
setActivePinia(pinia);
|
||||||
|
@ -10,8 +9,10 @@ const state = useStateStore(pinia);
|
||||||
import { useChatStore } from "../store/chatStore.js";
|
import { useChatStore } from "../store/chatStore.js";
|
||||||
const chat = useChatStore(pinia);
|
const chat = useChatStore(pinia);
|
||||||
|
|
||||||
import { deleteChatByCallsign, getNewMessagesByDXCallsign } from "../js/chatHandler";
|
import {
|
||||||
|
deleteChatByCallsign,
|
||||||
|
getNewMessagesByDXCallsign,
|
||||||
|
} from "../js/chatHandler";
|
||||||
|
|
||||||
import { sendTestFrame, setTxAudioLevel } from "../js/sock.js";
|
import { sendTestFrame, setTxAudioLevel } from "../js/sock.js";
|
||||||
|
|
||||||
|
@ -36,8 +37,8 @@ import {
|
||||||
LineElement,
|
LineElement,
|
||||||
Title,
|
Title,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Legend
|
Legend,
|
||||||
} from 'chart.js'
|
} from "chart.js";
|
||||||
import { Line } from "vue-chartjs";
|
import { Line } from "vue-chartjs";
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed } from "vue";
|
||||||
|
|
||||||
|
@ -48,113 +49,172 @@ ChartJS.register(
|
||||||
LineElement,
|
LineElement,
|
||||||
Title,
|
Title,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Legend
|
Legend,
|
||||||
)
|
);
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<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-->
|
<button
|
||||||
<div class="modal fade" ref="modalEle" id="updaterReleaseNotes" tabindex="-1" aria-hidden="true">
|
type="button"
|
||||||
<div class="modal-dialog">
|
class="btn-close"
|
||||||
<div class="modal-content">
|
data-bs-dismiss="modal"
|
||||||
<div class="modal-header">
|
aria-label="Close"
|
||||||
<span class="input-group-text" id="updater_last_version"></span>
|
></button>
|
||||||
<span class="input-group-text ms-1" id="updater_last_update"></span>
|
</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 class="modal-footer">
|
||||||
</div>
|
<button
|
||||||
<div class="modal-body">
|
type="button"
|
||||||
<div class="modal-dialog modal-dialog-scrollable">
|
class="btn btn-secondary"
|
||||||
|
data-bs-dismiss="modal"
|
||||||
<div class="" id="updater_release_notes"></div>
|
>
|
||||||
|
Close
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<!-- delete chat modal -->
|
||||||
<!-- delete chat modal -->
|
<div
|
||||||
<div class="modal fade" ref="modalEle" id="deleteChatModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
class="modal fade"
|
||||||
<div class="modal-dialog">
|
ref="modalEle"
|
||||||
<div class="modal-content">
|
id="deleteChatModal"
|
||||||
<div class="modal-header">
|
tabindex="-1"
|
||||||
<h1 class="modal-title fs-5" id="deleteChatModalLabel">Sub menu for: {{chat.selectedCallsign}}</h1>
|
aria-labelledby="exampleModalLabel"
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
aria-hidden="true"
|
||||||
</div>
|
>
|
||||||
<div class="modal-body">
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h1 class="modal-title fs-5" id="deleteChatModalLabel">
|
||||||
<div class="input-group mb-3">
|
Sub menu for: {{ chat.selectedCallsign }}
|
||||||
<span class="input-group-text" id="basic-addon1">Total Messages</span>
|
</h1>
|
||||||
<span class="input-group-text" id="basic-addon1">{{getNewMessagesByDXCallsign(chat.selectedCallsign)[0]}}</span>
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn-close"
|
||||||
|
data-bs-dismiss="modal"
|
||||||
|
aria-label="Close"
|
||||||
|
></button>
|
||||||
</div>
|
</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">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>
|
|
||||||
<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>
|
||||||
</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 }}
|
||||||
|
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
|
||||||
<!-- 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">
|
|
||||||
<span class="input-group-text" id="basic-addon1">Status</span>
|
<span class="input-group-text" id="basic-addon1">Status</span>
|
||||||
<span class="input-group-text" id="basic-addon1">{{chat.selectedMessageObject["status"]}}</span>
|
<span class="input-group-text" id="basic-addon1">{{
|
||||||
</div>
|
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">Attempts</span>
|
||||||
<span class="input-group-text" id="basic-addon1">{{chat.selectedMessageObject["attempt"]}}</span>
|
<span class="input-group-text" id="basic-addon1">{{
|
||||||
</div>
|
chat.selectedMessageObject["attempt"]
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="input-group mb-3">
|
<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"
|
||||||
<span class="input-group-text" id="basic-addon1">{{chat.selectedMessageObject["bytesperminute"]}}</span>
|
>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>
|
|
||||||
<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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- HELP MODALS AUDIO -->
|
<!-- HELP MODALS AUDIO -->
|
||||||
<div
|
<div
|
||||||
|
@ -757,7 +817,11 @@ ChartJS.register(
|
||||||
<div class="card mb-3">
|
<div class="card mb-3">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">
|
<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
|
Tune
|
||||||
</button>
|
</button>
|
||||||
</h5>
|
</h5>
|
||||||
|
|
|
@ -17,7 +17,6 @@ const settings = useSettingsStore(pinia);
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<strong class="fs-5">Updater</strong>
|
<strong class="fs-5">Updater</strong>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-7">
|
<div class="col-7">
|
||||||
<div class="progress w-100 ms-1 m-1">
|
<div class="progress w-100 ms-1 m-1">
|
||||||
|
|
|
@ -15,8 +15,8 @@ import settings_exp from "./settings_exp.vue";
|
||||||
>
|
>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="badge text-bg-warning ms-3">
|
<div class="badge text-bg-warning ms-3">
|
||||||
<i class="bi bi-exclamation-triangle"></i> Please restart the modem after
|
<i class="bi bi-exclamation-triangle"></i> Please restart the modem
|
||||||
changing settings!
|
after changing settings!
|
||||||
</div>
|
</div>
|
||||||
<!-- SETTINGS Nav tabs -->
|
<!-- SETTINGS Nav tabs -->
|
||||||
<ul class="nav nav-tabs" id="myTab" role="tablist">
|
<ul class="nav nav-tabs" id="myTab" role="tablist">
|
||||||
|
|
|
@ -100,7 +100,6 @@ function saveSettings() {
|
||||||
v-model="settings.enable_auto_retry"
|
v-model="settings.enable_auto_retry"
|
||||||
true-value="True"
|
true-value="True"
|
||||||
false-value="False"
|
false-value="False"
|
||||||
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
@ -94,7 +94,12 @@ function saveSettings() {
|
||||||
<label class="input-group-text w-50" for="inputGroupFile02"
|
<label class="input-group-text w-50" for="inputGroupFile02"
|
||||||
>Received files folder</label
|
>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>
|
||||||
<div class="input-group input-group-sm mb-1">
|
<div class="input-group input-group-sm mb-1">
|
||||||
<span class="input-group-text w-50">Update channel</span>
|
<span class="input-group-text w-50">Update channel</span>
|
||||||
|
|
|
@ -43,36 +43,32 @@ function saveSettings() {
|
||||||
/>
|
/>
|
||||||
</div>
|
</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 ip</span>
|
||||||
<span class="input-group-text" style="width: 180px"
|
<input
|
||||||
>Rigctld remote ip</span
|
type="text"
|
||||||
>
|
class="form-control"
|
||||||
<input
|
placeholder="rigctld IP"
|
||||||
type="text"
|
id="hamlib_rigctld_ip"
|
||||||
class="form-control"
|
aria-label="Device IP"
|
||||||
placeholder="rigctld IP"
|
v-model="settings.hamlib_rigctld_ip"
|
||||||
id="hamlib_rigctld_ip"
|
/>
|
||||||
aria-label="Device IP"
|
|
||||||
v-model="settings.hamlib_rigctld_ip"
|
|
||||||
/>
|
|
||||||
</div>
|
</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"
|
<span class="input-group-text" style="width: 180px"
|
||||||
>Rigctld remote port</span
|
>Rigctld remote port</span
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
placeholder="rigctld port"
|
placeholder="rigctld port"
|
||||||
id="hamlib_rigctld_port"
|
id="hamlib_rigctld_port"
|
||||||
aria-label="Device Port"
|
aria-label="Device Port"
|
||||||
v-model="settings.hamlib_rigctld_port"
|
v-model="settings.hamlib_rigctld_port"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<hr class="m-2" />
|
<hr class="m-2" />
|
||||||
<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"> Radio model </span>
|
<span class="input-group-text" style="width: 180px"> Radio model </span>
|
||||||
|
|
|
@ -17,14 +17,11 @@ const state = useStateStore(pinia);
|
||||||
import { useSettingsStore } from "../store/settingsStore.js";
|
import { useSettingsStore } from "../store/settingsStore.js";
|
||||||
const settings = useSettingsStore(pinia);
|
const settings = useSettingsStore(pinia);
|
||||||
|
|
||||||
|
|
||||||
import { sendMessage, sendBroadcastChannel } from "./sock.js";
|
import { sendMessage, sendBroadcastChannel } from "./sock.js";
|
||||||
import { displayToast } from "./popupHandler.js";
|
import { displayToast } from "./popupHandler.js";
|
||||||
|
|
||||||
|
|
||||||
//const FD = require("./src/js/freedata.js");
|
//const FD = require("./src/js/freedata.js");
|
||||||
import {btoa_FD} from "./freedata.js"
|
import { btoa_FD } from "./freedata.js";
|
||||||
|
|
||||||
|
|
||||||
// split character
|
// split character
|
||||||
const split_char = "0;1;";
|
const split_char = "0;1;";
|
||||||
|
@ -61,8 +58,7 @@ interface messageDefaultObject {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface beaconDefaultObject {
|
||||||
interface beaconDefaultObject{
|
|
||||||
command: string;
|
command: string;
|
||||||
is_new: boolean;
|
is_new: boolean;
|
||||||
_id: string;
|
_id: string;
|
||||||
|
@ -94,37 +90,36 @@ PouchDB.plugin(require("pouchdb-find"));
|
||||||
PouchDB.plugin(require("pouchdb-upsert"));
|
PouchDB.plugin(require("pouchdb-upsert"));
|
||||||
|
|
||||||
// https://stackoverflow.com/a/26227660
|
// https://stackoverflow.com/a/26227660
|
||||||
if(typeof process.env["APPDATA"] !== "undefined"){
|
if (typeof process.env["APPDATA"] !== "undefined") {
|
||||||
var appDataFolder = process.env["APPDATA"]
|
var appDataFolder = process.env["APPDATA"];
|
||||||
console.log(appDataFolder)
|
console.log(appDataFolder);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
var appDataFolder: string;
|
var appDataFolder: string;
|
||||||
|
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
case "darwin":
|
case "darwin":
|
||||||
appDataFolder = process.env["HOME"] + "/Library/Application Support";
|
appDataFolder = process.env["HOME"] + "/Library/Application Support";
|
||||||
console.log(appDataFolder);
|
console.log(appDataFolder);
|
||||||
break;
|
break;
|
||||||
case "linux":
|
case "linux":
|
||||||
appDataFolder = process.env["HOME"] + "/.config";
|
appDataFolder = process.env["HOME"] + "/.config";
|
||||||
console.log(appDataFolder);
|
console.log(appDataFolder);
|
||||||
break;
|
break;
|
||||||
case "win32":
|
case "win32":
|
||||||
appDataFolder = "undefined";
|
appDataFolder = "undefined";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
appDataFolder = "undefined";
|
appDataFolder = "undefined";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log("loading chat database...")
|
console.log("loading chat database...");
|
||||||
console.log("appdata folder:" + appDataFolder)
|
console.log("appdata folder:" + appDataFolder);
|
||||||
var configFolder = path.join(appDataFolder, "FreeDATA");
|
var configFolder = path.join(appDataFolder, "FreeDATA");
|
||||||
console.log("config folder:" + configFolder)
|
console.log("config folder:" + configFolder);
|
||||||
|
|
||||||
var chatDB = path.join(configFolder, "chatDB");
|
var chatDB = path.join(configFolder, "chatDB");
|
||||||
console.log("database path:" + chatDB)
|
console.log("database path:" + chatDB);
|
||||||
|
|
||||||
var db = new PouchDB(chatDB);
|
var db = new PouchDB(chatDB);
|
||||||
|
|
||||||
|
@ -135,8 +130,7 @@ var db = new PouchDB(chatDB);
|
||||||
/* -------- RUN A DATABASE CLEANUP ON STARTUP */
|
/* -------- RUN A DATABASE CLEANUP ON STARTUP */
|
||||||
//dbClean()
|
//dbClean()
|
||||||
|
|
||||||
updateAllChat(true)
|
updateAllChat(true);
|
||||||
|
|
||||||
|
|
||||||
// create callsign set for storing unique callsigns
|
// create callsign set for storing unique callsigns
|
||||||
chat.callsign_list = new Set();
|
chat.callsign_list = new Set();
|
||||||
|
@ -147,9 +141,9 @@ export function newBroadcast(broadcastChannel, chatmessage) {
|
||||||
var frames = "";
|
var frames = "";
|
||||||
var data = "";
|
var data = "";
|
||||||
|
|
||||||
var file = "";
|
var file = "";
|
||||||
var filetype = "text";
|
var filetype = "text";
|
||||||
var filename = "";
|
var filename = "";
|
||||||
|
|
||||||
var file_checksum = ""; //crc32(file).toString(16).toUpperCase();
|
var file_checksum = ""; //crc32(file).toString(16).toUpperCase();
|
||||||
var checksum = "";
|
var checksum = "";
|
||||||
|
@ -167,37 +161,35 @@ export function newBroadcast(broadcastChannel, chatmessage) {
|
||||||
// slice uuid for reducing overhead
|
// slice uuid for reducing overhead
|
||||||
uuid = uuid.slice(-4);
|
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 = {
|
//sendMessage(newChatObj)
|
||||||
command: "broadcast",
|
sendBroadcastChannel(newChatObj);
|
||||||
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)
|
|
||||||
|
|
||||||
addObjToDatabase(newChatObj);
|
addObjToDatabase(newChatObj);
|
||||||
}
|
}
|
||||||
|
@ -216,7 +208,7 @@ export function newMessage(
|
||||||
var data = "";
|
var data = "";
|
||||||
var filename = "";
|
var filename = "";
|
||||||
var filetype = "";
|
var filetype = "";
|
||||||
var file=""
|
var file = "";
|
||||||
if (typeof chatFile !== "undefined") {
|
if (typeof chatFile !== "undefined") {
|
||||||
file = chatFile;
|
file = chatFile;
|
||||||
filetype = chatFileType;
|
filetype = chatFileType;
|
||||||
|
@ -242,33 +234,32 @@ export function newMessage(
|
||||||
// slice uuid for reducing overhead
|
// slice uuid for reducing overhead
|
||||||
uuid = uuid.slice(-8);
|
uuid = uuid.slice(-8);
|
||||||
|
|
||||||
|
let newChatObj: messageDefaultObject = {
|
||||||
let newChatObj: messageDefaultObject = {
|
command: "msg",
|
||||||
command: "msg",
|
hmac_signed: false,
|
||||||
hmac_signed: false,
|
percent: 0,
|
||||||
percent: 0,
|
bytesperminute: 0, // You need to assign a value here
|
||||||
bytesperminute: 0, // You need to assign a value here
|
is_new: false,
|
||||||
is_new: false,
|
_id: uuid,
|
||||||
_id: uuid,
|
timestamp: timestamp,
|
||||||
timestamp: timestamp,
|
dxcallsign: dxcallsign,
|
||||||
dxcallsign: dxcallsign,
|
dxgrid: "null",
|
||||||
dxgrid: "null",
|
msg: chatmessage,
|
||||||
msg: chatmessage,
|
checksum: file_checksum,
|
||||||
checksum: file_checksum,
|
type: message_type,
|
||||||
type: message_type,
|
status: "transmitting",
|
||||||
status: "transmitting",
|
attempt: 1,
|
||||||
attempt: 1,
|
uuid: uuid,
|
||||||
uuid: uuid,
|
duration: 0,
|
||||||
duration: 0,
|
nacks: 0,
|
||||||
nacks: 0,
|
speed_list: "null",
|
||||||
speed_list: "null",
|
_attachments: {
|
||||||
_attachments: {
|
[filename]: {
|
||||||
[filename]: {
|
content_type: filetype,
|
||||||
content_type: filetype,
|
data: btoa_FD(file),
|
||||||
data: btoa_FD(file)
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
sendMessage(newChatObj);
|
sendMessage(newChatObj);
|
||||||
addObjToDatabase(newChatObj);
|
addObjToDatabase(newChatObj);
|
||||||
|
@ -288,7 +279,9 @@ function sortChatList() {
|
||||||
}
|
}
|
||||||
reorderedData[dxcallsign].push(obj);
|
reorderedData[dxcallsign].push(obj);
|
||||||
|
|
||||||
reorderedData[dxcallsign] = reorderedData[dxcallsign].sort(sortByProperty("timestamp"));
|
reorderedData[dxcallsign] = reorderedData[dxcallsign].sort(
|
||||||
|
sortByProperty("timestamp"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
//console.log(reorderedData["2LS-0"])
|
//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
|
//https://medium.com/@asadise/sorting-a-json-array-according-one-property-in-javascript-18b1d22cd9e9
|
||||||
function sortByProperty(property){
|
function sortByProperty(property) {
|
||||||
return function(a,b){
|
return function (a, b) {
|
||||||
if(a[property] > b[property])
|
if (a[property] > b[property]) return 1;
|
||||||
return 1;
|
else if (a[property] < b[property]) return -1;
|
||||||
else if(a[property] < b[property])
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function getMessageAttachment(id) {
|
export function getMessageAttachment(id) {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
|
@ -333,28 +323,29 @@ export function getMessageAttachment(id) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//repeat a message
|
//repeat a message
|
||||||
export function repeatMessageTransmission(id) {
|
export function repeatMessageTransmission(id) {
|
||||||
// 1. get message object by ID
|
// 1. get message object by ID
|
||||||
// 2. Upsert Attempts
|
// 2. Upsert Attempts
|
||||||
// 3. send message
|
// 3. send message
|
||||||
|
|
||||||
db.find({
|
db.find({
|
||||||
selector: {
|
selector: {
|
||||||
_id: id,
|
_id: id,
|
||||||
},
|
},
|
||||||
}).then(function (result){
|
})
|
||||||
console.log(result)
|
.then(function (result) {
|
||||||
let obj = result.docs[0]
|
console.log(result);
|
||||||
console.log(obj)
|
let obj = result.docs[0];
|
||||||
obj.attempt += 1
|
console.log(obj);
|
||||||
databaseUpsert(obj.uuid, "attempt", obj.attempt);
|
obj.attempt += 1;
|
||||||
updateUnsortedChatListEntry(obj.uuid, "attempt", obj.attempt);
|
databaseUpsert(obj.uuid, "attempt", obj.attempt);
|
||||||
sendMessage(obj)
|
updateUnsortedChatListEntry(obj.uuid, "attempt", obj.attempt);
|
||||||
}).catch(function (err) {
|
sendMessage(obj);
|
||||||
console.log(err);
|
})
|
||||||
});
|
.catch(function (err) {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete a message from databse and gui
|
// delete a message from databse and gui
|
||||||
|
@ -374,7 +365,6 @@ export function deleteMessageFromDB(id) {
|
||||||
chat.sorted_chat_list = sortChatList();
|
chat.sorted_chat_list = sortChatList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Function to clean old beacons and optimize database
|
//Function to clean old beacons and optimize database
|
||||||
async function dbClean() {
|
async function dbClean() {
|
||||||
//Only keep the most x latest days of beacons
|
//Only keep the most x latest days of beacons
|
||||||
|
@ -384,7 +374,6 @@ async function dbClean() {
|
||||||
(Date.now() - beaconKeep * 24 * 60 * 60 * 1000) / 1000,
|
(Date.now() - beaconKeep * 24 * 60 * 60 * 1000) / 1000,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
//Items to purge from database
|
//Items to purge from database
|
||||||
var purgeFilter = [
|
var purgeFilter = [
|
||||||
{ type: "beacon" },
|
{ type: "beacon" },
|
||||||
|
@ -404,7 +393,7 @@ async function dbClean() {
|
||||||
//console.log("Purging " + result.docs.length + " beacons received before " + timestampPurge);
|
//console.log("Purging " + result.docs.length + " beacons received before " + timestampPurge);
|
||||||
itemCount = result.docs.length;
|
itemCount = result.docs.length;
|
||||||
result.docs.forEach(async function (item) {
|
result.docs.forEach(async function (item) {
|
||||||
await deleteMessageFromDB(item._id)
|
await deleteMessageFromDB(item._id);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
|
@ -415,20 +404,13 @@ async function dbClean() {
|
||||||
//Too slow on older/slower machines
|
//Too slow on older/slower machines
|
||||||
//await db.compact();
|
//await db.compact();
|
||||||
|
|
||||||
|
let message = "Database maintenance is complete";
|
||||||
|
displayToast("info", "bi bi-info-circle", message, 5000);
|
||||||
|
|
||||||
|
message = "Removed " + itemCount + " items from database";
|
||||||
let message = "Database maintenance is complete"
|
displayToast("info", "bi bi-info-circle", message, 5000);
|
||||||
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
|
// function to update transmission status
|
||||||
export function updateTransmissionStatus(obj) {
|
export function updateTransmissionStatus(obj) {
|
||||||
// update database entries
|
// update database entries
|
||||||
|
@ -436,23 +418,19 @@ export function updateTransmissionStatus(obj) {
|
||||||
databaseUpsert(obj.uuid, "bytesperminute", obj.bytesperminute);
|
databaseUpsert(obj.uuid, "bytesperminute", obj.bytesperminute);
|
||||||
databaseUpsert(obj.uuid, "status", obj.status);
|
databaseUpsert(obj.uuid, "status", obj.status);
|
||||||
|
|
||||||
|
|
||||||
// update screen rendering / messages
|
// update screen rendering / messages
|
||||||
updateUnsortedChatListEntry(obj.uuid, "percent", obj.percent);
|
updateUnsortedChatListEntry(obj.uuid, "percent", obj.percent);
|
||||||
updateUnsortedChatListEntry(obj.uuid, "bytesperminute", obj.bytesperminute);
|
updateUnsortedChatListEntry(obj.uuid, "bytesperminute", obj.bytesperminute);
|
||||||
updateUnsortedChatListEntry(obj.uuid, "status", obj.status);
|
updateUnsortedChatListEntry(obj.uuid, "status", obj.status);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateUnsortedChatListEntry(uuid, object, value) {
|
export function updateUnsortedChatListEntry(uuid, object, value) {
|
||||||
|
var data = getFromUnsortedChatListByUUID(uuid);
|
||||||
var data = getFromUnsortedChatListByUUID(uuid)
|
if (data) {
|
||||||
if(data){
|
|
||||||
data[object] = value;
|
data[object] = value;
|
||||||
console.log("Entry updated:", data[object]);
|
console.log("Entry updated:", data[object]);
|
||||||
chat.sorted_chat_list = sortChatList();
|
chat.sorted_chat_list = sortChatList();
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -470,43 +448,39 @@ export function updateUnsortedChatListEntry(uuid, object, value) {
|
||||||
return null; // Return null if not found
|
return null; // Return null if not found
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFromUnsortedChatListByUUID(uuid){
|
function getFromUnsortedChatListByUUID(uuid) {
|
||||||
for (const entry of chat.unsorted_chat_list) {
|
for (const entry of chat.unsorted_chat_list) {
|
||||||
if (entry.uuid === uuid) {
|
if (entry.uuid === uuid) {
|
||||||
return entry;
|
return entry;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNewMessagesByDXCallsign(dxcallsign): [number, number, any]{
|
export function getNewMessagesByDXCallsign(dxcallsign): [number, number, any] {
|
||||||
let new_counter = 0
|
let new_counter = 0;
|
||||||
let total_counter = 0
|
let total_counter = 0;
|
||||||
let item_array = []
|
let item_array = [];
|
||||||
if (typeof dxcallsign !== 'undefined'){
|
if (typeof dxcallsign !== "undefined") {
|
||||||
for (const key in chat.sorted_chat_list[dxcallsign]){
|
for (const key in chat.sorted_chat_list[dxcallsign]) {
|
||||||
//console.log(chat.sorted_chat_list[dxcallsign][key])
|
//console.log(chat.sorted_chat_list[dxcallsign][key])
|
||||||
//item_array.push(chat.sorted_chat_list[dxcallsign][key])
|
//item_array.push(chat.sorted_chat_list[dxcallsign][key])
|
||||||
if(chat.sorted_chat_list[dxcallsign][key].is_new){
|
if (chat.sorted_chat_list[dxcallsign][key].is_new) {
|
||||||
item_array.push(chat.sorted_chat_list[dxcallsign][key])
|
item_array.push(chat.sorted_chat_list[dxcallsign][key]);
|
||||||
new_counter += 1
|
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) {
|
export function databaseUpsert(id, object, value) {
|
||||||
db.upsert(id, function (doc) {
|
db.upsert(id, function (doc) {
|
||||||
if (!doc[object]) {
|
if (!doc[object]) {
|
||||||
|
@ -527,70 +501,61 @@ export function databaseUpsert(id, object, value) {
|
||||||
|
|
||||||
// function for fetching all messages from chat / updating chat
|
// function for fetching all messages from chat / updating chat
|
||||||
export async function updateAllChat(cleanup) {
|
export async function updateAllChat(cleanup) {
|
||||||
|
// run cleanup if requested
|
||||||
// run cleanup if requested
|
if (cleanup) {
|
||||||
if (cleanup) {
|
await dbClean();
|
||||||
await dbClean()
|
}
|
||||||
}
|
let indexFields = [{ dxcallsign: "asc" }, { timestamp: "asc" }];
|
||||||
let indexFields = [
|
|
||||||
{dxcallsign: "asc"},
|
|
||||||
{timestamp: "asc"}
|
|
||||||
]
|
|
||||||
let filter = {
|
let filter = {
|
||||||
selector: {
|
selector: {
|
||||||
$and: [
|
$and: [
|
||||||
{ dxcallsign: { $exists: true } },
|
{ dxcallsign: { $exists: true } },
|
||||||
{ timestamp: { $exists: true } },
|
{ timestamp: { $exists: true } },
|
||||||
//{ $or: chat.chat_filter },
|
//{ $or: chat.chat_filter },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
sort: [{ dxcallsign: "asc" }, { timestamp: "asc" }],
|
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") {
|
if (item.type === "beacon") {
|
||||||
//console.log(item);
|
//console.log(item);
|
||||||
|
|
||||||
// TODO: sort beacon list .... maybe a part for a separate function
|
// TODO: sort beacon list .... maybe a part for a separate function
|
||||||
const jsonData = [item];
|
const jsonData = [item];
|
||||||
|
|
||||||
// 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
|
// Process each JSON item step by step
|
||||||
chat.sorted_beacon_list[dxcallsign].snr.push(snr);
|
jsonData.forEach((jsonitem) => {
|
||||||
chat.sorted_beacon_list[dxcallsign].timestamp.push(timestamp);
|
const { snr, timestamp } = item;
|
||||||
});
|
|
||||||
} else {
|
|
||||||
|
|
||||||
chat.unsorted_chat_list.push(item);
|
|
||||||
chat.sorted_chat_list = sortChatList();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
.catch(function (err) {
|
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// 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) {
|
function addObjToDatabase(newobj) {
|
||||||
|
@ -610,12 +575,10 @@ function addObjToDatabase(newobj) {
|
||||||
console.log("new database entry");
|
console.log("new database entry");
|
||||||
console.log(response);
|
console.log(response);
|
||||||
|
|
||||||
|
|
||||||
if (newobj.command === "msg") {
|
if (newobj.command === "msg") {
|
||||||
chat.unsorted_chat_list.push(newobj);
|
chat.unsorted_chat_list.push(newobj);
|
||||||
chat.sorted_chat_list = sortChatList();
|
chat.sorted_chat_list = sortChatList();
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
@ -624,11 +587,8 @@ function addObjToDatabase(newobj) {
|
||||||
// try upserting status in case we tried sending a message to our selfes
|
// try upserting status in case we tried sending a message to our selfes
|
||||||
databaseUpsert(newobj.uuid, "status", newobj.status);
|
databaseUpsert(newobj.uuid, "status", newobj.status);
|
||||||
updateUnsortedChatListEntry(newobj.uuid, "status", newobj.status);
|
updateUnsortedChatListEntry(newobj.uuid, "status", newobj.status);
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// upsert footer ...
|
// upsert footer ...
|
||||||
|
|
||||||
|
@ -659,7 +619,7 @@ function createChatIndex() {
|
||||||
"is_new",
|
"is_new",
|
||||||
"nacks",
|
"nacks",
|
||||||
"duration",
|
"duration",
|
||||||
"speed_list"
|
"speed_list",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -681,8 +641,6 @@ export function deleteChatByCallsign(callsign) {
|
||||||
deleteFromDatabaseByCallsign(callsign);
|
deleteFromDatabaseByCallsign(callsign);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function deleteFromDatabaseByCallsign(callsign) {
|
function deleteFromDatabaseByCallsign(callsign) {
|
||||||
db.find({
|
db.find({
|
||||||
selector: {
|
selector: {
|
||||||
|
@ -730,18 +688,18 @@ export function newBeaconReceived(obj) {
|
||||||
"mycallsign": "DJ2LS-0"
|
"mycallsign": "DJ2LS-0"
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
let newChatObj: beaconDefaultObject = {
|
let newChatObj: beaconDefaultObject = {
|
||||||
command: "beacon",
|
command: "beacon",
|
||||||
is_new: false,
|
is_new: false,
|
||||||
_id: obj["uuid"],
|
_id: obj["uuid"],
|
||||||
timestamp: obj["timestamp"],
|
timestamp: obj["timestamp"],
|
||||||
dxcallsign: obj["dxcallsign"],
|
dxcallsign: obj["dxcallsign"],
|
||||||
dxgrid: obj["dxgrid"],
|
dxgrid: obj["dxgrid"],
|
||||||
type: "beacon",
|
type: "beacon",
|
||||||
status: obj["beacon"],
|
status: obj["beacon"],
|
||||||
uuid: obj["uuid"],
|
uuid: obj["uuid"],
|
||||||
snr: obj["snr"], // adding the new field
|
snr: obj["snr"], // adding the new field
|
||||||
};
|
};
|
||||||
|
|
||||||
addObjToDatabase(newChatObj);
|
addObjToDatabase(newChatObj);
|
||||||
|
|
||||||
|
@ -769,13 +727,11 @@ let newChatObj: beaconDefaultObject = {
|
||||||
});
|
});
|
||||||
|
|
||||||
// check if auto retry enabled
|
// check if auto retry enabled
|
||||||
console.log("-----------------------------------------")
|
console.log("-----------------------------------------");
|
||||||
console.log(settings.enable_auto_retry.toUpperCase())
|
console.log(settings.enable_auto_retry.toUpperCase());
|
||||||
if (settings.enable_auto_retry.toUpperCase() == "TRUE") {
|
if (settings.enable_auto_retry.toUpperCase() == "TRUE") {
|
||||||
checkForWaitingMessages(dxcallsign);
|
checkForWaitingMessages(dxcallsign);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// function for handling a received message
|
// function for handling a received message
|
||||||
|
@ -857,33 +813,32 @@ export function newMessageReceived(message, protocol) {
|
||||||
*/
|
*/
|
||||||
console.log(protocol);
|
console.log(protocol);
|
||||||
|
|
||||||
let newChatObj: messageDefaultObject = {
|
let newChatObj: messageDefaultObject = {
|
||||||
command: "msg",
|
command: "msg",
|
||||||
hmac_signed: protocol["hmac_signed"],
|
hmac_signed: protocol["hmac_signed"],
|
||||||
percent: 100,
|
percent: 100,
|
||||||
bytesperminute: protocol["bytesperminute"],
|
bytesperminute: protocol["bytesperminute"],
|
||||||
is_new: true,
|
is_new: true,
|
||||||
_id: message[3],
|
_id: message[3],
|
||||||
timestamp: message[4],
|
timestamp: message[4],
|
||||||
dxcallsign: protocol["dxcallsign"],
|
dxcallsign: protocol["dxcallsign"],
|
||||||
dxgrid: protocol["dxgrid"],
|
dxgrid: protocol["dxgrid"],
|
||||||
msg: message[5],
|
msg: message[5],
|
||||||
checksum: message[2],
|
checksum: message[2],
|
||||||
type: protocol["status"],
|
type: protocol["status"],
|
||||||
status: protocol["status"],
|
status: protocol["status"],
|
||||||
attempt: 1,
|
attempt: 1,
|
||||||
uuid: message[3],
|
uuid: message[3],
|
||||||
duration: protocol["duration"],
|
duration: protocol["duration"],
|
||||||
nacks: protocol["nacks"],
|
nacks: protocol["nacks"],
|
||||||
speed_list: protocol["speed_list"],
|
speed_list: protocol["speed_list"],
|
||||||
_attachments: {
|
_attachments: {
|
||||||
[message[6]]: {
|
[message[6]]: {
|
||||||
content_type: message[7],
|
content_type: message[7],
|
||||||
data: btoa_FD(message[8])
|
data: btoa_FD(message[8]),
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// some tweaks for broadcasts
|
// some tweaks for broadcasts
|
||||||
if (protocol.fec == "broadcast") {
|
if (protocol.fec == "broadcast") {
|
||||||
|
@ -906,31 +861,26 @@ export function setStateSuccess() {
|
||||||
state.arq_seconds_until_timeout_percent = 100;
|
state.arq_seconds_until_timeout_percent = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requestMessageInfo(id){
|
export function requestMessageInfo(id) {
|
||||||
|
console.log(id);
|
||||||
console.log(id)
|
// id and uuid are the same
|
||||||
// id and uuid are the same
|
var data = getFromUnsortedChatListByUUID(id);
|
||||||
var data = getFromUnsortedChatListByUUID(id)
|
console.log(data);
|
||||||
console.log(data)
|
chat.selectedMessageObject = data;
|
||||||
chat.selectedMessageObject = data
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createIndex(myIndexFields)
|
async function createIndex(myIndexFields) {
|
||||||
{
|
db.createIndex({
|
||||||
db.createIndex({
|
index: {
|
||||||
index: {
|
fields: myIndexFields,
|
||||||
fields: myIndexFields,
|
},
|
||||||
},
|
}).catch((err) => {
|
||||||
})
|
console.log(err);
|
||||||
.catch(err => {
|
});
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getFromDBByFilter(filter) {
|
async function getFromDBByFilter(filter) {
|
||||||
/*
|
/*
|
||||||
USAGE:
|
USAGE:
|
||||||
|
|
||||||
let filter = {
|
let filter = {
|
||||||
|
@ -951,54 +901,53 @@ getFromDBByFilter(filter)
|
||||||
});
|
});
|
||||||
|
|
||||||
*/
|
*/
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
return db.find(filter)
|
return db
|
||||||
.then(result => {
|
.find(filter)
|
||||||
console.log(result);
|
.then((result) => {
|
||||||
resolve(result);
|
console.log(result);
|
||||||
})
|
resolve(result);
|
||||||
.catch(err => {
|
})
|
||||||
console.log(err);
|
.catch((err) => {
|
||||||
reject(err);
|
console.log(err);
|
||||||
})})
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function checkForWaitingMessages(dxcall) {
|
async function checkForWaitingMessages(dxcall) {
|
||||||
|
let filter = {
|
||||||
let filter = {
|
|
||||||
selector: {
|
selector: {
|
||||||
dxcallsign: dxcall,
|
dxcallsign: dxcall,
|
||||||
type: "transmit",
|
type: "transmit",
|
||||||
status: "failed",
|
status: "failed",
|
||||||
//attempt: { $lt: parseInt(config.max_retry_attempts) }
|
//attempt: { $lt: parseInt(config.max_retry_attempts) }
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
getFromDBByFilter(filter)
|
getFromDBByFilter(filter)
|
||||||
.then(result => {
|
.then((result) => {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
let message = "Found " + result.docs.length + " waiting messages for " + dxcall
|
let message =
|
||||||
|
"Found " + result.docs.length + " waiting messages for " + dxcall;
|
||||||
|
|
||||||
console.log(message);
|
console.log(message);
|
||||||
displayToast("info", "bi bi-info-circle", message, 5000);
|
displayToast("info", "bi bi-info-circle", message, 5000);
|
||||||
|
|
||||||
// handle result
|
// handle result
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
if (result.docs.length > 0) {
|
if (result.docs.length > 0) {
|
||||||
// only want to process the first available item object, then return
|
// only want to process the first available item object, then return
|
||||||
// this ensures, we are only sending one message at once
|
// 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) {
|
if (result.docs[0].attempt < settings.max_retry_attempts) {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
repeatMessageTransmission(result.docs[0].uuid)
|
repeatMessageTransmission(result.docs[0].uuid);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
})
|
||||||
})
|
.catch((err) => {
|
||||||
.catch(err => {
|
console.log(err);
|
||||||
console.log(err)
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -116,14 +116,13 @@ daemon.on("data", function (socketdata) {
|
||||||
stackoverflow.com questions 9070700 nodejs-net-createserver-large-amount-of-data-coming-in
|
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 = socketchunk.join("\n") + socketdata.toString("utf8"); //append incoming data to socketchunk
|
||||||
//socketdata = socketdata.toString("utf8"); // convert data to string
|
//socketdata = socketdata.toString("utf8"); // convert data to string
|
||||||
|
|
||||||
//socketchunk += socketdata; // append data to buffer so we can stick long data together
|
//socketchunk += socketdata; // append data to buffer so we can stick long data together
|
||||||
|
|
||||||
// check if we received begin and end of json data
|
// check if we received begin and end of json data
|
||||||
if (socketdata.startsWith('{"') && socketdata.endsWith('"}\n')) {
|
if (socketdata.startsWith('{"') && socketdata.endsWith('"}\n')) {
|
||||||
|
|
||||||
var data = "";
|
var data = "";
|
||||||
|
|
||||||
// split data into chunks if we received multiple commands
|
// 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") {
|
if (data["command"] == "daemon_state") {
|
||||||
|
|
||||||
// update audio devices by putting them to audio store
|
// update audio devices by putting them to audio store
|
||||||
audioStore.inputDevices = data["input_devices"];
|
audioStore.inputDevices = data["input_devices"];
|
||||||
audioStore.outputDevices = data["output_devices"];
|
audioStore.outputDevices = data["output_devices"];
|
||||||
settings.serial_devices = data["serial_devices"];
|
settings.serial_devices = data["serial_devices"];
|
||||||
state.python_version = data["python_version"]
|
state.python_version = data["python_version"];
|
||||||
state.modem_version = data["version"]
|
state.modem_version = data["version"];
|
||||||
state.modem_running_state = data["daemon_state"][0]["status"];
|
state.modem_running_state = data["daemon_state"][0]["status"];
|
||||||
state.rigctld_started = data["rigctld_state"][0]["status"];
|
state.rigctld_started = data["rigctld_state"][0]["status"];
|
||||||
//state.rigctld_process = data["daemon_state"][0]["rigctld_process"];
|
//state.rigctld_process = data["daemon_state"][0]["rigctld_process"];
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (data["command"] == "test_hamlib") {
|
if (data["command"] == "test_hamlib") {
|
||||||
let Data = {
|
let Data = {
|
||||||
hamlib_result: data["result"],
|
hamlib_result: data["result"],
|
||||||
|
@ -246,7 +239,8 @@ export function startModem() {
|
||||||
// STOP Modem
|
// STOP Modem
|
||||||
//exports.stopModem = function () {
|
//exports.stopModem = function () {
|
||||||
export function stopModem() {
|
export function stopModem() {
|
||||||
var command = '{"type" : "set", "command": "stop_modem" , "parameter": "---" }';
|
var command =
|
||||||
|
'{"type" : "set", "command": "stop_modem" , "parameter": "---" }';
|
||||||
writeDaemonCommand(command);
|
writeDaemonCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,44 +283,38 @@ function testHamlib(
|
||||||
}
|
}
|
||||||
|
|
||||||
export function startRigctld() {
|
export function startRigctld() {
|
||||||
|
|
||||||
var json_command = JSON.stringify({
|
var json_command = JSON.stringify({
|
||||||
type: "set",
|
type: "set",
|
||||||
command: "start_rigctld",
|
command: "start_rigctld",
|
||||||
parameter: [
|
parameter: [
|
||||||
{
|
{
|
||||||
hamlib_deviceid: settings.hamlib_deviceid,
|
hamlib_deviceid: settings.hamlib_deviceid,
|
||||||
hamlib_deviceport: settings.hamlib_deviceport,
|
hamlib_deviceport: settings.hamlib_deviceport,
|
||||||
hamlib_stop_bits: settings.hamlib_stop_bits,
|
hamlib_stop_bits: settings.hamlib_stop_bits,
|
||||||
hamlib_data_bits: settings.hamlib_data_bits,
|
hamlib_data_bits: settings.hamlib_data_bits,
|
||||||
hamlib_handshake: settings.hamlib_handshake,
|
hamlib_handshake: settings.hamlib_handshake,
|
||||||
hamlib_serialspeed: settings.hamlib_serialspeed,
|
hamlib_serialspeed: settings.hamlib_serialspeed,
|
||||||
hamlib_dtrstate: settings.hamlib_dtrstate,
|
hamlib_dtrstate: settings.hamlib_dtrstate,
|
||||||
hamlib_pttprotocol: settings.hamlib_pttprotocol,
|
hamlib_pttprotocol: settings.hamlib_pttprotocol,
|
||||||
hamlib_ptt_port: settings.hamlib_ptt_port,
|
hamlib_ptt_port: settings.hamlib_ptt_port,
|
||||||
hamlib_dcd: settings.hamlib_dcd,
|
hamlib_dcd: settings.hamlib_dcd,
|
||||||
hamlbib_serialspeed_ptt: settings.hamlib_serialspeed,
|
hamlbib_serialspeed_ptt: settings.hamlib_serialspeed,
|
||||||
hamlib_rigctld_port: settings.hamlib_rigctld_port,
|
hamlib_rigctld_port: settings.hamlib_rigctld_port,
|
||||||
hamlib_rigctld_ip: settings.hamlib_rigctld_ip,
|
hamlib_rigctld_ip: settings.hamlib_rigctld_ip,
|
||||||
hamlib_rigctld_path: settings.hamlib_rigctld_path,
|
hamlib_rigctld_path: settings.hamlib_rigctld_path,
|
||||||
hamlib_rigctld_server_port: settings.hamlib_rigctld_server_port,
|
hamlib_rigctld_server_port: settings.hamlib_rigctld_server_port,
|
||||||
hamlib_rigctld_custom_args: settings.hamlib_rigctld_custom_args
|
hamlib_rigctld_custom_args: settings.hamlib_rigctld_custom_args,
|
||||||
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
console.log(json_command);
|
console.log(json_command);
|
||||||
writeDaemonCommand(json_command);
|
writeDaemonCommand(json_command);
|
||||||
|
|
||||||
}
|
}
|
||||||
export function stopRigctld(){
|
export function stopRigctld() {
|
||||||
let command = '{"type" : "set", "command": "stop_rigctld"}';
|
let command = '{"type" : "set", "command": "stop_rigctld"}';
|
||||||
writeDaemonCommand(command);
|
writeDaemonCommand(command);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Save myCall
|
//Save myCall
|
||||||
function saveMyCall(callsign) {
|
function saveMyCall(callsign) {
|
||||||
//exports.saveMyCall = function (callsign) {
|
//exports.saveMyCall = function (callsign) {
|
||||||
|
@ -344,5 +332,3 @@ function saveMyGrid(grid) {
|
||||||
'{"type" : "set", "command": "mygrid" , "parameter": "' + grid + '"}';
|
'{"type" : "set", "command": "mygrid" , "parameter": "' + grid + '"}';
|
||||||
writeDaemonCommand(command);
|
writeDaemonCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,24 +6,24 @@ const fs = require("fs");
|
||||||
* @returns base64 encoded string
|
* @returns base64 encoded string
|
||||||
*/
|
*/
|
||||||
export function btoa_FD(data) {
|
export function btoa_FD(data) {
|
||||||
//exports.btoa_FD = function (data) {
|
//exports.btoa_FD = function (data) {
|
||||||
return Buffer.from(data, "utf-8").toString("base64");
|
return Buffer.from(data, "utf-8").toString("base64");
|
||||||
};
|
}
|
||||||
/**
|
/**
|
||||||
* ASCII to Binary replacement
|
* ASCII to Binary replacement
|
||||||
* @param {string} data in base64 encoding
|
* @param {string} data in base64 encoding
|
||||||
* @returns utf-8 normal/usual string
|
* @returns utf-8 normal/usual string
|
||||||
*/
|
*/
|
||||||
export function atob_FD(data) {
|
export function atob_FD(data) {
|
||||||
//exports.atob_FD = function (data) {
|
//exports.atob_FD = function (data) {
|
||||||
return Buffer.from(data, "base64").toString("utf-8");
|
return Buffer.from(data, "base64").toString("utf-8");
|
||||||
};
|
}
|
||||||
/**
|
/**
|
||||||
* UTF8 to ASCII btoa
|
* UTF8 to ASCII btoa
|
||||||
* @param {string} data in base64 encoding
|
* @param {string} data in base64 encoding
|
||||||
* @returns base64 bota compatible data for use in browser
|
* @returns base64 bota compatible data for use in browser
|
||||||
*/
|
*/
|
||||||
export function atob(data) {
|
export function atob(data) {
|
||||||
//exports.atob = function (data) {
|
//exports.atob = function (data) {
|
||||||
return window.btoa(Buffer.from(data, "base64").toString("utf8"));
|
return window.btoa(Buffer.from(data, "base64").toString("utf8"));
|
||||||
};
|
}
|
||||||
|
|
|
@ -15,43 +15,40 @@ import { useSettingsStore } from "../store/settingsStore.js";
|
||||||
const settings = useSettingsStore(pinia);
|
const settings = useSettingsStore(pinia);
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
|
|
||||||
console.log(process.env)
|
console.log(process.env);
|
||||||
if(typeof process.env["APPDATA"] !== "undefined"){
|
if (typeof process.env["APPDATA"] !== "undefined") {
|
||||||
var appDataFolder = process.env["APPDATA"]
|
var appDataFolder = process.env["APPDATA"];
|
||||||
console.log(appDataFolder)
|
console.log(appDataFolder);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
case "darwin":
|
case "darwin":
|
||||||
var appDataFolder = process.env["HOME"] + "/Library/Application Support";
|
var appDataFolder = process.env["HOME"] + "/Library/Application Support";
|
||||||
console.log(appDataFolder)
|
console.log(appDataFolder);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "linux":
|
case "linux":
|
||||||
var appDataFolder = process.env["HOME"] + "/.config";
|
var appDataFolder = process.env["HOME"] + "/.config";
|
||||||
console.log(appDataFolder)
|
console.log(appDataFolder);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "linux":
|
case "linux":
|
||||||
var appDataFolder = "undefined";
|
var appDataFolder = "undefined";
|
||||||
break;
|
break;
|
||||||
case "win32":
|
case "win32":
|
||||||
var appDataFolder = "undefined";
|
var appDataFolder = "undefined";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
var appDataFolder = "undefined";
|
var appDataFolder = "undefined";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var configFolder = path.join(appDataFolder, "FreeDATA");
|
var configFolder = path.join(appDataFolder, "FreeDATA");
|
||||||
var configPath = path.join(configFolder, "config.json");
|
var configPath = path.join(configFolder, "config.json");
|
||||||
|
|
||||||
console.log(appDataFolder)
|
console.log(appDataFolder);
|
||||||
console.log(configFolder)
|
console.log(configFolder);
|
||||||
console.log(configPath)
|
console.log(configPath);
|
||||||
|
|
||||||
|
|
||||||
// create config folder if not exists
|
// create config folder if not exists
|
||||||
if (!fs.existsSync(configFolder)) {
|
if (!fs.existsSync(configFolder)) {
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
var net = require("net");
|
var net = require("net");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
//const FD = require("./src/js/freedata.js");
|
//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 FD from './freedata.js';
|
||||||
|
|
||||||
import {addDataToWaterfall} from "../js/waterfallHandler.js"
|
import { addDataToWaterfall } from "../js/waterfallHandler.js";
|
||||||
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
newMessageReceived,
|
newMessageReceived,
|
||||||
|
@ -167,7 +166,7 @@ client.on("data", function (socketdata) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//console.log(data)
|
//console.log(data)
|
||||||
if (data["command"] == "modem_state") {
|
if (data["command"] == "modem_state") {
|
||||||
//console.log(data)
|
//console.log(data)
|
||||||
// set length of RX Buffer to global variable
|
// 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 = data["channel_busy"];
|
||||||
stateStore.channel_busy_slot = data["channel_busy_slot"];
|
stateStore.channel_busy_slot = data["channel_busy_slot"];
|
||||||
|
|
||||||
addDataToWaterfall(JSON.parse(data["fft"]))
|
addDataToWaterfall(JSON.parse(data["fft"]));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (data["scatter"].length > 0) {
|
if (data["scatter"].length > 0) {
|
||||||
stateStore.scatter = data["scatter"];
|
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_frame_n_bursts: data["arq_rx_frame_n_bursts"],
|
||||||
arq_rx_n_current_arq_frame: data["arq_rx_n_current_arq_frame"],
|
arq_rx_n_current_arq_frame: data["arq_rx_n_current_arq_frame"],
|
||||||
arq_n_arq_frames_per_data_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_bytes_per_minute: data["arq_bytes_per_minute"],
|
||||||
arq_compression_factor: data["arq_compression_factor"],
|
arq_compression_factor: data["arq_compression_factor"],
|
||||||
routing_table: data["routing_table"],
|
routing_table: data["routing_table"],
|
||||||
|
@ -272,7 +269,10 @@ client.on("data", function (socketdata) {
|
||||||
if (data["freedata"] == "modem-message") {
|
if (data["freedata"] == "modem-message") {
|
||||||
// break early if we received a dummy callsign
|
// break early if we received a dummy callsign
|
||||||
// thats a kind of hotfix, as long as the modem isnt handling this better
|
// 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,7 +334,12 @@ client.on("data", function (socketdata) {
|
||||||
switch (data["beacon"]) {
|
switch (data["beacon"]) {
|
||||||
case "transmitting":
|
case "transmitting":
|
||||||
// BEACON TRANSMITTING
|
// BEACON TRANSMITTING
|
||||||
displayToast("success", "bi-broadcast-pin", "Transmitting beacon", 5000);
|
displayToast(
|
||||||
|
"success",
|
||||||
|
"bi-broadcast-pin",
|
||||||
|
"Transmitting beacon",
|
||||||
|
5000,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "received":
|
case "received":
|
||||||
|
@ -357,14 +362,20 @@ client.on("data", function (socketdata) {
|
||||||
case "received":
|
case "received":
|
||||||
// PING RECEIVED
|
// PING RECEIVED
|
||||||
message =
|
message =
|
||||||
"Ping request from " + data["dxcallsign"] + " | " + data["dxgrid"];
|
"Ping request from " +
|
||||||
|
data["dxcallsign"] +
|
||||||
|
" | " +
|
||||||
|
data["dxgrid"];
|
||||||
displayToast("success", "bi-arrow-right-short", message, 5000);
|
displayToast("success", "bi-arrow-right-short", message, 5000);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "acknowledge":
|
case "acknowledge":
|
||||||
// PING ACKNOWLEDGE
|
// PING ACKNOWLEDGE
|
||||||
message =
|
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);
|
displayToast("success", "bi-arrow-left-right", message, 5000);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -485,7 +496,6 @@ client.on("data", function (socketdata) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//finally delete message buffer
|
//finally delete message buffer
|
||||||
|
@ -596,24 +606,22 @@ function sendFile(
|
||||||
|
|
||||||
// Send Message
|
// Send Message
|
||||||
export function sendMessage(obj) {
|
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 filename = Object.keys(obj._attachments)[0];
|
||||||
let checksum = obj.checksum
|
//let filetype = filename.split(".")[1]
|
||||||
let uuid = obj.uuid
|
let filetype = obj._attachments[filename].content_type;
|
||||||
let command = obj.command
|
let file = obj._attachments[filename].data;
|
||||||
|
|
||||||
let filename = Object.keys(obj._attachments)[0]
|
//console.log(obj._attachments)
|
||||||
//let filetype = filename.split(".")[1]
|
//console.log(filename)
|
||||||
let filetype = obj._attachments[filename].content_type
|
//console.log(filetype)
|
||||||
let file = obj._attachments[filename].data
|
//console.log(file)
|
||||||
|
|
||||||
//console.log(obj._attachments)
|
let data_with_attachment =
|
||||||
//console.log(filename)
|
|
||||||
//console.log(filetype)
|
|
||||||
//console.log(file)
|
|
||||||
|
|
||||||
|
|
||||||
let data_with_attachment =
|
|
||||||
obj.timestamp +
|
obj.timestamp +
|
||||||
split_char +
|
split_char +
|
||||||
obj.msg +
|
obj.msg +
|
||||||
|
@ -764,8 +772,7 @@ export function stopTransmission() {
|
||||||
export function getRxBuffer() {
|
export function getRxBuffer() {
|
||||||
var command = '{"type" : "get", "command" : "rx_buffer"}';
|
var command = '{"type" : "get", "command" : "rx_buffer"}';
|
||||||
|
|
||||||
writeTncCommand(command);
|
writeTncCommand(command);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// START BEACON
|
// START BEACON
|
||||||
|
@ -827,12 +834,11 @@ export function sendFecIsWriting(mycallsign) {
|
||||||
// SEND FEC TO BROADCASTCHANNEL
|
// SEND FEC TO BROADCASTCHANNEL
|
||||||
//export function sendBroadcastChannel(channel, data_out, uuid) {
|
//export function sendBroadcastChannel(channel, data_out, uuid) {
|
||||||
export function sendBroadcastChannel(obj) {
|
export function sendBroadcastChannel(obj) {
|
||||||
|
|
||||||
let checksum = obj.checksum;
|
let checksum = obj.checksum;
|
||||||
let command = obj.command;
|
let command = obj.command;
|
||||||
let uuid = obj.uuid;
|
let uuid = obj.uuid;
|
||||||
let channel = obj.dxcallsign
|
let channel = obj.dxcallsign;
|
||||||
let data_out = obj.msg
|
let data_out = obj.msg;
|
||||||
|
|
||||||
let data = btoa_FD(
|
let data = btoa_FD(
|
||||||
"m" +
|
"m" +
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import {Spectrum} from "../assets/waterfall/spectrum.js"
|
import { Spectrum } from "../assets/waterfall/spectrum.js";
|
||||||
|
|
||||||
|
|
||||||
import { setActivePinia } from "pinia";
|
import { setActivePinia } from "pinia";
|
||||||
import pinia from "../store/index";
|
import pinia from "../store/index";
|
||||||
|
@ -8,27 +7,23 @@ setActivePinia(pinia);
|
||||||
import { useSettingsStore } from "../store/settingsStore.js";
|
import { useSettingsStore } from "../store/settingsStore.js";
|
||||||
const settings = useSettingsStore(pinia);
|
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
|
console.log(settings.wftheme);
|
||||||
|
spectrum.setColorMap(settings.wftheme);
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addDataToWaterfall(data){
|
export function addDataToWaterfall(data) {
|
||||||
//console.log(spectrum)
|
//console.log(spectrum)
|
||||||
try {
|
try {
|
||||||
spectrum.addData(data);
|
spectrum.addData(data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
//console.log(e);
|
//console.log(e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,33 +1,29 @@
|
||||||
import { createApp } from 'vue'
|
import { createApp } from "vue";
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from "pinia";
|
||||||
import {loadSettings} from './js/settingsHandler'
|
import { loadSettings } from "./js/settingsHandler";
|
||||||
|
|
||||||
import './styles.css'
|
|
||||||
|
|
||||||
|
import "./styles.css";
|
||||||
|
|
||||||
// Import all of Bootstrap's JS
|
// Import all of Bootstrap's JS
|
||||||
//import * as bootstrap from 'bootstrap'
|
//import * as bootstrap from 'bootstrap'
|
||||||
|
|
||||||
import 'bootstrap/dist/js/bootstrap.bundle.min.js'
|
import "bootstrap/dist/js/bootstrap.bundle.min.js";
|
||||||
import 'bootstrap/dist/css/bootstrap.css'
|
import "bootstrap/dist/css/bootstrap.css";
|
||||||
import 'bootstrap-icons/font/bootstrap-icons.css'
|
import "bootstrap-icons/font/bootstrap-icons.css";
|
||||||
|
|
||||||
|
|
||||||
// Import our custom CSS
|
// Import our custom CSS
|
||||||
//import './scss/styles.scss'
|
//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' }, '*'))
|
//.mount('#app').$nextTick(() => postMessage({ payload: 'removeLoading' }, '*'))
|
||||||
const pinia = createPinia()
|
const pinia = createPinia();
|
||||||
app.mount('#app')
|
app.mount("#app");
|
||||||
|
|
||||||
app.use(pinia)
|
app.use(pinia);
|
||||||
loadSettings()
|
loadSettings();
|
||||||
|
|
||||||
//import './js/settingsHandler.js'
|
//import './js/settingsHandler.js'
|
||||||
import './js/daemon'
|
import "./js/daemon";
|
||||||
import './js/sock.js'
|
import "./js/sock.js";
|
||||||
//import './js/settingsHandler.js'
|
//import './js/settingsHandler.js'
|
||||||
|
|
|
@ -12,19 +12,17 @@ export const useAudioStore = defineStore("audioStore", () => {
|
||||||
var inputDevices = ref([{ id: 0, name: "no input devices" }]);
|
var inputDevices = ref([{ id: 0, name: "no input devices" }]);
|
||||||
var outputDevices = ref([{ id: 0, name: "no output devices" }]);
|
var outputDevices = ref([{ id: 0, name: "no output devices" }]);
|
||||||
|
|
||||||
var startupInputDevice = ref(0)
|
var startupInputDevice = ref(0);
|
||||||
var startupOutputDevice = ref(0)
|
var startupOutputDevice = ref(0);
|
||||||
|
|
||||||
|
|
||||||
function getInputDevices() {
|
function getInputDevices() {
|
||||||
var html = "";
|
var html = "";
|
||||||
for (var key in inputDevices.value) {
|
for (var key in inputDevices.value) {
|
||||||
|
let selected = "";
|
||||||
let selected = ''
|
if (inputDevices.value[key]["name"] == settings.rx_audio) {
|
||||||
if (inputDevices.value[key]["name"] == settings.rx_audio){
|
selected = "selected";
|
||||||
selected = "selected"
|
|
||||||
} else {
|
} else {
|
||||||
selected = ''
|
selected = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
html += `<option value=${inputDevices.value[key]["id"]} ${selected}>${inputDevices.value[key]["name"]}</option>`;
|
html += `<option value=${inputDevices.value[key]["id"]} ${selected}>${inputDevices.value[key]["name"]}</option>`;
|
||||||
|
@ -35,17 +33,23 @@ export const useAudioStore = defineStore("audioStore", () => {
|
||||||
function getOutputDevices() {
|
function getOutputDevices() {
|
||||||
var html = "";
|
var html = "";
|
||||||
for (var key in outputDevices.value) {
|
for (var key in outputDevices.value) {
|
||||||
|
let selected = "";
|
||||||
let selected = ''
|
if (outputDevices.value[key]["name"] == settings.tx_audio) {
|
||||||
if (outputDevices.value[key]["name"] == settings.tx_audio){
|
selected = "selected";
|
||||||
selected = "selected"
|
|
||||||
} else {
|
} else {
|
||||||
selected = ''
|
selected = "";
|
||||||
}
|
}
|
||||||
html += `<option value=${outputDevices.value[key]["id"]} ${selected}>${outputDevices.value[key]["name"]}</option>`;
|
html += `<option value=${outputDevices.value[key]["id"]} ${selected}>${outputDevices.value[key]["name"]}</option>`;
|
||||||
}
|
}
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { inputDevices, outputDevices, getInputDevices, getOutputDevices, startupInputDevice, startupOutputDevice };
|
return {
|
||||||
|
inputDevices,
|
||||||
|
outputDevices,
|
||||||
|
getInputDevices,
|
||||||
|
getOutputDevices,
|
||||||
|
startupInputDevice,
|
||||||
|
startupOutputDevice,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,31 +16,31 @@ export const useChatStore = defineStore("chatStore", () => {
|
||||||
var selectedCallsign = ref();
|
var selectedCallsign = ref();
|
||||||
// we need a default value in our ref because of our message info modal
|
// we need a default value in our ref because of our message info modal
|
||||||
var selectedMessageObject = ref({
|
var selectedMessageObject = ref({
|
||||||
"command": "msg",
|
command: "msg",
|
||||||
"hmac_signed": false,
|
hmac_signed: false,
|
||||||
"percent": 0,
|
percent: 0,
|
||||||
"is_new": false,
|
is_new: false,
|
||||||
"_id": "2ead6698",
|
_id: "2ead6698",
|
||||||
"timestamp": 1697289795,
|
timestamp: 1697289795,
|
||||||
"dxcallsign": "DJ2LS-0",
|
dxcallsign: "DJ2LS-0",
|
||||||
"dxgrid": "null",
|
dxgrid: "null",
|
||||||
"msg": "test",
|
msg: "test",
|
||||||
"checksum": "",
|
checksum: "",
|
||||||
"type": "transmit",
|
type: "transmit",
|
||||||
"status": "transmitting",
|
status: "transmitting",
|
||||||
"attempt": 1,
|
attempt: 1,
|
||||||
"uuid": "2ead6698",
|
uuid: "2ead6698",
|
||||||
"duration": 0,
|
duration: 0,
|
||||||
"nacks": 0,
|
nacks: 0,
|
||||||
"speed_list": "null",
|
speed_list: "null",
|
||||||
"_attachments": {
|
_attachments: {
|
||||||
"": {
|
"": {
|
||||||
"content_type": "text",
|
content_type: "text",
|
||||||
"data": ""
|
data: "",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
var inputText = ref('');
|
var inputText = ref("");
|
||||||
var inputFile = ref();
|
var inputFile = ref();
|
||||||
var inputFileName = ref();
|
var inputFileName = ref();
|
||||||
var inputFileType = ref();
|
var inputFileType = ref();
|
||||||
|
@ -62,8 +62,6 @@ export const useChatStore = defineStore("chatStore", () => {
|
||||||
var beaconDataArray = ref([]);
|
var beaconDataArray = ref([]);
|
||||||
var beaconLabelArray = ref([]);
|
var beaconLabelArray = ref([]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
selectedCallsign,
|
selectedCallsign,
|
||||||
selectedMessageObject,
|
selectedMessageObject,
|
||||||
|
|
|
@ -3,8 +3,8 @@ import { ref } from "vue";
|
||||||
|
|
||||||
export const useSettingsStore = defineStore("settingsStore", () => {
|
export const useSettingsStore = defineStore("settingsStore", () => {
|
||||||
// audio
|
// audio
|
||||||
var tx_audio = ref()
|
var tx_audio = ref();
|
||||||
var rx_audio = ref()
|
var rx_audio = ref();
|
||||||
|
|
||||||
// network
|
// network
|
||||||
var modem_host = ref("127.0.0.1");
|
var modem_host = ref("127.0.0.1");
|
||||||
|
@ -77,19 +77,19 @@ export const useSettingsStore = defineStore("settingsStore", () => {
|
||||||
var enable_mesh_features = ref("False");
|
var enable_mesh_features = ref("False");
|
||||||
var serial_devices = ref();
|
var serial_devices = ref();
|
||||||
|
|
||||||
|
|
||||||
function getSerialDevices() {
|
function getSerialDevices() {
|
||||||
if (this.hamlib_deviceport == "ignore")
|
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
|
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) {
|
for (var key in serial_devices.value) {
|
||||||
|
let selected = "";
|
||||||
let selected = ''
|
if (serial_devices.value[key]["port"] == this.hamlib_deviceport) {
|
||||||
if (serial_devices.value[key]["port"] == this. hamlib_deviceport){
|
selected = "selected";
|
||||||
selected = "selected"
|
|
||||||
} else {
|
} else {
|
||||||
selected = ''
|
selected = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
html += `<option value="${serial_devices.value[key]["port"]}" ${selected}>${serial_devices.value[key]["port"]} - ${serial_devices.value[key]["description"]}</option>`;
|
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,
|
tx_audio,
|
||||||
rx_audio,
|
rx_audio,
|
||||||
getSerialDevices,
|
getSerialDevices,
|
||||||
serial_devices
|
serial_devices,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -59,24 +59,24 @@ export const useStateStore = defineStore("stateStore", () => {
|
||||||
var python_version = ref();
|
var python_version = ref();
|
||||||
var modem_version = ref();
|
var modem_version = ref();
|
||||||
|
|
||||||
|
function getChannelBusySlotState(slot) {
|
||||||
function getChannelBusySlotState(slot){
|
|
||||||
const slot_state = channel_busy_slot.value;
|
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
|
// 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
|
// Parse the string to get an array
|
||||||
const arr = JSON.parse(string);
|
const arr = JSON.parse(string);
|
||||||
|
|
||||||
return arr[slot]
|
return arr[slot];
|
||||||
} else {
|
} else {
|
||||||
// Handle the undefined case
|
// Handle the undefined case
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function updateTncState(state) {
|
function updateTncState(state) {
|
||||||
modem_connection.value = state;
|
modem_connection.value = state;
|
||||||
|
@ -175,6 +175,6 @@ function getChannelBusySlotState(slot){
|
||||||
rigctld_started,
|
rigctld_started,
|
||||||
rigctld_process,
|
rigctld_process,
|
||||||
python_version,
|
python_version,
|
||||||
modem_version
|
modem_version,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
import { rmSync } from 'node:fs'
|
import { rmSync } from "node:fs";
|
||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from "vite";
|
||||||
import vue from '@vitejs/plugin-vue'
|
import vue from "@vitejs/plugin-vue";
|
||||||
import electron from 'vite-plugin-electron'
|
import electron from "vite-plugin-electron";
|
||||||
import renderer from 'vite-plugin-electron-renderer'
|
import renderer from "vite-plugin-electron-renderer";
|
||||||
import { notBundle } from 'vite-plugin-electron/plugin'
|
import { notBundle } from "vite-plugin-electron/plugin";
|
||||||
import pkg from './package.json'
|
import pkg from "./package.json";
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig(({ command }) => {
|
export default defineConfig(({ command }) => {
|
||||||
rmSync('dist-electron', { recursive: true, force: true })
|
rmSync("dist-electron", { recursive: true, force: true });
|
||||||
|
|
||||||
const isServe = command === 'serve'
|
const isServe = command === "serve";
|
||||||
const isBuild = command === 'build'
|
const isBuild = command === "build";
|
||||||
const sourcemap = isServe || !!process.env.VSCODE_DEBUG
|
const sourcemap = isServe || !!process.env.VSCODE_DEBUG;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
plugins: [
|
plugins: [
|
||||||
|
@ -20,25 +20,29 @@ export default defineConfig(({ command }) => {
|
||||||
electron([
|
electron([
|
||||||
{
|
{
|
||||||
// Main process entry file of the Electron App.
|
// Main process entry file of the Electron App.
|
||||||
entry: 'electron/main/index.ts',
|
entry: "electron/main/index.ts",
|
||||||
onstart({ startup }) {
|
onstart({ startup }) {
|
||||||
if (process.env.VSCODE_DEBUG) {
|
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 {
|
} else {
|
||||||
startup()
|
startup();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
vite: {
|
vite: {
|
||||||
build: {
|
build: {
|
||||||
sourcemap,
|
sourcemap,
|
||||||
minify: isBuild,
|
minify: isBuild,
|
||||||
outDir: 'dist-electron/main',
|
outDir: "dist-electron/main",
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
// Some third-party Node.js libraries may not be built correctly by Vite, especially `C/C++` addons,
|
// 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.
|
// 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.
|
// 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. :)
|
// 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: [
|
plugins: [
|
||||||
|
@ -49,40 +53,42 @@ export default defineConfig(({ command }) => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
entry: 'electron/preload/index.ts',
|
entry: "electron/preload/index.ts",
|
||||||
onstart({ reload }) {
|
onstart({ reload }) {
|
||||||
// Notify the Renderer process to reload the page when the Preload scripts build is complete,
|
// Notify the Renderer process to reload the page when the Preload scripts build is complete,
|
||||||
// instead of restarting the entire Electron App.
|
// instead of restarting the entire Electron App.
|
||||||
reload()
|
reload();
|
||||||
},
|
},
|
||||||
vite: {
|
vite: {
|
||||||
build: {
|
build: {
|
||||||
sourcemap: sourcemap ? 'inline' : undefined, // #332
|
sourcemap: sourcemap ? "inline" : undefined, // #332
|
||||||
minify: isBuild,
|
minify: isBuild,
|
||||||
outDir: 'dist-electron/preload',
|
outDir: "dist-electron/preload",
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
external: Object.keys('dependencies' in pkg ? pkg.dependencies : {}),
|
external: Object.keys(
|
||||||
|
"dependencies" in pkg ? pkg.dependencies : {},
|
||||||
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [isServe && notBundle()],
|
||||||
isServe && notBundle(),
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
]),
|
]),
|
||||||
// Use Node.js API in the Renderer process
|
// Use Node.js API in the Renderer process
|
||||||
renderer(),
|
renderer(),
|
||||||
],
|
],
|
||||||
server: process.env.VSCODE_DEBUG && (() => {
|
server:
|
||||||
const url = new URL(pkg.debug.env.VITE_DEV_SERVER_URL)
|
process.env.VSCODE_DEBUG &&
|
||||||
return {
|
(() => {
|
||||||
host: url.hostname,
|
const url = new URL(pkg.debug.env.VITE_DEV_SERVER_URL);
|
||||||
port: +url.port,
|
return {
|
||||||
}
|
host: url.hostname,
|
||||||
})(),
|
port: +url.port,
|
||||||
define: {
|
};
|
||||||
'import.meta.env.PACKAGE_VERSION':JSON.stringify(pkg.version)
|
})(),
|
||||||
},
|
define: {
|
||||||
|
"import.meta.env.PACKAGE_VERSION": JSON.stringify(pkg.version),
|
||||||
|
},
|
||||||
clearScreen: false,
|
clearScreen: false,
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
|
|
Loading…
Reference in a new issue