mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
Merge pull request #448 from DJ2LS/qm-newmsg
This commit is contained in:
commit
73bcb26659
7 changed files with 308 additions and 39 deletions
20
gui/main.js
20
gui/main.js
|
@ -100,7 +100,8 @@ const configDefaultSettings =
|
||||||
"max_retry_attempts" : 5, \
|
"max_retry_attempts" : 5, \
|
||||||
"enable_auto_retry" : "False", \
|
"enable_auto_retry" : "False", \
|
||||||
"tx_delay" : 0, \
|
"tx_delay" : 0, \
|
||||||
"auto_start": 0 \
|
"auto_start": 0, \
|
||||||
|
"enable_sys_notification": 1 \
|
||||||
}';
|
}';
|
||||||
|
|
||||||
if (!fs.existsSync(configPath)) {
|
if (!fs.existsSync(configPath)) {
|
||||||
|
@ -463,6 +464,23 @@ ipcMain.on("request-update-reception-status", (event, arg) => {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Called by main to query chat if there are new messages
|
||||||
|
ipcMain.on("request-update-unread-messages",() => {
|
||||||
|
//mainLog.info("Got request to check if chat has new messages")
|
||||||
|
chat.webContents.send("action-update-unread-messages");
|
||||||
|
|
||||||
|
});
|
||||||
|
//Called by chat to notify main if there are new messages
|
||||||
|
ipcMain.on("request-update-unread-messages-main", (event,arg) => {
|
||||||
|
win.webContents.send("action-update-unread-messages-main",arg);
|
||||||
|
//mainLog.info("Received reply from chat and ?new messages = " +arg);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Called by main to notify chat we should clean the DB
|
||||||
|
ipcMain.on("request-clean-db", () => {
|
||||||
|
chat.webContents.send("action-clean-db");
|
||||||
|
});
|
||||||
|
|
||||||
ipcMain.on("request-open-tnc-log", () => {
|
ipcMain.on("request-open-tnc-log", () => {
|
||||||
logViewer.show();
|
logViewer.show();
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
"@electron/osx-sign": "^1.0.4",
|
"@electron/osx-sign": "^1.0.4",
|
||||||
"@popperjs/core": "^2.11.6",
|
"@popperjs/core": "^2.11.6",
|
||||||
"blob-util": "^2.0.2",
|
"blob-util": "^2.0.2",
|
||||||
"bootstrap": "^5.3.0-alpha.3",
|
"bootstrap": "^5.3.0",
|
||||||
"bootstrap-icons": "^1.10.3",
|
"bootstrap-icons": "^1.10.5",
|
||||||
"bootswatch": "^5.2.3",
|
"bootswatch": "^5.2.3",
|
||||||
"browser-image-compression": "^2.0.0",
|
"browser-image-compression": "^2.0.0",
|
||||||
"chart.js": "^4.2.1",
|
"chart.js": "^4.2.1",
|
||||||
|
|
|
@ -165,7 +165,6 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||||
"user_info_website",
|
"user_info_website",
|
||||||
"user_info_comments",
|
"user_info_comments",
|
||||||
];
|
];
|
||||||
|
|
||||||
users
|
users
|
||||||
.find({
|
.find({
|
||||||
selector: {
|
selector: {
|
||||||
|
@ -216,9 +215,11 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||||
|
|
||||||
//Add event listener for filter apply button
|
//Add event listener for filter apply button
|
||||||
document.getElementById("btnFilter").addEventListener("click", () => {
|
document.getElementById("btnFilter").addEventListener("click", () => {
|
||||||
|
chatFilter.length=0;
|
||||||
|
if (document.getElementById("chkMessage").checked == true) {
|
||||||
chatFilter = [{ type: "newchat" }];
|
chatFilter = [{ type: "newchat" }];
|
||||||
if (document.getElementById("chkMessage").checked == true)
|
|
||||||
chatFilter.push({ type: "received" }, { type: "transmit" });
|
chatFilter.push({ type: "received" }, { type: "transmit" });
|
||||||
|
}
|
||||||
if (document.getElementById("chkPing").checked == true)
|
if (document.getElementById("chkPing").checked == true)
|
||||||
chatFilter.push({ type: "ping" });
|
chatFilter.push({ type: "ping" });
|
||||||
if (document.getElementById("chkPingAck").checked == true)
|
if (document.getElementById("chkPingAck").checked == true)
|
||||||
|
@ -229,6 +230,8 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||||
chatFilter.push({ type: "request" });
|
chatFilter.push({ type: "request" });
|
||||||
if (document.getElementById("chkResponse").checked == true)
|
if (document.getElementById("chkResponse").checked == true)
|
||||||
chatFilter.push({ type: "response" });
|
chatFilter.push({ type: "response" });
|
||||||
|
if (document.getElementById("chkNewMessage").checked == true)
|
||||||
|
chatFilter.push({new:1});
|
||||||
updateAllChat(true);
|
updateAllChat(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -785,6 +788,7 @@ ipcRenderer.on("action-new-msg-received", (event, arg) => {
|
||||||
obj.filename = "null";
|
obj.filename = "null";
|
||||||
obj.filetype = "null";
|
obj.filetype = "null";
|
||||||
obj.file = "null";
|
obj.file = "null";
|
||||||
|
obj.new = 1;
|
||||||
console.log(obj);
|
console.log(obj);
|
||||||
add_obj_to_database(obj);
|
add_obj_to_database(obj);
|
||||||
update_chat_obj_by_uuid(obj.uuid);
|
update_chat_obj_by_uuid(obj.uuid);
|
||||||
|
@ -813,11 +817,12 @@ ipcRenderer.on("action-new-msg-received", (event, arg) => {
|
||||||
obj.filename = "null";
|
obj.filename = "null";
|
||||||
obj.filetype = "null";
|
obj.filetype = "null";
|
||||||
obj.file = "null";
|
obj.file = "null";
|
||||||
|
obj.new = 0;
|
||||||
|
|
||||||
add_obj_to_database(obj);
|
add_obj_to_database(obj);
|
||||||
update_chat_obj_by_uuid(obj.uuid);
|
update_chat_obj_by_uuid(obj.uuid);
|
||||||
|
|
||||||
// handle beacon
|
// handle ping-ack
|
||||||
} else if (item.ping == "acknowledge") {
|
} else if (item.ping == "acknowledge") {
|
||||||
obj.timestamp = parseInt(item.timestamp);
|
obj.timestamp = parseInt(item.timestamp);
|
||||||
obj.dxcallsign = item.dxcallsign;
|
obj.dxcallsign = item.dxcallsign;
|
||||||
|
@ -832,7 +837,7 @@ ipcRenderer.on("action-new-msg-received", (event, arg) => {
|
||||||
obj.filename = "null";
|
obj.filename = "null";
|
||||||
obj.filetype = "null";
|
obj.filetype = "null";
|
||||||
obj.file = "null";
|
obj.file = "null";
|
||||||
|
obj.new = 0;
|
||||||
add_obj_to_database(obj);
|
add_obj_to_database(obj);
|
||||||
update_chat_obj_by_uuid(obj.uuid);
|
update_chat_obj_by_uuid(obj.uuid);
|
||||||
|
|
||||||
|
@ -851,7 +856,7 @@ ipcRenderer.on("action-new-msg-received", (event, arg) => {
|
||||||
obj.filename = "null";
|
obj.filename = "null";
|
||||||
obj.filetype = "null";
|
obj.filetype = "null";
|
||||||
obj.file = "null";
|
obj.file = "null";
|
||||||
|
obj.new = 0;
|
||||||
add_obj_to_database(obj);
|
add_obj_to_database(obj);
|
||||||
update_chat_obj_by_uuid(obj.uuid);
|
update_chat_obj_by_uuid(obj.uuid);
|
||||||
|
|
||||||
|
@ -879,6 +884,7 @@ ipcRenderer.on("action-new-msg-received", (event, arg) => {
|
||||||
obj.filetype = splitted_data[7];
|
obj.filetype = splitted_data[7];
|
||||||
//obj.file = btoa(splitted_data[8]);
|
//obj.file = btoa(splitted_data[8]);
|
||||||
obj.file = FD.btoa_FD(splitted_data[8]);
|
obj.file = FD.btoa_FD(splitted_data[8]);
|
||||||
|
obj.new=1;
|
||||||
} else if (splitted_data[1] == "req" && splitted_data[2] == "0") {
|
} else if (splitted_data[1] == "req" && splitted_data[2] == "0") {
|
||||||
obj.uuid = uuidv4().toString();
|
obj.uuid = uuidv4().toString();
|
||||||
obj.timestamp = Math.floor(Date.now() / 1000);
|
obj.timestamp = Math.floor(Date.now() / 1000);
|
||||||
|
@ -891,7 +897,7 @@ ipcRenderer.on("action-new-msg-received", (event, arg) => {
|
||||||
obj.filename = "null";
|
obj.filename = "null";
|
||||||
obj.filetype = "null";
|
obj.filetype = "null";
|
||||||
obj.file = "null";
|
obj.file = "null";
|
||||||
|
obj.new=0;
|
||||||
if (config.enable_request_profile == "True") {
|
if (config.enable_request_profile == "True") {
|
||||||
sendUserData(item.dxcallsign);
|
sendUserData(item.dxcallsign);
|
||||||
}
|
}
|
||||||
|
@ -907,7 +913,7 @@ ipcRenderer.on("action-new-msg-received", (event, arg) => {
|
||||||
obj.filename = "null";
|
obj.filename = "null";
|
||||||
obj.filetype = "null";
|
obj.filetype = "null";
|
||||||
obj.file = "null";
|
obj.file = "null";
|
||||||
|
obj.new=0;
|
||||||
if (config.enable_request_shared_folder == "True") {
|
if (config.enable_request_shared_folder == "True") {
|
||||||
sendSharedFolderList(item.dxcallsign);
|
sendSharedFolderList(item.dxcallsign);
|
||||||
}
|
}
|
||||||
|
@ -928,7 +934,7 @@ ipcRenderer.on("action-new-msg-received", (event, arg) => {
|
||||||
obj.filename = "null";
|
obj.filename = "null";
|
||||||
obj.filetype = "null";
|
obj.filetype = "null";
|
||||||
obj.file = "null";
|
obj.file = "null";
|
||||||
|
obj.new=0;
|
||||||
if (config.enable_request_shared_folder == "True") {
|
if (config.enable_request_shared_folder == "True") {
|
||||||
sendSharedFolderFile(item.dxcallsign, name);
|
sendSharedFolderFile(item.dxcallsign, name);
|
||||||
}
|
}
|
||||||
|
@ -944,7 +950,7 @@ ipcRenderer.on("action-new-msg-received", (event, arg) => {
|
||||||
obj.filename = "null";
|
obj.filename = "null";
|
||||||
obj.filetype = "null";
|
obj.filetype = "null";
|
||||||
obj.file = "null";
|
obj.file = "null";
|
||||||
|
obj.new=0;
|
||||||
console.log(splitted_data);
|
console.log(splitted_data);
|
||||||
let userData = new Object();
|
let userData = new Object();
|
||||||
userData.user_info_image = splitted_data[2];
|
userData.user_info_image = splitted_data[2];
|
||||||
|
@ -973,7 +979,7 @@ ipcRenderer.on("action-new-msg-received", (event, arg) => {
|
||||||
obj.filename = "null";
|
obj.filename = "null";
|
||||||
obj.filetype = "null";
|
obj.filetype = "null";
|
||||||
obj.file = "null";
|
obj.file = "null";
|
||||||
|
obj.new=0;
|
||||||
console.log(splitted_data);
|
console.log(splitted_data);
|
||||||
|
|
||||||
let userData = new Object();
|
let userData = new Object();
|
||||||
|
@ -1001,6 +1007,7 @@ ipcRenderer.on("action-new-msg-received", (event, arg) => {
|
||||||
obj.filename = sharedFileInfo[0];
|
obj.filename = sharedFileInfo[0];
|
||||||
obj.filetype = "application/octet-stream";
|
obj.filetype = "application/octet-stream";
|
||||||
obj.file = FD.btoa_FD(sharedFileInfo[1]);
|
obj.file = FD.btoa_FD(sharedFileInfo[1]);
|
||||||
|
obj.new=0;
|
||||||
} else {
|
} else {
|
||||||
console.log("no rule matched for handling received data!");
|
console.log("no rule matched for handling received data!");
|
||||||
}
|
}
|
||||||
|
@ -1040,7 +1047,7 @@ update_chat = function (obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// add percent and bytes per minute if not existing
|
// add percent and bytes per minute if not existing
|
||||||
console.log(obj.percent)
|
//console.log(obj.percent)
|
||||||
if (typeof obj.percent == "undefined") {
|
if (typeof obj.percent == "undefined") {
|
||||||
obj.percent = 0;
|
obj.percent = 0;
|
||||||
obj.bytesperminute = 0;
|
obj.bytesperminute = 0;
|
||||||
|
@ -1060,13 +1067,16 @@ var TimeDifference = (new Date().getTime()/1000) - obj.timestamp
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (typeof obj.new == "undefined"){
|
||||||
|
obj.new=0;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof config.max_retry_attempts == "undefined") {
|
if (typeof config.max_retry_attempts == "undefined") {
|
||||||
var max_retry_attempts = 3;
|
var max_retry_attempts = 3;
|
||||||
} else {
|
} else {
|
||||||
var max_retry_attempts = parseInt(config.max_retry_attempts);
|
var max_retry_attempts = parseInt(config.max_retry_attempts);
|
||||||
}
|
}
|
||||||
console.log(obj.msg);
|
//console.log(obj.msg);
|
||||||
// define shortmessage
|
// define shortmessage
|
||||||
if (obj.msg == "null" || obj.msg == "NULL") {
|
if (obj.msg == "null" || obj.msg == "NULL") {
|
||||||
var shortmsg = obj.type;
|
var shortmsg = obj.type;
|
||||||
|
@ -1201,7 +1211,7 @@ var TimeDifference = (new Date().getTime()/1000) - obj.timestamp
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span style="font-size:1.2rem;"><strong>${dxcallsign}</strong></span>
|
<span style="font-size:1.2rem;" ><strong id="chat-${dxcallsign}-list-displaydxcall">${dxcallsign}</strong></span>
|
||||||
<span class="badge bg-secondary text-white p-1 h-100" id="chat-${dxcallsign}-list-dxgrid"><small>${dxgrid}</small></span>
|
<span class="badge bg-secondary text-white p-1 h-100" id="chat-${dxcallsign}-list-dxgrid"><small>${dxgrid}</small></span>
|
||||||
<span style="font-size:0.8rem;" id="chat-${dxcallsign}-list-time">${timestampHours}</span>
|
<span style="font-size:0.8rem;" id="chat-${dxcallsign}-list-time">${timestampHours}</span>
|
||||||
<span class="position-absolute m-2 bottom-0 end-0" style="font-size:0.8rem;" id="chat-${dxcallsign}-list-shortmsg">${shortmsg}</span>
|
<span class="position-absolute m-2 bottom-0 end-0" style="font-size:0.8rem;" id="chat-${dxcallsign}-list-shortmsg">${shortmsg}</span>
|
||||||
|
@ -1231,6 +1241,11 @@ var TimeDifference = (new Date().getTime()/1000) - obj.timestamp
|
||||||
.addEventListener("click", function () {
|
.addEventListener("click", function () {
|
||||||
//document.getElementById('chatModuleDxCall').value = dxcallsign;
|
//document.getElementById('chatModuleDxCall').value = dxcallsign;
|
||||||
selected_callsign = dxcallsign;
|
selected_callsign = dxcallsign;
|
||||||
|
//Reset unread messages and new message indicator
|
||||||
|
let clear = selected_callsign;
|
||||||
|
clearUnreadMessages(clear);
|
||||||
|
document.getElementById(`chat-${selected_callsign}-list-displaydxcall`).textContent=selected_callsign;
|
||||||
|
document.getElementById(`chat-${selected_callsign}-list`).classList.remove("list-group-item-warning");
|
||||||
setTimeout(scrollMessagesToBottom, 200);
|
setTimeout(scrollMessagesToBottom, 200);
|
||||||
|
|
||||||
//get user information
|
//get user information
|
||||||
|
@ -1251,6 +1266,11 @@ var TimeDifference = (new Date().getTime()/1000) - obj.timestamp
|
||||||
// short message
|
// short message
|
||||||
document.getElementById("chat-" + dxcallsign + "-list-shortmsg").innerHTML =
|
document.getElementById("chat-" + dxcallsign + "-list-shortmsg").innerHTML =
|
||||||
shortmsg;
|
shortmsg;
|
||||||
|
if (obj.new==1) {
|
||||||
|
document.getElementById(`chat-${obj.dxcallsign}-list-displaydxcall`).textContent="*" +obj.dxcallsign;
|
||||||
|
document.getElementById(`chat-${dxcallsign}-list`).classList.add("list-group-item-warning");
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// APPEND MESSAGES TO CALLSIGN
|
// APPEND MESSAGES TO CALLSIGN
|
||||||
|
|
||||||
|
@ -1260,7 +1280,10 @@ var TimeDifference = (new Date().getTime()/1000) - obj.timestamp
|
||||||
if (config.enable_auto_retry.toUpperCase() == "TRUE") {
|
if (config.enable_auto_retry.toUpperCase() == "TRUE") {
|
||||||
checkForWaitingMessages(obj.dxcallsign);
|
checkForWaitingMessages(obj.dxcallsign);
|
||||||
}
|
}
|
||||||
|
//if (obj.new == 1)
|
||||||
|
//{
|
||||||
|
// showOsPopUp("Ping from " + obj.dxcallsign,"You've been ping'd!");
|
||||||
|
//}
|
||||||
var new_message = `
|
var new_message = `
|
||||||
<div class="m-auto mt-1 p-0 w-50 rounded bg-secondary bg-gradient" id="msg-${obj._id}">
|
<div class="m-auto mt-1 p-0 w-50 rounded bg-secondary bg-gradient" id="msg-${obj._id}">
|
||||||
<p class="text-small text-white mb-0 text-break" style="font-size: 0.7rem;"><i class="m-3 bi bi-arrow-left-right"></i>snr: ${obj.snr} - ${timestamp} </p>
|
<p class="text-small text-white mb-0 text-break" style="font-size: 0.7rem;"><i class="m-3 bi bi-arrow-left-right"></i>snr: ${obj.snr} - ${timestamp} </p>
|
||||||
|
@ -1311,6 +1334,11 @@ var TimeDifference = (new Date().getTime()/1000) - obj.timestamp
|
||||||
var message_html = obj.msg.replaceAll(/\n/g, "<br>");
|
var message_html = obj.msg.replaceAll(/\n/g, "<br>");
|
||||||
|
|
||||||
if (obj.type == "received") {
|
if (obj.type == "received") {
|
||||||
|
if (obj.new == 1)
|
||||||
|
{
|
||||||
|
showOsPopUp("Message received from " + obj.dxcallsign,obj.msg);
|
||||||
|
}
|
||||||
|
|
||||||
var new_message = `
|
var new_message = `
|
||||||
<div class="d-flex align-items-center" style="margin-left: auto;"> <!-- max-width: 75%; -->
|
<div class="d-flex align-items-center" style="margin-left: auto;"> <!-- max-width: 75%; -->
|
||||||
|
|
||||||
|
@ -1401,7 +1429,7 @@ var TimeDifference = (new Date().getTime()/1000) - obj.timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.type == "transmit") {
|
if (obj.type == "transmit") {
|
||||||
console.log(obj);
|
//console.log(obj);
|
||||||
//console.log('msg-' + obj._id + '-status')
|
//console.log('msg-' + obj._id + '-status')
|
||||||
|
|
||||||
if (obj.status == "failed") {
|
if (obj.status == "failed") {
|
||||||
|
@ -1474,11 +1502,11 @@ var TimeDifference = (new Date().getTime()/1000) - obj.timestamp
|
||||||
|
|
||||||
/* UPDATE EXISTING ELEMENTS */
|
/* UPDATE EXISTING ELEMENTS */
|
||||||
} else if (document.getElementById("msg-" + obj._id)) {
|
} else if (document.getElementById("msg-" + obj._id)) {
|
||||||
console.log("element already exists......");
|
//console.log("element already exists......");
|
||||||
console.log(obj);
|
//console.log(obj);
|
||||||
|
|
||||||
console.log(obj.status)
|
// console.log(obj.status)
|
||||||
console.log(obj.attempt)
|
// console.log(obj.attempt)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1861,6 +1889,7 @@ add_obj_to_database = function (obj) {
|
||||||
status: obj.status,
|
status: obj.status,
|
||||||
snr: obj.snr,
|
snr: obj.snr,
|
||||||
attempt: obj.attempt,
|
attempt: obj.attempt,
|
||||||
|
new: obj.new,
|
||||||
_attachments: {
|
_attachments: {
|
||||||
[obj.filename]: {
|
[obj.filename]: {
|
||||||
content_type: obj.filetype,
|
content_type: obj.filetype,
|
||||||
|
@ -2110,6 +2139,7 @@ function createChatIndex() {
|
||||||
"attempt",
|
"attempt",
|
||||||
"bytesperminute",
|
"bytesperminute",
|
||||||
"_attachments",
|
"_attachments",
|
||||||
|
"new",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -2171,7 +2201,10 @@ async function updateAllChat(clear) {
|
||||||
await db
|
await db
|
||||||
.createIndex({
|
.createIndex({
|
||||||
index: {
|
index: {
|
||||||
fields: [{ timestamp: "asc" }],
|
fields: [
|
||||||
|
{ dxcallsign:"asc" },
|
||||||
|
{ timestamp:"asc" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(async function (result) {
|
.then(async function (result) {
|
||||||
|
@ -2179,14 +2212,16 @@ async function updateAllChat(clear) {
|
||||||
await db
|
await db
|
||||||
.find({
|
.find({
|
||||||
selector: {
|
selector: {
|
||||||
$and: [{ timestamp: { $exists: true } }, { $or: chatFilter }],
|
$and: [
|
||||||
|
{dxcallsign: { $exists: true } },
|
||||||
|
{timestamp: { $exists: true } },
|
||||||
|
{ $or: chatFilter }]
|
||||||
//$or: chatFilter
|
//$or: chatFilter
|
||||||
},
|
},
|
||||||
sort: [
|
sort: [
|
||||||
{
|
{ dxcallsign:"asc" },
|
||||||
timestamp: "asc",
|
{ timestamp: "asc" },
|
||||||
},
|
]
|
||||||
],
|
|
||||||
})
|
})
|
||||||
.then(async function (result) {
|
.then(async function (result) {
|
||||||
console.log(result);
|
console.log(result);
|
||||||
|
@ -2249,9 +2284,9 @@ function getSetUserSharedFolder(selected_callsign) {
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
|
||||||
console.log(data.user_shared_folder);
|
|
||||||
|
|
||||||
if (typeof data.user_shared_folder !== "undefined") {
|
if (typeof data.user_shared_folder !== "undefined") {
|
||||||
|
console.log(data.user_shared_folder);
|
||||||
// shared folder table
|
// shared folder table
|
||||||
var icons = [
|
var icons = [
|
||||||
"aac",
|
"aac",
|
||||||
|
@ -2637,6 +2672,16 @@ ipcRenderer.on("update-config", (event, data) => {
|
||||||
config = data;
|
config = data;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcRenderer.on("action-update-unread-messages", (event) => {
|
||||||
|
checkForNewMessages().then(function(count) {
|
||||||
|
ipcRenderer.send("request-update-unread-messages-main",count);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcRenderer.on("action-clean-db", (event) => {
|
||||||
|
dbClean();
|
||||||
|
});
|
||||||
|
|
||||||
// https://stackoverflow.com/a/18650828
|
// https://stackoverflow.com/a/18650828
|
||||||
function formatBytes(bytes, decimals = 2) {
|
function formatBytes(bytes, decimals = 2) {
|
||||||
if (!+bytes) return "0 Bytes";
|
if (!+bytes) return "0 Bytes";
|
||||||
|
@ -2766,3 +2811,110 @@ function checkForWaitingMessages(dxcall) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function checkForNewMessages()
|
||||||
|
{
|
||||||
|
var newmsgs;
|
||||||
|
await db.find({
|
||||||
|
selector: {
|
||||||
|
new: {$eq: 1},
|
||||||
|
}, limit:1,
|
||||||
|
})
|
||||||
|
.then(function (result) {
|
||||||
|
if (result.docs.length >0)
|
||||||
|
newmsgs=true;
|
||||||
|
else
|
||||||
|
newmsgs=false;
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
return newmsgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearUnreadMessages(dxcall) {
|
||||||
|
//console.log(dxcall);
|
||||||
|
//Selector of dxcall and new $eq: 1 isn't working, don't know why
|
||||||
|
//For now parse all messages of callsign to clear new flag
|
||||||
|
db.find({
|
||||||
|
selector: //{
|
||||||
|
//$and:[
|
||||||
|
{dxcallsign:dxcall}//, {new: { $gte: 1}}
|
||||||
|
//]
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
.then(function (result) {
|
||||||
|
//console.log(result);
|
||||||
|
//console.log ("New messages count to clear for " + dxcall + ": " + result.docs.length)
|
||||||
|
result.docs.forEach(function (item) {
|
||||||
|
if (item.new ==1)
|
||||||
|
{
|
||||||
|
db.upsert(item._id, function (doc) {
|
||||||
|
doc.new=0;
|
||||||
|
//console.log("Clearing new on _id " + item._id);
|
||||||
|
return doc;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Have the operating system show a notification popup
|
||||||
|
function showOsPopUp(title, message)
|
||||||
|
{
|
||||||
|
if (config.enable_sys_notification == 0) return;
|
||||||
|
const NOTIFICATION_TITLE = title;
|
||||||
|
const NOTIFICATION_BODY = message;
|
||||||
|
new Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY });
|
||||||
|
}
|
||||||
|
|
||||||
|
//Function to clean old beacons and optimize database
|
||||||
|
async function dbClean()
|
||||||
|
{
|
||||||
|
//Only keep the most x latest days of beacons
|
||||||
|
let beaconKeep = 7;
|
||||||
|
let itemCount = 0;
|
||||||
|
let timestampPurge = Math.floor((Date.now()- beaconKeep * 24*60*60*1000) / 1000) ;
|
||||||
|
if (confirm("Delete beacons and pings older than " + beaconKeep + " days and compact database?")) {
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Items to purge from database
|
||||||
|
var purgeFilter = [
|
||||||
|
{ type: "beacon" },
|
||||||
|
{ type: "ping-ack" },
|
||||||
|
{ type: "ping" },
|
||||||
|
];
|
||||||
|
|
||||||
|
await db.find({
|
||||||
|
selector: {
|
||||||
|
$and: [
|
||||||
|
{timestamp: { $lt: timestampPurge } },
|
||||||
|
{ $or: purgeFilter }]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(async function (result) {
|
||||||
|
//console.log("Purging " + result.docs.length + " beacons received before " + timestampPurge);
|
||||||
|
itemCount=result.docs.length;
|
||||||
|
result.docs.forEach(async function (item) {
|
||||||
|
await db.get(item._id)
|
||||||
|
.then(async function (doc) {
|
||||||
|
await db.remove(doc)
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Compact database
|
||||||
|
await db.compact();
|
||||||
|
window.alert("Database maintenance is complete. " + itemCount + " items removed from database. It's recommended you now restart the GUI.");
|
||||||
|
}
|
||||||
|
|
|
@ -390,6 +390,12 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||||
document.getElementById("AutoStartSwitch").checked = false;
|
document.getElementById("AutoStartSwitch").checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.enable_sys_notification == 1) {
|
||||||
|
document.getElementById("NotificationSwitch").checked = true;
|
||||||
|
} else {
|
||||||
|
document.getElementById("NotificationSwitch").checked = false;
|
||||||
|
}
|
||||||
|
|
||||||
// theme selector
|
// theme selector
|
||||||
changeGuiDesign(config.theme);
|
changeGuiDesign(config.theme);
|
||||||
|
|
||||||
|
@ -1213,6 +1219,17 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||||
FD.saveConfig(config, configPath);
|
FD.saveConfig(config, configPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Handle change of Notification settings
|
||||||
|
document.getElementById("NotificationSwitch").addEventListener("click", () => {
|
||||||
|
if (document.getElementById("NotificationSwitch").checked == true) {
|
||||||
|
config.enable_sys_notification = 1;
|
||||||
|
} else {
|
||||||
|
config.enable_sys_notification = 0;
|
||||||
|
}
|
||||||
|
//fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
||||||
|
FD.saveConfig(config, configPath);
|
||||||
|
});
|
||||||
|
|
||||||
// enable fsk Switch clicked
|
// enable fsk Switch clicked
|
||||||
document.getElementById("fskModeSwitch").addEventListener("click", () => {
|
document.getElementById("fskModeSwitch").addEventListener("click", () => {
|
||||||
if (document.getElementById("fskModeSwitch").checked == true) {
|
if (document.getElementById("fskModeSwitch").checked == true) {
|
||||||
|
@ -1589,6 +1606,11 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||||
daemon.stopTNC();
|
daemon.stopTNC();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// btnCleanDB button clicked
|
||||||
|
document.getElementById("btnCleanDB").addEventListener("click", () => {
|
||||||
|
ipcRenderer.send("request-clean-db");
|
||||||
|
});
|
||||||
|
|
||||||
// TEST HAMLIB
|
// TEST HAMLIB
|
||||||
document.getElementById("testHamlib").addEventListener("click", () => {
|
document.getElementById("testHamlib").addEventListener("click", () => {
|
||||||
var data_bits = document.getElementById("hamlib_data_bits").value;
|
var data_bits = document.getElementById("hamlib_data_bits").value;
|
||||||
|
@ -1610,6 +1632,8 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||||
var radiocontrol = "rigctld";
|
var radiocontrol = "rigctld";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
daemon.testHamlib(
|
daemon.testHamlib(
|
||||||
radiocontrol,
|
radiocontrol,
|
||||||
deviceid,
|
deviceid,
|
||||||
|
@ -1934,7 +1958,16 @@ function signal_quality_perc_quad(rssi, perfect_rssi = 10, worst_rssi = -150) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var lastHeard = "";
|
var lastHeard = "";
|
||||||
|
var checkForNewMessageWait=85;
|
||||||
|
|
||||||
ipcRenderer.on("action-update-tnc-state", (event, arg) => {
|
ipcRenderer.on("action-update-tnc-state", (event, arg) => {
|
||||||
|
//check for new messages
|
||||||
|
if (checkForNewMessageWait >= 100){
|
||||||
|
//This is very expensive
|
||||||
|
ipcRenderer.send("request-update-unread-messages");
|
||||||
|
checkForNewMessageWait=-1;
|
||||||
|
}
|
||||||
|
checkForNewMessageWait++;
|
||||||
// update FFT
|
// update FFT
|
||||||
if (typeof arg.fft !== "undefined") {
|
if (typeof arg.fft !== "undefined") {
|
||||||
// FIXME: WE need to fix this when disabled waterfall chart
|
// FIXME: WE need to fix this when disabled waterfall chart
|
||||||
|
@ -2891,6 +2924,22 @@ ipcRenderer.on("run-tnc-command-fec-iswriting", (event) => {
|
||||||
sock.sendFecIsWriting(config.mycall);
|
sock.sendFecIsWriting(config.mycall);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Change background color of RF Chat button if new messages are available
|
||||||
|
ipcRenderer.on("action-update-unread-messages-main", (event,data) => {
|
||||||
|
//Do something
|
||||||
|
if (data == true)
|
||||||
|
{
|
||||||
|
document.getElementById("openRFChat").classList.add("btn-warning")
|
||||||
|
document.getElementById("openRFChat").classList.remove("btn-secondary")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
document.getElementById("openRFChat").classList.remove("btn-warning")
|
||||||
|
document.getElementById("openRFChat").classList.add("btn-secondary")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
ipcRenderer.on("run-tnc-command", (event, arg) => {
|
ipcRenderer.on("run-tnc-command", (event, arg) => {
|
||||||
if (arg.command == "save_my_call") {
|
if (arg.command == "save_my_call") {
|
||||||
sock.saveMyCall(arg.callsign);
|
sock.saveMyCall(arg.callsign);
|
||||||
|
@ -3072,7 +3121,7 @@ ipcRenderer.on("action-show-cq-toast-received", (event, data) => {
|
||||||
let dxcallsign = data["data"][0]["dxcallsign"];
|
let dxcallsign = data["data"][0]["dxcallsign"];
|
||||||
let dxgrid = data["data"][0]["dxgrid"];
|
let dxgrid = data["data"][0]["dxgrid"];
|
||||||
let content = `cq from <strong>${dxcallsign}</strong> (${dxgrid})`;
|
let content = `cq from <strong>${dxcallsign}</strong> (${dxgrid})`;
|
||||||
|
showOsPopUp("CQ from " + dxcallsign,"Say hello!");
|
||||||
displayToast(
|
displayToast(
|
||||||
(type = "success"),
|
(type = "success"),
|
||||||
(icon = "bi-broadcast"),
|
(icon = "bi-broadcast"),
|
||||||
|
@ -3760,3 +3809,12 @@ function autostart_tnc() {
|
||||||
document.getElementById("startTNC").click();
|
document.getElementById("startTNC").click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Have the operating system show a notification popup
|
||||||
|
function showOsPopUp(title, message)
|
||||||
|
{
|
||||||
|
if (config.enable_sys_notification == 0) return;
|
||||||
|
const NOTIFICATION_TITLE = title;
|
||||||
|
const NOTIFICATION_BODY = message;
|
||||||
|
new Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY });
|
||||||
|
}
|
|
@ -161,7 +161,21 @@
|
||||||
id="chkMessage"
|
id="chkMessage"
|
||||||
/>
|
/>
|
||||||
<label class="form-check-label" for="chkMessage">
|
<label class="form-check-label" for="chkMessage">
|
||||||
Messages
|
All Messages
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-1">
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
checked="false"
|
||||||
|
type="checkbox"
|
||||||
|
class="form-check-input"
|
||||||
|
id="chkNewMessage"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<label class="form-check-label" for="chkNewMessage">
|
||||||
|
Unread Messages
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -247,9 +261,13 @@
|
||||||
class="dropdown-item bg-danger text-white"
|
class="dropdown-item bg-danger text-white"
|
||||||
id="delete_selected_chat"
|
id="delete_selected_chat"
|
||||||
href="#"
|
href="#"
|
||||||
>Delete chat</a
|
><i
|
||||||
>
|
class="bi bi-person-x"
|
||||||
|
style="font-size: 1rem"
|
||||||
|
></i>
|
||||||
|
Delete chat</a>
|
||||||
</li>
|
</li>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
<li>
|
<li>
|
||||||
<button
|
<button
|
||||||
class="dropdown-item"
|
class="dropdown-item"
|
||||||
|
@ -264,9 +282,6 @@
|
||||||
Help
|
Help
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
|
|
|
@ -189,7 +189,7 @@
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-trigger="hover"
|
data-bs-trigger="hover"
|
||||||
data-bs-html="false"
|
data-bs-html="false"
|
||||||
title="Open the HF chat module. This is currently just a test and not finished, yet!"
|
title="Open the chat window. The background will change to yellow if a new message is available."
|
||||||
>
|
>
|
||||||
<i class="bi bi-chat-left-text-fill me-2"></i>
|
<i class="bi bi-chat-left-text-fill me-2"></i>
|
||||||
<strong>RF Chat</strong>
|
<strong>RF Chat</strong>
|
||||||
|
@ -2907,6 +2907,23 @@
|
||||||
<option value="alpha">alpha</option>
|
<option value="alpha">alpha</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="input-group input-group-sm mb-1">
|
||||||
|
<label class="input-group-text w-50"
|
||||||
|
>Enable notifications</label
|
||||||
|
>
|
||||||
|
<label class="input-group-text w-50">
|
||||||
|
<div class="form-check form-switch form-check-inline">
|
||||||
|
<input
|
||||||
|
class="form-check-input"
|
||||||
|
type="checkbox"
|
||||||
|
id="NotificationSwitch"
|
||||||
|
/>
|
||||||
|
<label class="form-check-label" for="NotificationSwitch"
|
||||||
|
>Show system pop-ups</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<div class="input-group input-group-sm mb-1">
|
<div class="input-group input-group-sm mb-1">
|
||||||
<label class="input-group-text w-50"
|
<label class="input-group-text w-50"
|
||||||
>Auto-start TNC/rigctld</label
|
>Auto-start TNC/rigctld</label
|
||||||
|
@ -3779,6 +3796,12 @@
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="input-group input-group-sm mb-1">
|
||||||
|
<label class="input-group-text w-50">Database maintenance</label>
|
||||||
|
<label class="input-group-text w-50">
|
||||||
|
<button class="btn btn-outline-secondary btn-sm w-50" id="btnCleanDB" type="button">Clean</button>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<div class="badge text-bg-danger">
|
<div class="badge text-bg-danger">
|
||||||
<i class="bi bi-shield-exclamation"></i> These options may
|
<i class="bi bi-shield-exclamation"></i> These options may
|
||||||
|
|
|
@ -76,6 +76,9 @@ def fetch_audio_devices(input_devices, output_devices):
|
||||||
# Use a try/except block because Windows doesn't have an audio device range
|
# Use a try/except block because Windows doesn't have an audio device range
|
||||||
try:
|
try:
|
||||||
name = device["name"]
|
name = device["name"]
|
||||||
|
# Ignore some Flex Radio devices to make device selection simpler
|
||||||
|
if name.startswith("DAX RESERVED") or name.startswith("DAX IQ"):
|
||||||
|
continue
|
||||||
|
|
||||||
max_output_channels = device["max_output_channels"]
|
max_output_channels = device["max_output_channels"]
|
||||||
max_input_channels = device["max_input_channels"]
|
max_input_channels = device["max_input_channels"]
|
||||||
|
|
Loading…
Reference in a new issue