FreeDATA/gui/preload-chat.js

2921 lines
97 KiB
JavaScript
Raw Normal View History

2023-02-11 21:49:07 +00:00
const path = require("path");
const { ipcRenderer } = require("electron");
const { v4: uuidv4 } = require("uuid");
2023-02-25 22:23:59 +00:00
const imageCompression = require("browser-image-compression");
2023-02-26 07:48:51 +00:00
const blobUtil = require("blob-util");
const FD = require("./freedata");
2023-03-05 21:16:43 +00:00
const fs = require("fs");
2023-02-26 07:48:51 +00:00
2021-11-19 16:30:17 +00:00
// https://stackoverflow.com/a/26227660
2023-02-11 21:49:07 +00:00
var appDataFolder =
process.env.APPDATA ||
(process.platform == "darwin"
? process.env.HOME + "/Library/Application Support"
: process.env.HOME + "/.config");
2021-11-19 16:30:17 +00:00
var configFolder = path.join(appDataFolder, "FreeDATA");
2023-02-11 21:49:07 +00:00
var configPath = path.join(configFolder, "config.json");
2023-03-04 15:47:42 +00:00
var config = require(configPath);
2022-03-10 20:29:30 +00:00
// set date format
2023-02-25 00:04:19 +00:00
const dateFormat = new Intl.DateTimeFormat(navigator.language, {
2023-02-11 21:49:07 +00:00
timeStyle: "long",
2023-02-23 10:48:19 +00:00
dateStyle: "short",
2022-03-10 20:29:30 +00:00
});
// set date format information
2023-02-25 00:04:19 +00:00
const dateFormatShort = new Intl.DateTimeFormat(navigator.language, {
2023-02-11 21:49:07 +00:00
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
second: "numeric",
hour12: false,
});
2022-04-02 16:40:12 +00:00
2023-02-25 00:04:19 +00:00
const dateFormatHours = new Intl.DateTimeFormat(navigator.language, {
2023-02-11 21:49:07 +00:00
hour: "numeric",
minute: "numeric",
hour12: false,
2022-04-02 16:40:12 +00:00
});
2022-03-10 20:29:30 +00:00
// split character
2023-02-11 21:49:07 +00:00
const split_char = "\0;\1;";
// global for our selected file we want to transmit
2022-03-29 20:24:35 +00:00
// ----------------- some chat globals
2023-02-11 21:49:07 +00:00
var filetype = "";
var file = "";
var filename = "";
2022-03-29 20:24:35 +00:00
var callsign_counter = 0;
2023-02-11 21:49:07 +00:00
var selected_callsign = "";
2023-02-12 23:15:12 +00:00
var lastIsWritingBroadcast = new Date().getTime();
2023-02-28 19:07:10 +00:00
var defaultUserIcon =
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iY3VycmVudENvbG9yIiBjbGFzcz0iYmkgYmktcGVyc29uLWJvdW5kaW5nLWJveCIgdmlld0JveD0iMCAwIDE2IDE2Ij4KICA8cGF0aCBkPSJNMS41IDFhLjUuNSAwIDAgMC0uNS41djNhLjUuNSAwIDAgMS0xIDB2LTNBMS41IDEuNSAwIDAgMSAxLjUgMGgzYS41LjUgMCAwIDEgMCAxaC0zek0xMSAuNWEuNS41IDAgMCAxIC41LS41aDNBMS41IDEuNSAwIDAgMSAxNiAxLjV2M2EuNS41IDAgMCAxLTEgMHYtM2EuNS41IDAgMCAwLS41LS41aC0zYS41LjUgMCAwIDEtLjUtLjV6TS41IDExYS41LjUgMCAwIDEgLjUuNXYzYS41LjUgMCAwIDAgLjUuNWgzYS41LjUgMCAwIDEgMCAxaC0zQTEuNSAxLjUgMCAwIDEgMCAxNC41di0zYS41LjUgMCAwIDEgLjUtLjV6bTE1IDBhLjUuNSAwIDAgMSAuNS41djNhMS41IDEuNSAwIDAgMS0xLjUgMS41aC0zYS41LjUgMCAwIDEgMC0xaDNhLjUuNSAwIDAgMCAuNS0uNXYtM2EuNS41IDAgMCAxIC41LS41eiIvPgogIDxwYXRoIGQ9Ik0zIDE0cy0xIDAtMS0xIDEtNCA2LTQgNiAzIDYgNC0xIDEtMSAxSDN6bTgtOWEzIDMgMCAxIDEtNiAwIDMgMyAwIDAgMSA2IDB6Ii8+Cjwvc3ZnPg==";
2023-05-16 17:08:31 +00:00
var defaultGroupIcon =
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iY3VycmVudENvbG9yIiBjbGFzcz0iYmkgYmktcGVvcGxlLWZpbGwiIHZpZXdCb3g9IjAgMCAxNiAxNiI+CiAgPHBhdGggZD0iTTcgMTRzLTEgMC0xLTEgMS00IDUtNCA1IDMgNSA0LTEgMS0xIDFIN1ptNC02YTMgMyAwIDEgMCAwLTYgMyAzIDAgMCAwIDAgNlptLTUuNzg0IDZBMi4yMzggMi4yMzggMCAwIDEgNSAxM2MwLTEuMzU1LjY4LTIuNzUgMS45MzYtMy43MkE2LjMyNSA2LjMyNSAwIDAgMCA1IDljLTQgMC01IDMtNSA0czEgMSAxIDFoNC4yMTZaTTQuNSA4YTIuNSAyLjUgMCAxIDAgMC01IDIuNSAyLjUgMCAwIDAgMCA1WiIvPgo8L3N2Zz4=";
2023-02-28 19:06:39 +00:00
2022-03-29 20:24:35 +00:00
// -----------------------------------
// Initially fill sharedFolderFileList
//TODO: Make this automatically ever N seconds
2023-02-28 14:20:17 +00:00
var sharedFolderFileList = "";
ipcRenderer.send("read-files-in-folder", {
2023-02-28 14:20:17 +00:00
folder: config.shared_folder_path,
});
2022-04-03 13:26:24 +00:00
2023-02-11 21:49:07 +00:00
var chatDB = path.join(configFolder, "chatDB");
2023-02-19 13:36:29 +00:00
var userDB = path.join(configFolder, "userDB");
2022-03-10 20:29:30 +00:00
// ---- MessageDB
2023-02-11 21:49:07 +00:00
try {
var PouchDB = require("pouchdb");
} catch (err) {
console.log(err);
2023-02-11 21:49:07 +00:00
/*
This is a fix for raspberryPi where we get an error when loading pouchdb because of
leveldown package isnt running on ARM devices.
pouchdb-browser does not depend on leveldb and seems to be working.
*/
2023-02-11 21:49:07 +00:00
console.log("using pouchdb-browser fallback");
var PouchDB = require("pouchdb-browser");
}
2023-02-11 21:49:07 +00:00
PouchDB.plugin(require("pouchdb-find"));
2022-12-26 19:41:58 +00:00
//PouchDB.plugin(require('pouchdb-replication'));
2023-05-09 08:36:30 +00:00
PouchDB.plugin(require("pouchdb-upsert"));
2022-12-26 19:41:58 +00:00
2022-03-10 20:29:30 +00:00
var db = new PouchDB(chatDB);
2023-02-18 18:55:13 +00:00
var users = new PouchDB(userDB);
2022-11-17 21:17:50 +00:00
2023-02-19 13:36:29 +00:00
/* -------- CREATE DATABASE INDEXES */
2023-02-20 17:55:21 +00:00
createChatIndex();
createUserIndex();
2023-02-19 13:36:29 +00:00
2023-02-25 22:23:59 +00:00
// REMOTE SYNC ATTEMPTS
2022-12-26 19:41:58 +00:00
2023-02-25 22:23:59 +00:00
//var remoteDB = new PouchDB('http://172.20.10.4:5984/chatDB')
/*
2022-12-26 19:41:58 +00:00
// we need express packages for running pouchdb sync "express-pouchdb"
var express = require('express');
var app = express();
2023-02-25 22:23:59 +00:00
app.use('/chatDB', require('express-pouchdb')(PouchDB));
app.listen(5984);
2022-12-26 19:41:58 +00:00
app.use('/chatDB', require('pouchdb-express-router')(PouchDB));
app.listen(5984);
db.sync('http://172.20.10.4:5984/jojo', {
//var sync = PouchDB.sync('chatDB', 'http://172.20.10.4:5984/chatDB', {
2022-11-17 21:17:50 +00:00
live: true,
2022-12-26 19:41:58 +00:00
retry: false
2022-11-17 21:17:50 +00:00
}).on('change', function (change) {
// yo, something changed!
console.log(change)
2022-12-26 19:41:58 +00:00
}).on('paused', function (err) {
2022-11-17 21:17:50 +00:00
// replication was paused, usually because of a lost connection
2022-12-26 19:41:58 +00:00
console.log(err)
2022-11-17 21:17:50 +00:00
}).on('active', function (info) {
// replication was resumed
console.log(info)
}).on('error', function (err) {
// totally unhandled error (shouldn't happen)
2022-12-26 19:41:58 +00:00
console.log(err)
}).on('denied', function (err) {
// a document failed to replicate (e.g. due to permissions)
console.log(err)
}).on('complete', function (info) {
// handle complete;
console.log(info)
2022-11-17 21:17:50 +00:00
});
2022-12-26 19:41:58 +00:00
*/
2022-11-17 21:17:50 +00:00
2022-03-10 20:29:30 +00:00
var dxcallsigns = new Set();
2023-03-04 15:26:17 +00:00
//Set default chat filter
2023-02-20 17:55:21 +00:00
var chatFilter = [
{ type: "newchat" },
{ type: "received" },
{ type: "transmit" },
{ type: "ping-ack" },
2023-05-16 09:35:20 +00:00
{ type: "broadcast_received" },
{ type: "broadcast_transmit" },
2023-03-04 15:26:17 +00:00
//{ type: "request" },
//{ type: "response" },
2023-02-20 17:55:21 +00:00
];
2023-02-19 13:36:29 +00:00
2023-02-19 14:37:51 +00:00
updateAllChat(false);
2022-11-17 21:17:50 +00:00
2021-11-19 16:30:17 +00:00
// WINDOW LISTENER
2023-02-11 21:49:07 +00:00
window.addEventListener("DOMContentLoaded", () => {
// theme selector
2023-03-16 07:59:54 +00:00
changeGuiDesign(config.theme);
2023-02-11 21:49:07 +00:00
2023-02-19 14:59:38 +00:00
const userInfoFields = [
2023-02-26 09:48:21 +00:00
"user_info_image",
2023-02-19 14:59:38 +00:00
"user_info_callsign",
"user_info_gridsquare",
"user_info_name",
"user_info_age",
"user_info_location",
"user_info_radio",
"user_info_antenna",
"user_info_email",
"user_info_website",
"user_info_comments",
];
2023-02-18 18:55:13 +00:00
users
.find({
selector: {
2023-02-19 14:37:51 +00:00
user_info_callsign: config.mycall,
2023-02-18 18:55:13 +00:00
},
})
.then(function (result) {
2023-02-26 10:04:14 +00:00
console.log(result);
2023-02-20 17:55:21 +00:00
if (typeof result.docs[0] !== "undefined") {
// handle result
userInfoFields.forEach(function (elem) {
2023-02-26 10:04:14 +00:00
if (elem !== "user_info_image") {
document.getElementById(elem).value = result.docs[0][elem];
} else {
document.getElementById(elem).src = result.docs[0][elem];
}
2023-02-20 17:55:21 +00:00
});
2023-02-23 11:13:49 +00:00
} else {
2023-02-23 11:14:31 +00:00
console.log(
config.mycall + " not found in user db - creating new entry"
);
// add initial entry for own callsign and grid
let obj = new Object();
obj.user_info_callsign = config.mycall;
obj.user_info_gridsquare = config.mygrid;
addUserToDatabaseIfNotExists(obj);
2023-02-23 11:13:49 +00:00
2023-02-23 11:14:31 +00:00
document.getElementById("user_info_callsign").value = config.mycall;
document.getElementById("user_info_gridsquare").value = config.mygrid;
2023-02-19 14:59:38 +00:00
}
2023-02-18 18:55:13 +00:00
})
.catch(function (err) {
console.log(err);
});
2023-02-26 10:04:14 +00:00
//save user info
2023-02-26 09:48:21 +00:00
document.getElementById("userInfoSave").addEventListener("click", () => {
let obj = new Object();
2023-02-26 10:04:14 +00:00
userInfoFields.forEach(function (subelem) {
if (subelem !== "user_info_image") {
obj[subelem] = document.getElementById(subelem).value;
} else {
obj[subelem] = document.getElementById(subelem).src;
}
});
addUserToDatabaseIfNotExists(obj);
2023-02-18 18:55:13 +00:00
});
2023-02-19 07:06:28 +00:00
//Add event listener for filter apply button
2023-02-20 17:55:21 +00:00
document.getElementById("btnFilter").addEventListener("click", () => {
2023-06-18 18:57:18 +00:00
chatFilter.length=0;
if (document.getElementById("chkMessage").checked == true) {
chatFilter = [{ type: "newchat" }];
2023-02-20 17:55:21 +00:00
chatFilter.push({ type: "received" }, { type: "transmit" });
2023-06-18 18:57:18 +00:00
}
2023-02-20 17:55:21 +00:00
if (document.getElementById("chkPing").checked == true)
chatFilter.push({ type: "ping" });
if (document.getElementById("chkPingAck").checked == true)
chatFilter.push({ type: "ping-ack" });
if (document.getElementById("chkBeacon").checked == true)
chatFilter.push({ type: "beacon" });
2023-02-26 15:27:55 +00:00
if (document.getElementById("chkRequest").checked == true)
chatFilter.push({ type: "request" });
2023-02-26 15:27:55 +00:00
if (document.getElementById("chkResponse").checked == true)
chatFilter.push({ type: "response" });
2023-06-18 18:57:18 +00:00
if (document.getElementById("chkNewMessage").checked == true)
chatFilter.push({new:1});
2023-02-19 07:06:28 +00:00
updateAllChat(true);
});
2023-02-19 13:36:29 +00:00
2023-02-11 21:49:07 +00:00
document
.querySelector("emoji-picker")
.addEventListener("emoji-click", (event) => {
var msg = document.getElementById("chatModuleMessage");
//Convert to utf-8--so we can just use utf-8 everywhere
msg.setRangeText(event.detail.emoji.unicode.toString("utf-8"));
//console.log(event.detail);
//msg.focus();
});
document.getElementById("emojipickerbutton").addEventListener("click", () => {
var element = document.getElementById("emojipickercontainer");
console.log(element.style.display);
if (element.style.display === "none") {
element.style.display = "block";
} else {
element.style.display = "none";
2022-04-03 13:26:24 +00:00
}
2023-02-11 21:49:07 +00:00
});
2023-02-11 21:49:07 +00:00
document
.getElementById("delete_selected_chat")
.addEventListener("click", () => {
db.find({
selector: {
dxcallsign: selected_callsign,
},
})
.then(function (result) {
// handle result
if (typeof result !== "undefined") {
result.docs.forEach(function (item) {
console.log(item);
db.get(item._id)
.then(function (doc) {
db.remove(doc)
.then(function (doc) {
return location.reload();
})
.catch(function (err) {
console.log(err);
2022-03-29 20:24:35 +00:00
});
2023-02-11 21:49:07 +00:00
})
.catch(function (err) {
console.log(err);
2022-03-29 20:24:35 +00:00
});
2023-02-11 21:49:07 +00:00
});
}
})
.catch(function (err) {
console.log(err);
2022-03-29 20:24:35 +00:00
});
2023-02-11 21:49:07 +00:00
});
document.getElementById("selectFilesButton").addEventListener("click", () => {
//document.getElementById('selectFiles').click();
ipcRenderer.send("select-file", {
title: "Title",
});
});
2022-11-08 18:53:14 +00:00
2023-02-26 13:08:26 +00:00
document.getElementById("requestUserInfo").addEventListener("click", () => {
ipcRenderer.send("run-tnc-command", {
command: "requestUserInfo",
dxcallsign: selected_callsign,
});
2023-02-26 16:54:21 +00:00
2023-02-28 19:37:55 +00:00
pauseButton(document.getElementById("requestUserInfo"), 60000);
2023-02-26 13:08:26 +00:00
});
2023-02-11 21:49:07 +00:00
document.getElementById("ping").addEventListener("click", () => {
ipcRenderer.send("run-tnc-command", {
command: "ping",
dxcallsign: selected_callsign,
});
});
2022-11-08 18:53:14 +00:00
2023-02-11 21:49:07 +00:00
document.addEventListener("keyup", function (event) {
// Number 13 == Enter
2023-02-20 17:55:21 +00:00
if (
event.keyCode === 13 &&
!event.shiftKey &&
document.activeElement.id == "chatModuleMessage"
2023-02-19 14:37:51 +00:00
) {
2023-02-11 21:49:07 +00:00
// Cancel the default action, if needed
event.preventDefault();
// Trigger the button element with a click
document.getElementById("sendMessage").click();
}
});
2022-11-08 18:53:14 +00:00
2023-02-11 21:49:07 +00:00
// ADJUST TEXTAREA SIZE
document.getElementById("chatModuleMessage").addEventListener("input", () => {
var textarea = document.getElementById("chatModuleMessage");
var text = textarea.value;
2022-11-08 18:53:14 +00:00
2023-02-11 21:49:07 +00:00
if (document.getElementById("expand_textarea").checked) {
var lines = 6;
} else {
var lines = text.split("\n").length;
2022-11-08 18:53:14 +00:00
2023-02-11 21:49:07 +00:00
if (lines >= 6) {
lines = 6;
}
}
var message_container_height_offset = 130 + 20 * lines;
var message_container_height = `calc(100% - ${message_container_height_offset}px)`;
document.getElementById("message-container").style.height =
message_container_height;
textarea.rows = lines;
console.log(textarea.value);
if (lastIsWritingBroadcast < new Date().getTime() - 5 * 2000) {
2023-02-12 23:15:12 +00:00
//console.log("Sending FECIsWriting");
2023-02-14 15:00:34 +00:00
console.log(config.enable_is_writing);
if (config.enable_is_writing == "True") {
2023-02-14 15:00:10 +00:00
ipcRenderer.send("tnc-fec-iswriting");
}
2023-02-12 23:15:12 +00:00
lastIsWritingBroadcast = new Date().getTime();
}
2023-02-11 21:49:07 +00:00
});
document.getElementById("expand_textarea").addEventListener("click", () => {
var textarea = document.getElementById("chatModuleMessage");
if (document.getElementById("expand_textarea").checked) {
var lines = 6;
document.getElementById("expand_textarea_button").className =
"bi bi-chevron-compact-down";
} else {
var lines = 1;
document.getElementById("expand_textarea_button").className =
"bi bi-chevron-compact-up";
}
2023-02-11 21:49:07 +00:00
var message_container_height_offset = 130 + 20 * lines;
//var message_container_height_offset = 90 + (23*lines);
var message_container_height = `calc(100% - ${message_container_height_offset}px)`;
document.getElementById("message-container").style.height =
message_container_height;
textarea.rows = lines;
console.log(textarea.rows);
});
// NEW CHAT
document
.getElementById("createNewChatButton")
.addEventListener("click", () => {
var dxcallsign = document.getElementById("chatModuleNewDxCall").value;
var uuid = uuidv4();
db.post({
_id: uuid,
timestamp: Math.floor(Date.now() / 1000),
dxcallsign: dxcallsign.toUpperCase(),
dxgrid: "---",
msg: "null",
checksum: "null",
type: "newchat",
status: "null",
uuid: uuid,
})
.then(function (response) {
// handle response
console.log("new database entry");
console.log(response);
})
.catch(function (err) {
console.log(err);
});
2023-02-11 21:49:07 +00:00
update_chat_obj_by_uuid(uuid);
});
2022-06-07 09:31:59 +00:00
2023-02-25 22:24:28 +00:00
// open file selector for user image
document.getElementById("userImageSelector").addEventListener("click", () => {
ipcRenderer.send("select-user-image", {
2023-02-25 22:23:59 +00:00
title: "Title",
});
2023-02-25 22:24:28 +00:00
});
2023-02-25 22:23:59 +00:00
// open file selector for shared folder
2023-02-28 12:55:54 +00:00
document
.getElementById("sharedFolderButton")
.addEventListener("click", () => {
ipcRenderer.send("read-files-in-folder", {
folder: config.shared_folder_path,
});
});
document
.getElementById("openSharedFilesFolder")
.addEventListener("click", () => {
ipcRenderer.send("open-folder", {
path: config.shared_folder_path,
});
});
2023-02-28 14:20:17 +00:00
document
.getElementById("requestSharedFolderList")
.addEventListener("click", () => {
2023-02-28 14:20:17 +00:00
ipcRenderer.send("run-tnc-command", {
command: "requestSharedFolderList",
dxcallsign: selected_callsign,
});
2023-02-28 19:37:55 +00:00
pauseButton(document.getElementById("requestSharedFolderList"), 60000);
});
2023-02-11 21:49:07 +00:00
// SEND MSG
document.getElementById("sendMessage").addEventListener("click", () => {
document.getElementById("emojipickercontainer").style.display = "none";
var dxcallsign = selected_callsign.toUpperCase();
var textarea = document.getElementById("chatModuleMessage");
var chatmessage = textarea.value;
//Remove non-printable chars from begining and end of string--should save us a byte here and there
chatmessage = chatmessage.toString().trim();
// reset textarea size
var message_container_height_offset = 150;
var message_container_height = `calc(100% - ${message_container_height_offset}px)`;
document.getElementById("message-container").style.height =
message_container_height;
textarea.rows = 1;
document.getElementById("expand_textarea_button").className =
"bi bi-chevron-compact-up";
document.getElementById("expand_textarea").checked = false;
//console.log(file);
//console.log(filename);
//console.log(filetype);
2023-02-11 21:49:07 +00:00
if (filetype == "") {
filetype = "plain/text";
}
var timestamp = Math.floor(Date.now() / 1000);
2023-05-15 17:10:56 +00:00
var uuid = uuidv4();
let uuidlast = uuid.lastIndexOf("-");
uuidlast += 1;
if (uuidlast > 0) {
uuid = uuid.substring(uuidlast);
}
2023-05-15 16:56:21 +00:00
// check if broadcast
2023-05-14 17:45:07 +00:00
if (dxcallsign.startsWith("BC-")) {
2023-05-15 16:56:21 +00:00
//let broadcastChannelId = dxcallsign.split("BC-")[1];
//broadcastChannelIdCRC = crc32(broadcastChannelId)
// .toString(16)
// .toUpperCase();
//dxcallsignWithID = "BC-" + broadcastChannelIdCRC;
2023-05-14 17:45:07 +00:00
var tnc_command = "broadcast";
2023-05-15 17:10:56 +00:00
var message_type = "broadcast_transmit";
2023-05-17 09:05:24 +00:00
2023-05-17 09:06:07 +00:00
// slice uuid for reducing overhead
uuid = uuid.slice(-4);
2023-05-17 09:05:24 +00:00
let Data = {
2023-05-14 17:45:07 +00:00
command: tnc_command,
broadcastChannel: dxcallsign,
data: chatmessage,
2023-05-15 17:10:56 +00:00
uuid: uuid,
2023-05-14 17:45:07 +00:00
};
ipcRenderer.send("run-tnc-command", Data);
} else {
2023-05-15 17:10:56 +00:00
var message_type = "transmit";
2023-05-14 17:45:07 +00:00
var file_checksum = crc32(file).toString(16).toUpperCase();
var tnc_command = "msg";
var data_with_attachment =
timestamp +
split_char +
chatmessage +
split_char +
filename +
split_char +
filetype +
split_char +
file;
document.getElementById("selectFilesButton").innerHTML = ``;
2023-05-15 16:56:21 +00:00
2023-05-14 17:45:07 +00:00
console.log(data_with_attachment);
let Data = {
command: tnc_command,
dxcallsign: dxcallsign,
mode: 255,
frames: 5,
data: data_with_attachment,
checksum: file_checksum,
uuid: uuid,
};
ipcRenderer.send("run-tnc-command", Data);
}
2023-02-11 21:49:07 +00:00
db.post({
_id: uuid,
timestamp: timestamp,
dxcallsign: dxcallsign,
dxgrid: "null",
msg: chatmessage,
checksum: file_checksum,
2023-05-15 16:56:21 +00:00
type: message_type,
2023-02-11 21:49:07 +00:00
status: "transmit",
2023-05-09 08:35:50 +00:00
attempt: 1,
2023-02-11 21:49:07 +00:00
uuid: uuid,
_attachments: {
[filename]: {
content_type: filetype,
//data: btoa(file)
data: FD.btoa_FD(file),
2023-02-11 21:49:07 +00:00
},
},
2021-11-19 16:30:17 +00:00
})
2023-02-11 21:49:07 +00:00
.then(function (response) {
// handle response
console.log("new database entry");
console.log(response);
})
.catch(function (err) {
console.log(err);
});
update_chat_obj_by_uuid(uuid);
// clear input
document.getElementById("chatModuleMessage").value = "";
// after adding file data to our attachment variable, delete it from global
filetype = "";
file = "";
filename = "";
});
// cleanup after transmission
filetype = "";
file = "";
filename = "";
});
2023-02-11 21:49:07 +00:00
ipcRenderer.on("return-selected-files", (event, arg) => {
filetype = arg.mime;
console.log(filetype);
2023-02-11 21:49:07 +00:00
file = arg.data;
filename = arg.filename;
document.getElementById("selectFilesButton").innerHTML = `
2022-04-03 13:26:24 +00:00
<span class="position-absolute top-0 start-85 translate-middle p-2 bg-danger border border-light rounded-circle">
<span class="visually-hidden">New file selected</span>
2023-02-18 18:55:13 +00:00
</span>
`;
});
2023-02-25 22:23:59 +00:00
ipcRenderer.on("return-shared-folder-files", (event, arg) => {
2023-02-28 12:55:54 +00:00
console.log(arg);
2023-02-28 14:20:17 +00:00
sharedFolderFileList = arg.files;
var tbl = document.getElementById("sharedFolderTable");
2023-03-04 16:12:28 +00:00
if (tbl == undefined) return;
tbl.innerHTML = "";
2023-02-28 12:55:54 +00:00
let counter = 0;
arg.files.forEach((file) => {
2023-03-19 15:18:32 +00:00
//console.log(file["name"]);
2023-02-28 12:55:54 +00:00
var row = document.createElement("tr");
let id = document.createElement("td");
let idText = document.createElement("span");
idText.innerText = counter += 1;
id.appendChild(idText);
row.appendChild(id);
let filename = document.createElement("td");
let filenameText = document.createElement("span");
filenameText.innerText = file["name"];
filename.appendChild(filenameText);
row.appendChild(filename);
let filetype = document.createElement("td");
let filetypeText = document.createElement("span");
filetypeText.innerHTML = `
<i class="bi bi-filetype-${file["extension"]}" style="font-size: 1.8rem"></i>
`;
2023-02-28 12:55:54 +00:00
filetype.appendChild(filetypeText);
row.appendChild(filetype);
2023-02-28 12:55:54 +00:00
let filesize = document.createElement("td");
let filesizeText = document.createElement("span");
2023-03-04 12:24:37 +00:00
filesizeText.innerText = formatBytes(file["size"], 2);
2023-02-28 12:55:54 +00:00
filesize.appendChild(filesizeText);
row.appendChild(filesize);
2023-02-28 12:55:54 +00:00
tbl.appendChild(row);
});
});
2023-02-25 22:23:59 +00:00
ipcRenderer.on("return-select-user-image", (event, arg) => {
2023-02-26 07:48:51 +00:00
let imageFiletype = arg.mime;
let imageFile = arg.data;
2023-02-25 22:23:59 +00:00
2023-02-26 07:49:19 +00:00
imageFile = blobUtil.base64StringToBlob(imageFile, imageFiletype);
2023-02-25 22:23:59 +00:00
var options = {
2023-02-26 17:31:11 +00:00
maxSizeMB: 0.01,
2023-02-26 17:30:52 +00:00
maxWidthOrHeight: 125,
2023-02-26 07:48:51 +00:00
useWebWorker: false,
2023-02-25 22:24:28 +00:00
};
2023-02-25 22:23:59 +00:00
imageCompression(imageFile, options)
.then(function (compressedFile) {
2023-02-25 22:24:28 +00:00
console.log(
"compressedFile instanceof Blob",
compressedFile instanceof Blob
); // true
console.log(
`compressedFile size ${compressedFile.size / 1024 / 1024} MB`
); // smaller than maxSizeMB
2023-02-25 22:23:59 +00:00
console.log(compressedFile.size);
2023-02-26 08:18:13 +00:00
2023-02-26 08:22:38 +00:00
blobUtil
.blobToBase64String(compressedFile)
.then(function (base64String) {
2023-02-26 08:18:13 +00:00
// update image
2023-02-26 09:48:21 +00:00
document.getElementById("user_info_image").src =
2023-02-26 08:22:38 +00:00
"data:" + imageFiletype + ";base64," + base64String;
})
.catch(function (err) {
2023-02-26 09:48:21 +00:00
document.getElementById("user_info_image").src = "img/icon.png";
2023-02-26 08:18:13 +00:00
});
2023-02-25 22:23:59 +00:00
})
.catch(function (error) {
console.log(error.message);
});
});
2023-05-27 09:28:07 +00:00
ipcRenderer.on("action-update-reception-status", (event, arg) => {
var data = arg["data"][0];
document.getElementById("txtConnectedWithChat").textContent = data.dxcallsign;
});
ipcRenderer.on("action-clear-reception-status", (event) => {
//Clear connected with textbox
let cwc = document.getElementById("txtConnectedWithChat");
if (cwc.textContent != "------") {
cwc.textContent = "------";
//console.log("Reseting connected with");
}
});
2023-05-27 09:28:07 +00:00
2023-02-11 21:49:07 +00:00
ipcRenderer.on("action-update-transmission-status", (event, arg) => {
var data = arg["data"][0];
2023-05-27 09:28:07 +00:00
document.getElementById("txtConnectedWithChat").textContent = data.dxcallsign;
2023-02-11 21:49:07 +00:00
console.log(data.status);
2023-02-27 17:10:11 +00:00
if (data.uuid !== "no-uuid") {
db.get(data.uuid, {
attachments: true,
})
.then(function (doc) {
return db.put({
_id: doc.uuid.toString(),
_rev: doc._rev,
timestamp: doc.timestamp,
dxcallsign: doc.dxcallsign,
dxgrid: doc.dxgrid,
msg: doc.msg,
checksum: doc.checksum,
type: "transmit",
status: data.status,
percent: data.percent,
bytesperminute: data.bytesperminute,
uuid: doc.uuid,
_attachments: doc._attachments,
});
2023-02-27 17:10:11 +00:00
})
.then(function (response) {
update_chat_obj_by_uuid(data.uuid);
})
.catch(function (err) {
console.log(err);
console.log(data);
});
}
2022-03-10 20:29:30 +00:00
});
//Render is typing message in correct chat window
2023-02-14 03:50:05 +00:00
ipcRenderer.on("action-show-feciswriting", (event, arg) => {
//console.log("In action-show-feciswriting");
//console.log(arg);
let uuid = uuidv4.toString();
let dxcallsign = arg["data"][0]["dxcallsign"];
var new_message = `
<div class="m-auto mt-1 p-0 w-25 rounded bg-secondary bg-gradient" id="msg-${uuid}">
<p class="text-white mb-0 text-break" style="font-size: 0.7rem;"><i class="m-1 bi bi-pencil"></i><i id="msg-${uuid}-icon" class="m-1 bi bi-wifi-1"></i>${dxcallsign} is typing....</p>
2023-02-18 18:55:13 +00:00
</div>
`;
var id = "chat-" + dxcallsign;
let chatwin = document.getElementById(id);
if (chatwin == undefined) {
//console.log("Element not found!!!!! :(");
return;
}
chatwin.insertAdjacentHTML("beforeend", new_message);
scrollMessagesToBottom();
let animIcon = document.getElementById("msg-" + uuid + "-icon");
//Remove notification after about 4.5 seconds hopefully enough time before a second notification can come in
setTimeout(function () {
2023-02-14 03:50:05 +00:00
animIcon.classList = "m-1 bi bi-wifi-2";
}, 1000);
setTimeout(function () {
2023-02-14 03:50:05 +00:00
animIcon.classList = "m-1 bi bi-wifi";
}, 2000);
setTimeout(function () {
2023-02-14 03:50:05 +00:00
animIcon.classList = "m-1 bi bi-wifi-2";
}, 3000);
setTimeout(function () {
2023-02-14 03:50:05 +00:00
animIcon.classList = "m-1 bi bi-wifi-1";
}, 4000);
setTimeout(() => {
2023-02-14 03:50:05 +00:00
let feciw = document.getElementById("msg-" + uuid);
feciw.remove();
}, 4500);
});
2023-02-11 21:49:07 +00:00
ipcRenderer.on("action-new-msg-received", (event, arg) => {
console.log(arg.data);
var new_msg = arg.data;
new_msg.forEach(function (item) {
let obj = new Object();
//handle broadcast
if (item.fec == "broadcast") {
2023-05-15 08:13:33 +00:00
console.log("BROADCAST RECEIVED");
console.log(item);
2023-05-15 08:04:41 +00:00
var transmitting_station = item.dxcallsign;
var encoded_data = FD.atob_FD(item.data);
var splitted_data = encoded_data.split(split_char);
console.log(splitted_data);
2023-05-17 09:31:56 +00:00
console.log(transmitting_station);
2023-05-15 08:04:41 +00:00
// add callsign to message:
2023-05-17 09:30:22 +00:00
var message = splitted_data[3];
2023-05-15 08:13:33 +00:00
console.log(message);
obj.timestamp = Math.floor(Date.now() / 1000);
2023-05-15 08:04:41 +00:00
obj.dxcallsign = splitted_data[1];
2023-05-14 20:47:46 +00:00
obj.dxgrid = "null";
2023-05-17 09:30:22 +00:00
obj.uuid = splitted_data[2];
2023-05-16 16:21:57 +00:00
obj.broadcast_sender = transmitting_station;
obj.command = "msg";
obj.checksum = "null";
2023-05-15 08:04:41 +00:00
obj.msg = message;
obj.status = "received";
obj.snr = item.snr;
2023-05-15 16:56:21 +00:00
obj.type = "broadcast_received";
obj.filename = "null";
obj.filetype = "null";
obj.file = "null";
2023-06-27 20:43:52 +00:00
obj.new = 1;
2023-05-14 20:47:46 +00:00
console.log(obj);
add_obj_to_database(obj);
update_chat_obj_by_uuid(obj.uuid);
2023-05-16 09:35:50 +00:00
db.find({
selector: {
dxcallsign: obj.dxcallsign,
},
}).then(function (result) {
// handle result
console.log(result);
});
2023-05-16 09:35:20 +00:00
2023-05-14 20:47:46 +00:00
//handle ping
} else if (item.ping == "received") {
2023-02-11 21:49:07 +00:00
obj.timestamp = parseInt(item.timestamp);
obj.dxcallsign = item.dxcallsign;
obj.dxgrid = item.dxgrid;
obj.uuid = item.uuid;
obj.command = "ping";
obj.checksum = "null";
obj.msg = "null";
obj.status = item.status;
obj.snr = item.snr;
obj.type = "ping";
obj.filename = "null";
obj.filetype = "null";
obj.file = "null";
obj.new = 0;
2023-02-11 21:49:07 +00:00
add_obj_to_database(obj);
update_chat_obj_by_uuid(obj.uuid);
2023-06-14 22:03:10 +00:00
// handle ping-ack
2023-05-09 08:36:30 +00:00
} else if (item.ping == "acknowledge") {
2023-02-19 05:02:06 +00:00
obj.timestamp = parseInt(item.timestamp);
obj.dxcallsign = item.dxcallsign;
obj.dxgrid = item.dxgrid;
obj.uuid = item.uuid;
obj.command = "ping-ack";
obj.checksum = "null";
obj.msg = "null";
obj.status = item.status;
obj.snr = item.dxsnr + "/" + item.snr;
obj.type = "ping-ack";
obj.filename = "null";
obj.filetype = "null";
obj.file = "null";
obj.new = 0;
2023-02-19 05:02:06 +00:00
add_obj_to_database(obj);
update_chat_obj_by_uuid(obj.uuid);
2023-02-11 21:49:07 +00:00
// handle beacon
2023-05-09 08:36:30 +00:00
} else if (item.beacon == "received") {
2023-02-11 21:49:07 +00:00
obj.timestamp = parseInt(item.timestamp);
obj.dxcallsign = item.dxcallsign;
obj.dxgrid = item.dxgrid;
obj.uuid = item.uuid;
obj.command = "beacon";
obj.checksum = "null";
obj.msg = "null";
obj.status = item.status;
obj.snr = item.snr;
obj.type = "beacon";
obj.filename = "null";
obj.filetype = "null";
obj.file = "null";
obj.new = 0;
2023-02-11 21:49:07 +00:00
add_obj_to_database(obj);
update_chat_obj_by_uuid(obj.uuid);
// handle ARQ transmission
2023-05-09 08:36:30 +00:00
} else if (item.arq == "transmission" && item.status == "received") {
2023-02-11 21:49:07 +00:00
//var encoded_data = atob(item.data);
//var encoded_data = Buffer.from(item.data,'base64').toString('utf-8');
var encoded_data = FD.atob_FD(item.data);
2023-02-11 21:49:07 +00:00
var splitted_data = encoded_data.split(split_char);
console.log(splitted_data);
2023-02-26 15:27:55 +00:00
if (splitted_data[1] == "msg") {
obj.timestamp = parseInt(splitted_data[4]);
obj.dxcallsign = item.dxcallsign;
obj.dxgrid = item.dxgrid;
obj.command = splitted_data[1];
obj.checksum = splitted_data[2];
obj.uuid = splitted_data[3];
obj.msg = splitted_data[5];
obj.status = "null";
obj.snr = "null";
obj.type = "received";
obj.filename = splitted_data[6];
obj.filetype = splitted_data[7];
//obj.file = btoa(splitted_data[8]);
obj.file = FD.btoa_FD(splitted_data[8]);
obj.new=1;
2023-05-09 08:36:30 +00:00
} else if (splitted_data[1] == "req" && splitted_data[2] == "0") {
2023-02-26 15:27:55 +00:00
obj.uuid = uuidv4().toString();
obj.timestamp = Math.floor(Date.now() / 1000);
obj.dxcallsign = item.dxcallsign;
obj.command = splitted_data[1];
obj.type = "request";
obj.status = "received";
obj.snr = "null";
2023-03-05 21:16:03 +00:00
obj.msg = "Request for station info";
2023-02-26 15:27:55 +00:00
obj.filename = "null";
obj.filetype = "null";
obj.file = "null";
obj.new=0;
2023-02-28 12:55:54 +00:00
if (config.enable_request_profile == "True") {
sendUserData(item.dxcallsign);
}
2023-05-09 08:36:30 +00:00
} else if (splitted_data[1] == "req" && splitted_data[2] == "1") {
obj.uuid = uuidv4().toString();
obj.timestamp = Math.floor(Date.now() / 1000);
obj.dxcallsign = item.dxcallsign;
obj.command = splitted_data[1];
obj.type = "request";
obj.status = "received";
obj.snr = "null";
2023-03-05 21:16:03 +00:00
obj.msg = "Request for shared folder list";
obj.filename = "null";
obj.filetype = "null";
obj.file = "null";
obj.new=0;
if (config.enable_request_shared_folder == "True") {
sendSharedFolderList(item.dxcallsign);
}
2023-05-09 08:36:30 +00:00
} else if (
splitted_data[1] == "req" &&
splitted_data[2].substring(0, 1) == "2"
) {
2023-03-05 21:16:03 +00:00
let name = splitted_data[2].substring(1);
//console.log("In handle req for shared folder file");
obj.uuid = uuidv4().toString();
obj.timestamp = Math.floor(Date.now() / 1000);
obj.dxcallsign = item.dxcallsign;
obj.command = splitted_data[1];
obj.type = "request";
obj.status = "received";
obj.snr = "null";
2023-03-05 21:16:03 +00:00
obj.msg = "Request for shared file " + name;
obj.filename = "null";
obj.filetype = "null";
obj.file = "null";
obj.new=0;
if (config.enable_request_shared_folder == "True") {
2023-03-05 21:16:43 +00:00
sendSharedFolderFile(item.dxcallsign, name);
}
2023-05-09 08:36:30 +00:00
} else if (splitted_data[1] == "res-0") {
2023-02-26 15:27:55 +00:00
obj.uuid = uuidv4().toString();
obj.timestamp = Math.floor(Date.now() / 1000);
obj.dxcallsign = item.dxcallsign;
obj.command = splitted_data[1];
obj.type = "response";
obj.status = "received";
obj.snr = "null";
2023-03-05 21:16:03 +00:00
obj.msg = "Response for station info";
2023-02-26 15:27:55 +00:00
obj.filename = "null";
obj.filetype = "null";
obj.file = "null";
obj.new=0;
2023-02-26 15:27:55 +00:00
console.log(splitted_data);
let userData = new Object();
userData.user_info_image = splitted_data[2];
2023-02-27 14:18:17 +00:00
userData.user_info_callsign = splitted_data[3];
userData.user_info_gridsquare = splitted_data[4];
userData.user_info_name = splitted_data[5];
userData.user_info_age = splitted_data[6];
userData.user_info_location = splitted_data[7];
userData.user_info_radio = splitted_data[8];
userData.user_info_antenna = splitted_data[9];
userData.user_info_email = splitted_data[10];
userData.user_info_website = splitted_data[11];
userData.user_info_comments = splitted_data[12];
addUserToDatabaseIfNotExists(userData);
2023-03-19 16:22:55 +00:00
getSetUserInformation(splitted_data[3]);
2023-05-09 08:36:30 +00:00
} else if (splitted_data[1] == "res-1") {
obj.uuid = uuidv4().toString();
obj.timestamp = Math.floor(Date.now() / 1000);
obj.dxcallsign = item.dxcallsign;
obj.command = splitted_data[1];
obj.type = "response";
obj.status = "received";
obj.snr = "null";
2023-03-05 21:16:03 +00:00
obj.msg = "Response for shared file list";
obj.filename = "null";
obj.filetype = "null";
obj.file = "null";
obj.new=0;
2023-02-28 14:20:17 +00:00
console.log(splitted_data);
2023-02-28 19:06:39 +00:00
let userData = new Object();
userData.user_info_callsign = obj.dxcallsign;
2023-02-28 19:06:39 +00:00
let filelist = JSON.parse(splitted_data[3]);
2023-02-28 14:20:17 +00:00
console.log(filelist);
2023-02-28 19:07:10 +00:00
userData.user_shared_folder = filelist;
addFileListToUserDatabaseIfNotExists(userData);
2023-03-19 15:32:57 +00:00
getSetUserSharedFolder(obj.dxcallsign);
2023-03-19 15:18:32 +00:00
//getSetUserInformation(selected_callsign);
2023-05-09 08:36:30 +00:00
} else if (splitted_data[1] == "res-2") {
2023-03-05 21:16:03 +00:00
console.log("In received respons-2");
2023-03-05 21:16:43 +00:00
let sharedFileInfo = splitted_data[2].split("/", 2);
2023-03-05 21:16:03 +00:00
obj.uuid = uuidv4().toString();
obj.timestamp = Math.floor(Date.now() / 1000);
obj.dxcallsign = item.dxcallsign;
obj.command = splitted_data[1];
obj.type = "received";
obj.status = "received";
obj.snr = "null";
obj.msg = "Response for shared file download";
obj.filename = sharedFileInfo[0];
obj.filetype = "application/octet-stream";
obj.file = FD.btoa_FD(sharedFileInfo[1]);
obj.new=0;
2023-05-09 08:36:30 +00:00
} else {
console.log("no rule matched for handling received data!");
}
2023-02-11 21:49:07 +00:00
add_obj_to_database(obj);
update_chat_obj_by_uuid(obj.uuid);
}
});
//window.location = window.location;
2022-03-10 20:29:30 +00:00
});
2022-06-07 09:31:59 +00:00
2022-03-10 20:29:30 +00:00
// Update chat list
2023-02-11 21:49:07 +00:00
update_chat = function (obj) {
var dxcallsign = obj.dxcallsign;
var timestamp = dateFormat.format(obj.timestamp * 1000);
2023-02-24 03:42:57 +00:00
//var timestampShort = dateFormatShort.format(obj.timestamp * 1000);
2023-02-11 21:49:07 +00:00
var timestampHours = dateFormatHours.format(obj.timestamp * 1000);
var dxgrid = obj.dxgrid;
2023-05-09 12:45:58 +00:00
// check if obj.attempt exists
2023-05-09 12:49:46 +00:00
if (typeof obj.attempt == "undefined") {
db.upsert(obj._id, function (doc) {
if (!doc.attempt) {
doc.attempt = 1;
}
return doc;
});
obj.attempt = 1;
}
2023-05-09 12:45:58 +00:00
2023-05-09 08:36:30 +00:00
// define attempts
2023-05-09 08:35:50 +00:00
if (typeof obj.attempt == "undefined") {
2023-05-09 08:36:30 +00:00
var attempt = 1;
2023-05-09 08:35:50 +00:00
} else {
2023-05-09 08:36:30 +00:00
var attempt = obj.attempt;
2023-05-09 08:35:50 +00:00
}
2023-05-09 10:27:51 +00:00
2023-05-27 04:38:30 +00:00
// add percent and bytes per minute if not existing
//console.log(obj.percent)
2023-05-27 04:38:30 +00:00
if (typeof obj.percent == "undefined") {
obj.percent = 0;
obj.bytesperminute = 0;
}
2023-05-27 04:54:02 +00:00
// check if wrong status message
if (obj.status == "transmit" && obj.percent == 0) {
var TimeDifference = (new Date().getTime()/1000) - obj.timestamp
if (TimeDifference > 3600){
db.upsert(obj._id, function (doc) {
if (!doc.status) {
doc.status = "failed";
}
return doc;
});
obj.status = "failed";
}
}
if (typeof obj.new == "undefined"){
obj.new=0;
}
2023-05-09 10:27:51 +00:00
if (typeof config.max_retry_attempts == "undefined") {
var max_retry_attempts = 3;
} else {
var max_retry_attempts = parseInt(config.max_retry_attempts);
}
//console.log(obj.msg);
2023-02-11 21:49:07 +00:00
// define shortmessage
if (obj.msg == "null" || obj.msg == "NULL") {
var shortmsg = obj.type;
} else {
var shortmsg = obj.msg;
var maxlength = 30;
var shortmsg =
shortmsg.length > maxlength
? shortmsg.substring(0, maxlength - 3) + "..."
: shortmsg;
}
try {
//console.log(Object.keys(obj._attachments)[0].length)
if (
typeof obj._attachments !== "undefined" &&
Object.keys(obj._attachments)[0].length > 0
) {
//var filename = obj._attachments;
var filename = Object.keys(obj._attachments)[0];
var filetype = filename.split(".")[1];
var filesize = obj._attachments[filename]["length"] + " Bytes";
if (filesize == "undefined Bytes") {
// get filesize of new submitted data
// not that nice....
// we really should avoid converting back from base64 for performance reasons...
//var filesize = Math.ceil(atob(obj._attachments[filename]["data"]).length) + "Bytes";
var filesize =
Math.ceil(FD.atob_FD(obj._attachments[filename]["data"]).length) +
2023-02-11 21:49:07 +00:00
" Bytes";
}
// check if image, then display it
if (filetype == "image/png" || filetype == "png") {
var fileheader = `
2022-11-11 14:10:31 +00:00
<div class="card-header border-0 bg-transparent text-end p-0 mb-0 hover-overlay">
<img class="w-100 rounded-2" src="data:image/png;base64,${FD.atob(
2023-02-24 03:44:24 +00:00
obj._attachments[filename]["data"]
)}">
<p class="text-right mb-0 p-1" style="text-align: right; font-size : 1rem">
2022-11-11 14:10:31 +00:00
<span class="p-1" style="text-align: right; font-size : 0.8rem">${filename}</span>
<span class="p-1" style="text-align: right; font-size : 0.8rem">${filesize}</span>
<i class="bi bi-filetype-${filetype}" style="font-size: 2rem;"></i>
</p>
</div>
<hr class="m-0 p-0">
`;
2023-02-11 21:49:07 +00:00
} else {
var fileheader = `
<div class="card-header border-0 bg-transparent text-end p-0 mb-0 hover-overlay">
<p class="text-right mb-0 p-1" style="text-align: right; font-size : 1rem">
<span class="p-1" style="text-align: right; font-size : 0.8rem">${filename}</span>
<span class="p-1" style="text-align: right; font-size : 0.8rem">${filesize}</span>
2022-11-11 14:10:31 +00:00
<i class="bi bi-filetype-${filetype}" style="font-size: 2rem;"></i>
</p>
</div>
<hr class="m-0 p-0">
`;
2023-02-11 21:49:07 +00:00
}
2022-11-11 14:10:31 +00:00
2023-02-11 21:49:07 +00:00
var controlarea_transmit = `
<div class="ms-auto" id="msg-${obj._id}-control-area">
<button class="btn bg-transparent p-1 m-1"><i class="bi bi-arrow-repeat link-secondary" id="retransmit-msg-${obj._id}" style="font-size: 1.2rem;"></i></button>
<button class="btn bg-transparent p-1 m-1"><i class="bi bi-download link-secondary" id="save-file-msg-${obj._id}" style="font-size: 1.2rem;"></i></button>
<button class="btn bg-transparent p-1 m-1"><i class="bi bi-trash link-secondary" id="del-msg-${obj._id}" style="font-size: 1.2rem;"></i></button>
</div>
`;
2023-02-11 21:49:07 +00:00
var controlarea_receive = `
2023-02-18 18:55:13 +00:00
<div class="me-auto" id="msg-${obj._id}-control-area">
<button class="btn bg-transparent p-1 m-1"><i class="bi bi-download link-secondary" id="save-file-msg-${obj._id}" style="font-size: 1.2rem;"></i></button>
<button class="btn bg-transparent p-1 m-1"><i class="bi bi-trash link-secondary" id="del-msg-${obj._id}" style="font-size: 1.2rem;"></i></button>
</div>
2023-02-11 21:49:07 +00:00
`;
} else {
var filename = "";
var fileheader = "";
var filetype = "text/plain";
var controlarea_transmit = `
<div class="ms-auto" id="msg-${obj._id}-control-area">
<button class="btn bg-transparent p-1 m-1"><i class="bi bi-arrow-repeat link-secondary" id="retransmit-msg-${obj._id}" style="font-size: 1.2rem;"></i></button>
<button class="btn bg-transparent p-1 m-1"><i class="bi bi-trash link-secondary" id="del-msg-${obj._id}" style="font-size: 1.2rem;"></i></button>
</div>
`;
2023-02-19 02:02:13 +00:00
var controlarea_receive = `
<div class="float-start" id="msg-${obj._id}-control-area">
<button class="btn bg-transparent p-1 m-1"><i class="bi bi-trash link-secondary" id="del-msg-${obj._id}" style="font-size: 1.2rem;"></i></button>
2023-02-19 02:02:13 +00:00
</div>
`;
2023-02-11 21:49:07 +00:00
}
} catch (err) {
console.log("error with database parsing...");
console.log(err);
}
// CALLSIGN LIST
if (!document.getElementById("chat-" + dxcallsign + "-list")) {
// increment callsign counter
callsign_counter++;
dxcallsigns.add(dxcallsign);
2023-02-25 05:29:09 +00:00
if (
(callsign_counter == 1 && selected_callsign == "") ||
selected_callsign == dxcallsign
) {
2023-02-11 21:49:07 +00:00
var callsign_selected = "active show";
//document.getElementById('chatModuleDxCall').value = dxcallsign;
selected_callsign = dxcallsign;
2022-03-27 19:04:04 +00:00
}
2023-02-11 21:49:07 +00:00
2023-05-16 17:08:31 +00:00
if (dxcallsign.startsWith("BC-")) {
var user_image =
'<img id="user-image-' +
dxcallsign +
'" class="p-1 rounded-circle" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iY3VycmVudENvbG9yIiBjbGFzcz0iYmkgYmktcGVvcGxlLWZpbGwiIHZpZXdCb3g9IjAgMCAxNiAxNiI+CiAgPHBhdGggZD0iTTcgMTRzLTEgMC0xLTEgMS00IDUtNCA1IDMgNSA0LTEgMS0xIDFIN1ptNC02YTMgMyAwIDEgMCAwLTYgMyAzIDAgMCAwIDAgNlptLTUuNzg0IDZBMi4yMzggMi4yMzggMCAwIDEgNSAxM2MwLTEuMzU1LjY4LTIuNzUgMS45MzYtMy43MkE2LjMyNSA2LjMyNSAwIDAgMCA1IDljLTQgMC01IDMtNSA0czEgMSAxIDFoNC4yMTZaTTQuNSA4YTIuNSAyLjUgMCAxIDAgMC01IDIuNSAyLjUgMCAwIDAgMCA1WiIvPgo8L3N2Zz4="></img>';
2023-05-16 16:21:57 +00:00
} else {
2023-05-16 17:08:31 +00:00
var user_image =
'<img id="user-image-' +
dxcallsign +
'" class="p-1 rounded-circle" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iY3VycmVudENvbG9yIiBjbGFzcz0iYmkgYmktcGVyc29uLWNpcmNsZSIgdmlld0JveD0iMCAwIDE2IDE2Ij4KICA8cGF0aCBkPSJNMTEgNmEzIDMgMCAxIDEtNiAwIDMgMyAwIDAgMSA2IDB6Ii8+CiAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMCA4YTggOCAwIDEgMSAxNiAwQTggOCAwIDAgMSAwIDh6bTgtN2E3IDcgMCAwIDAtNS40NjggMTEuMzdDMy4yNDIgMTEuMjI2IDQuODA1IDEwIDggMTBzNC43NTcgMS4yMjUgNS40NjggMi4zN0E3IDcgMCAwIDAgOCAxeiIvPgo8L3N2Zz4="></img>';
2023-05-16 16:21:57 +00:00
2023-05-16 17:08:31 +00:00
getSetUserInformation(dxcallsign);
getSetUserSharedFolder(dxcallsign);
2023-05-16 16:21:57 +00:00
}
2023-03-22 21:32:37 +00:00
2023-05-15 17:10:56 +00:00
var new_callsign = `
<a class="list-group-item list-group-item-action rounded-4 rounded-top rounded-bottom border-1 mb-2 ${callsign_selected}" id="chat-${dxcallsign}-list" data-bs-toggle="list" href="#chat-${dxcallsign}" role="tab" aria-controls="chat-${dxcallsign}">
2023-02-18 18:55:13 +00:00
2022-03-10 20:29:30 +00:00
<div class="d-flex w-100 justify-content-between">
<div class="rounded-circle p-0">
2023-05-16 16:21:57 +00:00
${user_image}
</div>
2022-04-02 16:40:12 +00:00
<span style="font-size:1.2rem;" ><strong id="chat-${dxcallsign}-list-displaydxcall">${dxcallsign}</strong></span>
2023-02-18 18:55:13 +00:00
<span class="badge bg-secondary text-white p-1 h-100" id="chat-${dxcallsign}-list-dxgrid"><small>${dxgrid}</small></span>
2022-04-02 16:40:12 +00:00
<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>
2022-03-10 20:29:30 +00:00
</div>
2022-04-02 16:40:12 +00:00
2022-03-10 20:29:30 +00:00
</a>
2022-03-10 20:29:30 +00:00
`;
2023-02-27 17:32:01 +00:00
2023-02-11 21:49:07 +00:00
document
.getElementById("list-tab")
.insertAdjacentHTML("beforeend", new_callsign);
var message_area = `
2023-02-18 18:55:13 +00:00
<div class="tab-pane fade ${callsign_selected}" id="chat-${dxcallsign}" role="tabpanel" aria-labelledby="chat-${dxcallsign}-list"></div>
2022-03-10 20:29:30 +00:00
`;
2023-02-11 21:49:07 +00:00
document
.getElementById("nav-tabContent")
.insertAdjacentHTML("beforeend", message_area);
2023-02-26 11:15:29 +00:00
2023-02-28 08:08:09 +00:00
// finally get and set user information to first selected item
getSetUserInformation(selected_callsign);
2023-03-22 21:32:37 +00:00
getSetUserSharedFolder(selected_callsign);
2023-02-28 08:07:38 +00:00
2023-02-11 21:49:07 +00:00
// create eventlistener for listening on clicking on a callsign
document
.getElementById("chat-" + dxcallsign + "-list")
.addEventListener("click", function () {
//document.getElementById('chatModuleDxCall').value = 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");
2023-02-11 21:49:07 +00:00
setTimeout(scrollMessagesToBottom, 200);
2023-02-26 11:15:29 +00:00
//get user information
getSetUserInformation(selected_callsign);
2023-03-22 21:32:37 +00:00
getSetUserSharedFolder(selected_callsign);
2023-02-11 21:49:07 +00:00
});
2022-04-02 16:40:12 +00:00
// if callsign entry already exists - update
2023-02-11 21:49:07 +00:00
} else {
// gridsquare - update only on receive
if (obj.type !== "transmit") {
document.getElementById("chat-" + dxcallsign + "-list-dxgrid").innerHTML =
dxgrid;
2022-03-10 20:29:30 +00:00
}
2023-02-11 21:49:07 +00:00
// time
document.getElementById("chat-" + dxcallsign + "-list-time").innerHTML =
timestampHours;
// short message
document.getElementById("chat-" + dxcallsign + "-list-shortmsg").innerHTML =
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");
}
2023-02-11 21:49:07 +00:00
}
// APPEND MESSAGES TO CALLSIGN
if (!document.getElementById("msg-" + obj._id)) {
if (obj.type == "ping") {
2023-05-09 10:27:51 +00:00
// check for messages which failed and try to transmit them
2023-05-09 10:29:28 +00:00
if (config.enable_auto_retry.toUpperCase() == "TRUE") {
checkForWaitingMessages(obj.dxcallsign);
}
//if (obj.new == 1)
//{
// showOsPopUp("Ping from " + obj.dxcallsign,"You've been ping'd!");
//}
2023-02-11 21:49:07 +00:00
var new_message = `
2023-02-18 18:55:13 +00:00
<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>
2023-02-19 05:02:06 +00:00
</div>
`;
}
if (obj.type == "ping-ack") {
var new_message = `
<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-check-lg"></i>Ping ack dx/mine snr: ${obj.snr} - ${timestamp} </p>
</div>
`;
2023-02-11 21:49:07 +00:00
}
if (obj.type == "beacon") {
2023-05-09 10:29:28 +00:00
// check for messages which failed and try to transmit them
if (config.enable_auto_retry.toUpperCase() == "TRUE") {
checkForWaitingMessages(obj.dxcallsign);
}
2023-02-11 21:49:07 +00:00
var new_message = `
2023-02-18 18:55:13 +00:00
<div class="p-0 rounded m-auto mt-1 w-50 bg-info bg-gradient" id="msg-${obj._id}">
<p class="text-small text-white text-break" style="font-size: 0.7rem;"><i class="m-3 bi bi-broadcast"></i>snr: ${obj.snr} - ${timestamp} </p>
</div>
`;
2023-02-11 21:49:07 +00:00
}
if (obj.type == "request") {
var new_message = `
<div class="p-0 rounded m-auto mt-1 w-50 bg-warning bg-gradient" id="msg-${obj._id}">
2023-03-05 21:16:03 +00:00
<p class="text-small text-white text-break" style="font-size: 0.7rem;"><i class="m-3 bi bi-info"></i>${obj.msg} - ${timestamp} </p>
</div>
`;
}
if (obj.type == "response") {
var new_message = `
<div class="p-0 rounded m-auto mt-1 w-50 bg-warning bg-gradient" id="msg-${obj._id}">
<p class="text-small text-white text-break" style="font-size: 0.7rem;"><i class="m-3 bi bi-info"></i>Response - ${timestamp} </p>
</div>
`;
}
2023-02-11 21:49:07 +00:00
if (obj.type == "newchat") {
var new_message = `
2023-02-18 18:55:13 +00:00
<div class="p-0 rounded m-auto mt-1 w-50 bg-light bg-gradient" id="msg-${obj._id}">
2022-04-10 17:20:58 +00:00
<p class="text-small text-dark text-break" style="font-size: 0.7rem;"><i class="m-3 bi bi-file-earmark-plus"></i> new chat opened - ${timestamp} </p>
</div>
`;
2023-02-11 21:49:07 +00:00
}
// CHECK FOR NEW LINE AND REPLACE WITH <br>
var message_html = obj.msg.replaceAll(/\n/g, "<br>");
if (obj.type == "received") {
2023-06-11 03:14:25 +00:00
if (obj.new == 1)
{
showOsPopUp("Message received from " + obj.dxcallsign,obj.msg);
}
2023-02-11 21:49:07 +00:00
var new_message = `
<div class="d-flex align-items-center" style="margin-left: auto;"> <!-- max-width: 75%; -->
2023-02-18 18:55:13 +00:00
<div class="mt-3 rounded-3 mb-0" style="max-width: 75%;" id="msg-${obj._id}">
<!--<p class="font-monospace text-small mb-0 text-muted text-break">${timestamp}</p>-->
<div class="card border-light bg-light" id="msg-${obj._id}">
${fileheader}
2023-02-18 18:55:13 +00:00
2022-11-10 12:02:17 +00:00
<div class="card-body rounded-3 p-0">
2022-04-03 13:26:24 +00:00
<p class="card-text p-2 mb-0 text-break text-wrap">${message_html}</p>
<p class="text-right mb-0 p-1 text-white" style="text-align: left; font-size : 0.9rem">
2023-02-18 18:55:13 +00:00
<span class="badge bg-light text-muted">${timestamp}</span>
</p>
</div>
</div>
</div>
2023-02-19 13:36:29 +00:00
${controlarea_receive}
2022-03-10 20:29:30 +00:00
</div>
`;
2023-02-11 21:49:07 +00:00
}
2023-05-15 08:04:41 +00:00
2023-05-15 16:56:21 +00:00
if (obj.type == "broadcast_received") {
2023-05-17 09:31:56 +00:00
console.log(obj);
2023-05-15 08:13:33 +00:00
var new_message = `
2023-05-15 16:56:21 +00:00
<div class="d-flex align-items-center" style="margin-left: auto;"> <!-- max-width: 75%; -->
<div class="mt-3 rounded-3 mb-0" style="max-width: 75%;" id="msg-${obj._id}">
<!--<p class="font-monospace text-small mb-0 text-muted text-break">${timestamp}</p>-->
<div class="card border-light bg-light" id="msg-${obj._id}">
<div class="card-body rounded-3 p-0">
<p class="card-text p-2 mb-0 text-break text-wrap">${message_html}</p>
<p class="text-right mb-0 p-1 text-white" style="text-align: left; font-size : 0.9rem">
<span class="badge bg-light text-muted">${timestamp}</span>
2023-05-15 08:04:41 +00:00
2023-05-15 16:56:21 +00:00
</p>
2023-05-16 16:21:57 +00:00
2023-05-16 17:08:31 +00:00
<span id="msg-${obj._id}-dxcallsign-badge" class="position-absolute top-0 start-100 translate-middle badge rounded-1 bg-secondary border border-white">
2023-05-16 16:21:57 +00:00
2023-05-16 17:08:31 +00:00
<span id="msg-${obj._id}-attempts" class="">${obj.broadcast_sender}</span>
2023-05-16 16:21:57 +00:00
<span class="visually-hidden">dxcallsign</span>
</span>
2023-05-15 16:56:21 +00:00
</div>
2023-05-15 08:04:41 +00:00
</div>
2023-05-15 16:56:21 +00:00
</div>
2023-05-17 08:37:10 +00:00
<div class="me-auto" id="msg-${obj._id}-control-area">
<button class="btn bg-transparent p-1 m-1"><i class="bi bi-trash link-secondary" id="del-msg-${obj._id}" style="font-size: 1.2rem;"></i></button>
</div>
2023-05-15 16:56:21 +00:00
</div>
`;
}
if (obj.type == "broadcast_transmit") {
var new_message = `
<div class="d-flex align-items-center">
<div class="ms-auto" id="msg-${obj._id}-control-area">
2023-05-15 17:10:56 +00:00
<!--<button class="btn bg-transparent p-1 m-1"><i class="bi bi-arrow-repeat link-secondary" id="retransmit-msg-${
obj._id
}" style="font-size: 1.2rem;"></i></button>-->
<button class="btn bg-transparent p-1 m-1"><i class="bi bi-trash link-secondary" id="del-msg-${
obj._id
}" style="font-size: 1.2rem;"></i></button>
2023-05-15 08:13:11 +00:00
</div>
2023-05-15 16:56:21 +00:00
<div class="rounded-3 mt-3 mb-0 me-2" style="max-width: 75%;">
<div class="card border-primary bg-primary" id="msg-${obj._id}">
<div class="card-body rounded-3 p-0 text-right bg-primary">
<p class="card-text p-1 mb-0 text-white text-break text-wrap">${message_html}</p>
<p class="text-right mb-0 p-1 text-white" style="text-align: right; font-size : 0.9rem">
<span class="text-light" style="font-size: 0.7rem;">${timestamp} - </span>
<span class="text-white" id="msg-${
obj._id
}-status" style="font-size:0.8rem;">${get_icon_for_state(
obj.status
)}</span>
</p>
<span id="msg-${
obj._id
}-attempts-badge" class="position-absolute top-0 start-100 translate-middle badge rounded-1 bg-primary border border-white">
<span id="msg-${
obj._id
}-attempts" class="">${attempt}/${max_retry_attempts}</span>
<span class="visually-hidden">retries</span>
</span>
</div>
</div>
</div>
`;
2023-05-15 08:13:33 +00:00
}
2023-05-15 16:56:21 +00:00
2023-02-11 21:49:07 +00:00
if (obj.type == "transmit") {
//console.log(obj);
2023-02-11 21:49:07 +00:00
//console.log('msg-' + obj._id + '-status')
if (obj.status == "failed") {
var progressbar_bg = "bg-danger";
2023-03-22 21:49:30 +00:00
var percent_value = "TRANSMISSION FAILED";
} else if (obj.status == "transmitted") {
var progressbar_bg = "bg-success";
var percent_value = "TRANSMITTED";
2023-02-11 21:49:07 +00:00
} else {
var progressbar_bg = "bg-primary";
2023-03-22 21:45:57 +00:00
var percent_value = obj.percent;
2023-02-11 21:49:07 +00:00
}
//Sneak in low graphics mode if so enabled for progress bars
if (config.high_graphics.toString().toUpperCase() != "TRUE") {
progressbar_bg += " disable-effects";
//console.log("Low graphics enabled for chat module");
}
2023-02-18 18:55:13 +00:00
2023-05-27 04:38:30 +00:00
2023-05-09 08:35:50 +00:00
var new_message = `
<div class="d-flex align-items-center">
${controlarea_transmit}
2023-05-09 08:35:50 +00:00
<div class="rounded-3 mt-3 mb-0 me-2" style="max-width: 75%;">
<div class="card border-primary bg-primary" id="msg-${obj._id}">
${fileheader}
2023-05-09 08:35:50 +00:00
<div class="card-body rounded-3 p-0 text-right bg-primary">
<p class="card-text p-1 mb-0 text-white text-break text-wrap">${message_html}</p>
<p class="text-right mb-0 p-1 text-white" style="text-align: right; font-size : 0.9rem">
<span class="text-light" style="font-size: 0.7rem;">${timestamp} - </span>
2023-05-09 10:29:28 +00:00
<span class="text-white" id="msg-${
obj._id
}-status" style="font-size:0.8rem;">${get_icon_for_state(
obj.status
)}</span>
</p>
2023-05-09 10:29:28 +00:00
<span id="msg-${
obj._id
}-attempts-badge" class="position-absolute top-0 start-100 translate-middle badge rounded-1 bg-primary border border-white">
2023-05-09 08:35:50 +00:00
2023-05-09 10:29:28 +00:00
<span id="msg-${
obj._id
}-attempts" class="">${attempt}/${max_retry_attempts}</span>
2023-05-09 08:35:50 +00:00
<span class="visually-hidden">retries</span>
</span>
<div class="progress p-0 m-0 rounded-0 rounded-bottom bg-secondary" style="height: 10px;">
2023-05-09 08:36:30 +00:00
<div class="progress-bar progress-bar-striped ${progressbar_bg} p-0 m-0 rounded-0 force-gpu" id="msg-${
obj._id
}-progress" role="progressbar" style="width: ${
obj.percent
}%;" aria-valuenow="${
obj.percent
}" aria-valuemin="0" aria-valuemax="100"></div>
2023-05-27 05:06:26 +00:00
<p class="justify-content-center d-flex position-absolute m-0 p-0 w-100 text-white ${progressbar_bg}" style="font-size: xx-small" id="msg-${
2023-05-09 08:36:30 +00:00
obj._id
}-progress-information">${percent_value} % - ${
obj.bytesperminute
} Bpm</p>
2023-05-09 08:35:50 +00:00
</div>
</div>
</div>
2023-05-09 08:35:50 +00:00
</div>
</div>
`;
2023-02-11 21:49:07 +00:00
}
// CHECK CHECK CHECK --> This could be done better
var id = "chat-" + obj.dxcallsign;
document.getElementById(id).insertAdjacentHTML("beforeend", new_message);
2022-06-09 12:11:39 +00:00
/* UPDATE EXISTING ELEMENTS */
2023-02-11 21:49:07 +00:00
} else if (document.getElementById("msg-" + obj._id)) {
//console.log("element already exists......");
//console.log(obj);
2023-02-11 21:49:07 +00:00
// console.log(obj.status)
// console.log(obj.attempt)
2023-05-27 04:38:30 +00:00
2023-05-16 09:35:50 +00:00
if (
!obj.status == "broadcast_transmit" ||
!obj.status == "broadcast_received"
) {
document.getElementById("msg-" + obj._id + "-status").innerHTML =
get_icon_for_state(obj.status);
2023-02-11 21:49:07 +00:00
2023-05-16 09:35:50 +00:00
document
.getElementById("msg-" + obj._id + "-progress")
.setAttribute("aria-valuenow", obj.percent);
document
.getElementById("msg-" + obj._id + "-progress")
.setAttribute("style", "width:" + obj.percent + "%;");
document.getElementById(
"msg-" + obj._id + "-progress-information"
).innerHTML = obj.percent + "% - " + obj.bytesperminute + " Bpm";
document.getElementById("msg-" + obj._id + "-attempts").innerHTML =
obj.attempt + "/" + max_retry_attempts;
2023-05-16 09:35:20 +00:00
}
2023-05-27 04:38:30 +00:00
if (obj.status == "transmit") {
document.getElementById("msg-" + obj._id + "-status").innerHTML =
get_icon_for_state(obj.status);
if (typeof obj.percent !== "undefined") {
document
.getElementById("msg-" + obj._id + "-progress")
.setAttribute("aria-valuenow", obj.percent);
document
.getElementById("msg-" + obj._id + "-progress")
.setAttribute("style", "width:" + obj.percent + "%;");
document.getElementById(
"msg-" + obj._id + "-progress-information"
).innerHTML = obj.percent + "% - " + obj.bytesperminute + " Bpm";
} else {
document
.getElementById("msg-" + obj._id + "-progress")
.setAttribute("aria-valuenow", 0);
document
.getElementById("msg-" + obj._id + "-progress")
.setAttribute("style", "width:0%;");
document.getElementById(
"msg-" + obj._id + "-progress-information"
).innerHTML = "0% - 0 Bpm";
}
document.getElementById("msg-" + obj._id + "-attempts").innerHTML =
obj.attempt + "/" + max_retry_attempts;
}
if (obj.status == "transmitted") {
2023-02-11 21:49:07 +00:00
//document.getElementById('msg-' + obj._id + '-progress').classList.remove("progress-bar-striped");
document
.getElementById("msg-" + obj._id + "-progress")
.classList.remove("progress-bar-animated");
document
.getElementById("msg-" + obj._id + "-progress")
.classList.remove("bg-danger");
document
.getElementById("msg-" + obj._id + "-progress")
.classList.add("bg-success");
2023-02-11 21:49:07 +00:00
document.getElementById("msg-" + obj._id + "-progress").innerHTML = "";
2023-03-23 12:10:51 +00:00
document.getElementById(
"msg-" + obj._id + "-progress-information"
).innerHTML = "TRANSMITTED - " + obj.bytesperminute + " Bpm";
2023-05-16 09:35:50 +00:00
} else if (
!obj.status == "broadcast_transmit" ||
!obj.status == "broadcast_received"
) {
2023-02-11 21:49:07 +00:00
document
.getElementById("msg-" + obj._id + "-progress")
.classList.add("progress-bar-striped");
document
.getElementById("msg-" + obj._id + "-progress")
.classList.add("progress-bar-animated");
}
2023-02-11 21:49:07 +00:00
if (obj.status == "failed") {
//document.getElementById('msg-' + obj._id + '-progress').classList.remove("progress-bar-striped");
document
.getElementById("msg-" + obj._id + "-progress")
.classList.remove("progress-bar-animated");
document
.getElementById("msg-" + obj._id + "-progress")
.classList.remove("bg-primary");
document
.getElementById("msg-" + obj._id + "-progress")
.classList.add("bg-danger");
2023-05-27 05:06:26 +00:00
console.log(document
.getElementById("msg-" + obj._id + "-progress")
.classList)
2023-03-23 12:10:51 +00:00
document.getElementById(
"msg-" + obj._id + "-progress-information"
).innerHTML = "TRANSMISSION FAILED - " + obj.bytesperminute + " Bpm";
2023-05-27 05:06:26 +00:00
}
2023-02-11 21:49:07 +00:00
//document.getElementById(id).className = message_class;
}
2023-02-20 17:55:21 +00:00
//Delete message event listener
if (
document.getElementById("del-msg-" + obj._id) &&
!document
.getElementById("del-msg-" + obj._id)
.hasAttribute("listenerOnClick")
) {
// set Attribute to determine if we already created an EventListener for this element
document
.getElementById("del-msg-" + obj._id)
.setAttribute("listenerOnClick", "true");
document
.getElementById("del-msg-" + obj._id)
.addEventListener("click", () => {
db.get(obj._id, {
attachments: true,
2023-02-19 02:02:13 +00:00
})
2023-02-20 17:55:21 +00:00
.then(function (doc) {
db.remove(doc._id, doc._rev, function (err) {
if (err) console.log("Error removing item " + err);
});
})
.catch(function (err) {
console.log(err);
});
2023-02-19 13:36:29 +00:00
2023-02-20 17:55:21 +00:00
document.getElementById("msg-" + obj._id).remove();
document.getElementById("msg-" + obj._id + "-control-area").remove();
console.log("Removed message " + obj._id.toString());
// stop transmission if deleted message is still in progress
2023-03-22 22:03:52 +00:00
if (obj.status == "transmitting") {
let Data = {
command: "stop_transmission",
};
ipcRenderer.send("run-tnc-command", Data);
}
2023-02-20 17:55:21 +00:00
});
//scrollMessagesToBottom();
}
2023-02-19 02:02:13 +00:00
2023-02-11 21:49:07 +00:00
// CREATE SAVE TO FOLDER EVENT LISTENER
if (
document.getElementById("save-file-msg-" + obj._id) &&
!document
.getElementById("save-file-msg-" + obj._id)
.hasAttribute("listenerOnClick")
) {
// set Attribute to determine if we already created an EventListener for this element
document
.getElementById("save-file-msg-" + obj._id)
.setAttribute("listenerOnClick", "true");
document
.getElementById("save-file-msg-" + obj._id)
.addEventListener("click", () => {
saveFileToFolder(obj._id);
});
}
// CREATE RESEND MSG EVENT LISTENER
// check if element exists and if we already created NOT created an event listener
if (
document.getElementById("retransmit-msg-" + obj._id) &&
!document
.getElementById("retransmit-msg-" + obj._id)
.hasAttribute("listenerOnClick")
) {
// set Attribute to determine if we already created an EventListener for this element
document
.getElementById("retransmit-msg-" + obj._id)
.setAttribute("listenerOnClick", "true");
document
.getElementById("retransmit-msg-" + obj._id)
.addEventListener("click", () => {
2023-05-09 08:36:30 +00:00
// increment attempt
db.upsert(obj._id, function (doc) {
2023-05-09 08:35:50 +00:00
if (!doc.attempt) {
doc.attempt = 1;
}
doc.attempt++;
return doc;
2023-05-09 08:36:30 +00:00
})
.then(function (res) {
// success, res is {rev: '1-xxx', updated: true, id: 'myDocId'}
console.log(res);
update_chat_obj_by_uuid(obj.uuid);
})
.catch(function (err) {
// error
console.log(err);
});
2023-05-09 08:35:50 +00:00
2023-02-11 21:49:07 +00:00
db.get(obj._id, {
attachments: true,
})
.then(function (doc) {
// handle doc
console.log(doc);
var filename = Object.keys(obj._attachments)[0];
var filetype = filename.content_type;
console.log(filename);
console.log(filetype);
var file = obj._attachments[filename].data;
console.log(file);
console.log(Object.keys(obj._attachments)[0].data);
//var file = atob(obj._attachments[filename]["data"])
db.getAttachment(obj._id, filename).then(function (data) {
console.log(data);
//Rewrote this part to use buffers to ensure encoding is corect -- n1qm
var binaryString = FD.atob_FD(data);
2023-02-11 21:49:07 +00:00
console.log(binaryString);
var data_with_attachment =
doc.timestamp +
split_char +
doc.msg +
split_char +
filename +
split_char +
filetype +
split_char +
binaryString;
let Data = {
command: "msg",
2023-02-11 21:49:07 +00:00
dxcallsign: doc.dxcallsign,
mode: 255,
frames: 5,
2023-02-11 21:49:07 +00:00
data: data_with_attachment,
checksum: doc.checksum,
uuid: doc.uuid,
};
console.log(Data);
ipcRenderer.send("run-tnc-command", Data);
});
/*
2022-12-08 19:21:44 +00:00
// convert blob data to binary string
blobUtil.blobToBinaryString(data).then(function (binaryString) {
2022-12-09 09:22:03 +00:00
console.log(binaryString)
2022-12-08 19:21:44 +00:00
}).catch(function (err) {
// error
console.log(err);
2022-12-09 09:22:03 +00:00
binaryString = blobUtil.arrayBufferToBinaryString(data);
2023-02-18 18:55:13 +00:00
2022-12-09 10:24:39 +00:00
}).then(function(){
2022-12-08 19:21:44 +00:00
2022-12-09 09:22:03 +00:00
console.log(binaryString)
console.log(binaryString.length)
var data_with_attachment = doc.timestamp + split_char + utf8.encode(doc.msg) + split_char + filename + split_char + filetype + split_char + binaryString;
2022-12-09 09:22:03 +00:00
let Data = {
command: "msg",
2022-12-09 09:22:03 +00:00
dxcallsign: doc.dxcallsign,
mode: 255,
frames: 1,
data: data_with_attachment,
checksum: doc.checksum,
uuid: doc.uuid
};
console.log(Data)
ipcRenderer.send('run-tnc-command', Data);
2022-12-09 09:22:03 +00:00
});
2022-03-27 19:04:04 +00:00
});
*/
2023-02-11 21:49:07 +00:00
})
.catch(function (err) {
console.log(err);
});
});
}
//window.location = window.location
2022-06-07 09:31:59 +00:00
2023-02-11 21:49:07 +00:00
// scroll to bottom on new message
scrollMessagesToBottom();
};
2022-03-27 19:04:04 +00:00
function saveFileToFolder(id) {
2023-02-11 21:49:07 +00:00
db.get(id, {
attachments: true,
})
.then(function (obj) {
console.log(obj);
console.log(Object.keys(obj._attachments)[0].content_type);
var filename = Object.keys(obj._attachments)[0];
var filetype = filename.content_type;
var file = filename.data;
console.log(file);
console.log(filename.data);
db.getAttachment(id, filename)
.then(function (data) {
// handle result
console.log(data.length);
//data = new Blob([data.buffer], { type: 'image/png' } /* (1) */)
console.log(data);
// we need to encode data because of error "an object could not be cloned"
let Data = {
file: data,
filename: filename,
filetype: filetype,
};
console.log(Data);
ipcRenderer.send("save-file-to-folder", Data);
})
.catch(function (err) {
console.log(err);
return false;
2022-03-29 20:24:35 +00:00
});
2023-02-11 21:49:07 +00:00
})
.catch(function (err) {
console.log(err);
});
}
// function for setting an ICON to the corresponding state
function get_icon_for_state(state) {
2023-02-11 21:49:07 +00:00
if (state == "transmit") {
var status_icon = '<i class="bi bi-check" style="font-size:1rem;"></i>';
} else if (state == "transmitting") {
//var status_icon = '<i class="bi bi-arrow-left-right" style="font-size:0.8rem;"></i>';
var status_icon = `
2022-06-09 12:11:39 +00:00
<i class="spinner-border ms-auto" style="width: 0.8rem; height: 0.8rem;" role="status" aria-hidden="true"></i>
`;
2023-02-11 21:49:07 +00:00
} else if (state == "failed") {
var status_icon =
'<i class="bi bi-exclamation-circle" style="font-size:1rem;"></i>';
} else if (state == "transmitted") {
var status_icon = '<i class="bi bi-check-all" style="font-size:1rem;"></i>';
} else {
var status_icon = '<i class="bi bi-question" style="font-size:1rem;"></i>';
}
return status_icon;
}
2022-06-07 09:31:59 +00:00
2023-02-11 21:49:07 +00:00
update_chat_obj_by_uuid = function (uuid) {
db.get(uuid, {
attachments: true,
})
.then(function (doc) {
update_chat(doc);
//return doc
})
.catch(function (err) {
console.log(err);
2022-06-07 09:31:59 +00:00
});
2023-02-11 21:49:07 +00:00
};
2022-06-07 09:31:59 +00:00
2023-02-11 21:49:07 +00:00
add_obj_to_database = function (obj) {
2023-02-26 15:27:55 +00:00
console.log(obj);
2023-02-11 21:49:07 +00:00
db.put({
_id: obj.uuid,
timestamp: parseInt(obj.timestamp),
2023-05-17 09:30:22 +00:00
broadcast_sender: obj.broadcast_sender,
2023-02-11 21:49:07 +00:00
uuid: obj.uuid,
dxcallsign: obj.dxcallsign,
dxgrid: obj.dxgrid,
msg: obj.msg,
checksum: obj.checksum,
type: obj.type,
command: obj.command,
status: obj.status,
snr: obj.snr,
2023-05-09 08:35:50 +00:00
attempt: obj.attempt,
new: obj.new,
2023-02-11 21:49:07 +00:00
_attachments: {
[obj.filename]: {
content_type: obj.filetype,
data: obj.file,
},
},
})
.then(function (response) {
console.log("new database entry");
console.log(response);
})
.catch(function (err) {
2023-05-09 08:35:50 +00:00
console.log("already exists");
2023-02-11 21:49:07 +00:00
console.log(err);
2023-05-16 09:35:50 +00:00
console.log(obj);
2023-05-16 09:35:20 +00:00
db.upsert(obj.uuid, function (doc) {
2023-05-16 09:35:50 +00:00
doc = obj;
return doc;
})
.then(function (response) {
console.log("upsert");
console.log(response);
})
.catch(function (err) {
console.log(err);
});
2022-06-07 09:31:59 +00:00
});
2023-02-11 21:49:07 +00:00
};
2023-02-18 18:55:13 +00:00
/* users database functions */
addUserToDatabaseIfNotExists = function (obj) {
/*
"user_info_callsign",
"user_info_gridsquare",
"user_info_name",
"user_info_age",
"user_info_location",
"user_info_radio",
"user_info_antenna",
"user_info_email",
"user_info_website",
"user_info_comments",
*/
2023-02-20 17:55:21 +00:00
console.log(obj);
2023-02-18 18:55:13 +00:00
users
.find({
selector: {
2023-02-19 14:37:51 +00:00
user_info_callsign: obj.user_info_callsign,
2023-02-18 18:55:13 +00:00
},
})
.then(function (result) {
// handle result
2023-03-23 09:16:26 +00:00
console.log(result);
2023-02-18 18:55:13 +00:00
if (result.docs.length > 0) {
users
.put({
_id: result.docs[0]._id,
_rev: result.docs[0]._rev,
2023-02-19 14:37:51 +00:00
user_info_callsign: obj.user_info_callsign,
user_info_gridsquare: obj.user_info_gridsquare,
user_info_name: obj.user_info_name,
user_info_age: obj.user_info_age,
user_info_location: obj.user_info_location,
user_info_radio: obj.user_info_radio,
user_info_antenna: obj.user_info_antenna,
user_info_email: obj.user_info_email,
user_info_website: obj.user_info_website,
user_info_comments: obj.user_info_comments,
2023-02-26 09:48:21 +00:00
user_info_image: obj.user_info_image,
2023-02-18 18:55:13 +00:00
})
.then(function (response) {
console.log("UPDATED USER");
2023-02-23 11:13:49 +00:00
console.log(response);
console.log(obj);
2023-02-18 18:55:13 +00:00
})
.catch(function (err) {
console.log(err);
});
} else {
users
.post({
2023-02-19 14:37:51 +00:00
user_info_callsign: obj.user_info_callsign,
user_info_gridsquare: obj.user_info_gridsquare,
user_info_name: obj.user_info_name,
user_info_age: obj.user_info_age,
user_info_location: obj.user_info_location,
user_info_radio: obj.user_info_radio,
user_info_antenna: obj.user_info_antenna,
user_info_email: obj.user_info_email,
user_info_website: obj.user_info_website,
user_info_comments: obj.user_info_comments,
2023-02-18 18:55:13 +00:00
})
.then(function (response) {
console.log("NEW USER ADDED");
})
.catch(function (err) {
console.log(err);
});
}
})
.catch(function (err) {
console.log(err);
});
};
2023-02-28 19:06:39 +00:00
addFileListToUserDatabaseIfNotExists = function (obj) {
console.log(obj);
users
.find({
selector: {
user_info_callsign: obj.user_info_callsign,
},
})
.then(function (result) {
// handle result
if (result.docs.length > 0) {
users
.put({
_id: result.docs[0]._id,
_rev: result.docs[0]._rev,
user_shared_folder: obj.user_shared_folder,
user_info_callsign: result.docs[0].user_info_callsign,
user_info_gridsquare: result.docs[0].user_info_gridsquare,
user_info_name: result.docs[0].user_info_name,
user_info_age: result.docs[0].user_info_age,
user_info_location: result.docs[0].user_info_location,
user_info_radio: result.docs[0].user_info_radio,
user_info_antenna: result.docs[0].user_info_antenna,
user_info_email: result.docs[0].user_info_email,
user_info_website: result.docs[0].user_info_website,
user_info_comments: result.docs[0].user_info_comments,
2023-02-28 19:06:39 +00:00
})
.then(function (response) {
console.log("File List: UPDATED USER");
2023-02-28 19:06:39 +00:00
console.log(response);
console.log(obj);
2023-03-23 08:53:58 +00:00
getSetUserSharedFolder(obj.user_info_callsign);
2023-02-28 19:06:39 +00:00
})
.catch(function (err) {
console.log(err);
});
} else {
users
.post({
user_info_callsign: obj.user_info_callsign,
user_shared_folder: obj.user_shared_folder,
})
.then(function (response) {
console.log("File List: NEW USER ADDED");
2023-03-23 08:53:58 +00:00
getSetUserSharedFolder(obj.user_info_callsign);
2023-02-28 19:06:39 +00:00
})
.catch(function (err) {
console.log(err);
});
}
})
.catch(function (err) {
console.log(err);
});
};
// Scroll to bottom of message-container
function scrollMessagesToBottom() {
2023-02-11 21:49:07 +00:00
var messageBody = document.getElementById("message-container");
messageBody.scrollTop = messageBody.scrollHeight - messageBody.clientHeight;
2022-12-09 09:22:03 +00:00
}
2022-12-27 21:57:54 +00:00
2022-12-27 22:30:15 +00:00
// CRC CHECKSUMS
2022-12-27 21:57:54 +00:00
// https://stackoverflow.com/a/50579690
// crc32 calculation
//console.log(crc32('abc'));
2022-12-27 22:30:15 +00:00
//var crc32=function(r){for(var a,o=[],c=0;c<256;c++){a=c;for(var f=0;f<8;f++)a=1&a?3988292384^a>>>1:a>>>1;o[c]=a}for(var n=-1,t=0;t<r.length;t++)n=n>>>8^o[255&(n^r.charCodeAt(t))];return(-1^n)>>>0};
2022-12-27 21:57:54 +00:00
//console.log(crc32('abc').toString(16).toUpperCase()); // hex
2022-12-27 22:30:15 +00:00
2023-02-11 21:49:07 +00:00
var makeCRCTable = function () {
var c;
var crcTable = [];
for (var n = 0; n < 256; n++) {
c = n;
for (var k = 0; k < 8; k++) {
c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
2022-12-27 22:30:15 +00:00
}
2023-02-11 21:49:07 +00:00
crcTable[n] = c;
}
return crcTable;
};
2022-12-27 22:30:15 +00:00
2023-02-11 21:49:07 +00:00
var crc32 = function (str) {
var crcTable = window.crcTable || (window.crcTable = makeCRCTable());
var crc = 0 ^ -1;
2022-12-27 22:30:15 +00:00
2023-02-11 21:49:07 +00:00
for (var i = 0; i < str.length; i++) {
crc = (crc >>> 8) ^ crcTable[(crc ^ str.charCodeAt(i)) & 0xff];
}
2022-12-27 22:30:15 +00:00
2023-02-11 21:49:07 +00:00
return (crc ^ -1) >>> 0;
2023-02-05 03:26:44 +00:00
};
2023-02-19 14:37:51 +00:00
function returnObjFromCallsign(database, callsign) {
2023-02-26 11:15:29 +00:00
return new Promise((resolve, reject) => {
2023-02-26 11:20:01 +00:00
users
.find({
selector: {
user_info_callsign: callsign,
},
})
.then(function (result) {
//return new Promise((resolve, reject) => {
if (typeof result.docs[0] !== "undefined") {
resolve(result.docs[0]);
} else {
reject("Promise rejected");
}
/*
2023-02-20 17:55:21 +00:00
if (typeof result.docs[0] !== "undefined") {
return result.docs[0];
2023-02-26 11:15:29 +00:00
2023-02-20 17:55:21 +00:00
} else {
return false;
}
2023-02-26 11:15:29 +00:00
*/
2023-02-26 11:20:01 +00:00
})
.catch(function (err) {
console.log(err);
});
});
2023-02-19 13:36:29 +00:00
}
2023-02-20 17:55:21 +00:00
function createChatIndex() {
db.createIndex({
2023-02-19 13:36:29 +00:00
index: {
fields: [
"timestamp",
2023-02-20 17:55:21 +00:00
"uuid",
"dxcallsign",
"dxgrid",
"msg",
"checksum",
"type",
"command",
"status",
"percent",
2023-05-09 08:35:50 +00:00
"attempt",
2023-02-20 17:55:21 +00:00
"bytesperminute",
2023-02-19 13:36:29 +00:00
"_attachments",
"new",
2023-02-19 13:36:29 +00:00
],
},
})
2023-02-20 17:55:21 +00:00
.then(function (result) {
// handle result
console.log(result);
})
.catch(function (err) {
console.log(err);
});
}
function createUserIndex() {
users
.createIndex({
index: {
fields: [
"timestamp",
"user_info_callsign",
"user_info_gridsquare",
"user_info_name",
"user_info_age",
"user_info_location",
"user_info_radio",
"user_info_antenna",
"user_info_email",
"user_info_website",
"user_info_comments",
2023-02-26 09:48:21 +00:00
"user_info_image",
2023-02-20 17:55:21 +00:00
],
},
})
.then(function (result) {
// handle result
console.log(result);
return true;
})
.catch(function (err) {
console.log(err);
return false;
});
2023-02-19 14:37:51 +00:00
}
2023-02-19 13:36:29 +00:00
async function updateAllChat(clear) {
2023-02-20 17:55:21 +00:00
if (clear == true) {
2023-02-19 14:37:51 +00:00
filetype = "";
file = "";
filename = "";
callsign_counter = 0;
//selected_callsign = "";
dxcallsigns.clear();
2023-02-20 17:55:21 +00:00
document.getElementById("list-tab").innerHTML = "";
document.getElementById("nav-tabContent").innerHTML = "";
2023-02-19 14:37:51 +00:00
//document.getElementById("list-tab").childNodes.remove();
//document.getElementById("nav-tab-content").childrenNodes.remove();
}
//Ensure we create an index before running db.find
//We can't rely on the default index existing before we get here...... :'(
2023-02-25 05:29:09 +00:00
await db
.createIndex({
index: {
2023-06-18 18:57:18 +00:00
fields: [
{ dxcallsign:"asc" },
{ timestamp:"asc" },
],
2023-02-25 05:29:09 +00:00
},
})
.then(async function (result) {
// handle result
2023-02-25 05:29:09 +00:00
await db
.find({
selector: {
2023-06-18 18:57:18 +00:00
$and: [
{dxcallsign: { $exists: true } },
{timestamp: { $exists: true } },
{ $or: chatFilter }]
2023-02-25 05:29:09 +00:00
//$or: chatFilter
},
2023-02-25 05:29:09 +00:00
sort: [
2023-06-18 18:57:18 +00:00
{ dxcallsign:"asc" },
{ timestamp: "asc" },
]
2023-02-25 05:29:09 +00:00
})
.then(async function (result) {
2023-05-16 09:35:50 +00:00
console.log(result);
// handle result async
2023-03-22 22:46:43 +00:00
//document.getElementById("blurOverlay").classList.add("bg-primary");
2023-05-15 17:10:56 +00:00
console.log(result);
if (typeof result !== "undefined") {
2023-02-20 17:55:21 +00:00
for (const item of result.docs) {
//await otherwise history will not be in chronological order
await db
.get(item._id, {
attachments: true,
2023-02-20 17:55:21 +00:00
})
.then(function (item_with_attachments) {
update_chat(item_with_attachments);
});
2023-02-20 17:55:21 +00:00
}
2023-02-19 14:37:51 +00:00
}
2023-03-22 22:46:43 +00:00
})
.catch(function (err) {
console.log(err);
});
2023-02-19 14:37:51 +00:00
})
.catch(function (err) {
console.log(err);
});
2023-02-25 05:29:09 +00:00
if (clear == true && dxcallsigns.has(selected_callsign) == false) {
//Selected call sign is not visible, reset to first call sign
let tmp = dxcallsigns.entries().next().value[0];
selected_callsign = tmp;
document
.getElementById("chat-" + tmp + "-list")
.classList.add("active", "show");
document.getElementById("chat-" + tmp).classList.add("active", "show");
scrollMessagesToBottom();
}
2023-02-19 14:37:51 +00:00
}
2023-02-26 11:15:29 +00:00
2023-03-19 15:33:19 +00:00
function getSetUserSharedFolder(selected_callsign) {
2023-03-22 12:32:49 +00:00
// TODO: This is a dirty hotfix for avoiding, this function is canceld too fast.
console.log("get set user information:" + selected_callsign);
2023-03-22 12:27:59 +00:00
2023-03-04 18:49:59 +00:00
if (
selected_callsign == "" ||
selected_callsign == null ||
typeof selected_callsign == "undefined"
2023-03-22 12:53:04 +00:00
) {
console.log("return triggered");
2023-03-04 18:49:59 +00:00
return;
2023-03-22 12:53:04 +00:00
}
2023-05-15 17:10:56 +00:00
// disable button if broadcast
if (selected_callsign.startsWith("BC-")) {
document.getElementById("sharedFolderDXButton").disabled = true;
} else {
document.getElementById("sharedFolderDXButton").disabled = false;
}
2023-02-26 11:20:01 +00:00
returnObjFromCallsign(users, selected_callsign)
.then(function (data) {
2023-03-19 15:33:19 +00:00
console.log(data);
2023-02-28 19:06:39 +00:00
2023-02-28 19:07:10 +00:00
if (typeof data.user_shared_folder !== "undefined") {
console.log(data.user_shared_folder);
2023-02-28 19:07:10 +00:00
// shared folder table
2023-03-05 06:38:36 +00:00
var icons = [
"aac",
"ai",
"bmp",
"cs",
"css",
"csv",
"doc",
"docx",
"exe",
"gif",
"heic",
"html",
"java",
"jpg",
"js",
"json",
"jsx",
"key",
"m4p",
"md",
"mdx",
"mov",
"mp3",
"mp4",
"otf",
"pdf",
"php",
"png",
"ppt",
"pptx",
"psd",
"py",
"raw",
"rb",
"sass",
"scss",
"sh",
"sql",
"svg",
"tiff",
"tsx",
"ttf",
"txt",
"wav",
"woff",
"xls",
"xlsx",
"xml",
"yml",
];
2023-02-28 19:07:10 +00:00
var tbl = document.getElementById("sharedFolderTableDX");
tbl.innerHTML = "";
let counter = 0;
data.user_shared_folder.forEach((file) => {
var row = document.createElement("tr");
2023-03-05 06:38:36 +00:00
2023-03-05 06:32:22 +00:00
let dxcall = selected_callsign;
let name = file["name"];
let type = file["extension"];
2023-03-05 06:38:36 +00:00
if (icons.indexOf(type) == -1) {
type = "bi-file-earmark";
2023-03-05 06:32:22 +00:00
} else {
2023-03-05 06:38:36 +00:00
type = "bi-filetype-" + type;
2023-03-05 06:32:22 +00:00
}
2023-02-28 19:07:10 +00:00
let id = document.createElement("td");
let idText = document.createElement("span");
2023-03-05 06:32:22 +00:00
counter += 1;
2023-03-05 06:38:36 +00:00
idText.innerHTML +=
'<i class="bi bi-file-earmark-arrow-down" style="font-size: 1.8rem;cursor: pointer"></i> ' +
2023-03-05 06:38:36 +00:00
counter;
2023-02-28 19:07:10 +00:00
id.appendChild(idText);
row.appendChild(id);
let filename = document.createElement("td");
let filenameText = document.createElement("span");
filenameText.innerText = file["name"];
filename.appendChild(filenameText);
row.appendChild(filename);
let filetype = document.createElement("td");
let filetypeText = document.createElement("span");
2023-03-05 06:32:22 +00:00
filetypeText.innerHTML = `<i class="bi ${type}" style="font-size: 1.8rem"></i>`;
2023-02-28 19:07:10 +00:00
filetype.appendChild(filetypeText);
row.appendChild(filetype);
let filesize = document.createElement("td");
let filesizeText = document.createElement("span");
2023-03-04 12:24:37 +00:00
filesizeText.innerText = formatBytes(file["size"], 2);
2023-02-28 19:07:10 +00:00
filesize.appendChild(filesizeText);
row.appendChild(filesize);
id.addEventListener("click", function () {
2023-03-05 06:32:22 +00:00
//console.log(name," clicked");
2023-03-05 06:38:36 +00:00
sendFileReq(dxcall, name);
2023-03-05 06:32:22 +00:00
});
2023-02-28 19:07:10 +00:00
tbl.appendChild(row);
});
} else {
document.getElementById("sharedFolderTableDX").innerHTML = "no data";
}
2023-02-26 11:20:01 +00:00
})
2023-03-19 15:32:57 +00:00
.catch(function (err) {
2023-03-23 09:28:08 +00:00
console.log(err);
2023-03-19 15:32:57 +00:00
document.getElementById("sharedFolderTableDX").innerHTML = "no data";
});
}
2023-02-26 11:20:01 +00:00
function getSetUserInformation(selected_callsign) {
//Get user information
2023-03-22 12:45:37 +00:00
console.log("get set user information:" + selected_callsign);
2023-03-04 18:49:59 +00:00
if (
selected_callsign == "" ||
selected_callsign == null ||
typeof selected_callsign == "undefined"
2023-03-22 12:53:04 +00:00
) {
console.log("return triggered");
2023-03-04 18:49:59 +00:00
return;
2023-03-22 12:53:04 +00:00
}
2023-05-15 17:10:56 +00:00
// disable button if broadcast
if (selected_callsign.startsWith("BC-")) {
document.getElementById("userModalDXButton").disabled = true;
document.getElementById("ping").disabled = true;
} else {
document.getElementById("userModalDXButton").disabled = false;
document.getElementById("ping").disabled = false;
}
2023-02-26 11:20:01 +00:00
document.getElementById("dx_user_info_callsign").innerHTML =
selected_callsign;
returnObjFromCallsign(users, selected_callsign)
.then(function (data) {
2023-03-19 15:33:19 +00:00
console.log(data);
2023-03-19 15:32:57 +00:00
2023-02-28 19:06:39 +00:00
// image
2023-02-28 19:07:10 +00:00
if (typeof data.user_info_image !== "undefined") {
2023-03-19 16:17:29 +00:00
try {
2023-03-22 12:45:37 +00:00
console.log("try checking for image if base64 data");
2023-03-19 16:39:15 +00:00
// determine if we have a base64 encoded image
2023-03-22 21:08:42 +00:00
console.log(data.user_info_image);
2023-03-22 21:19:23 +00:00
console.log(data.user_info_image.split(";base64,")[1]);
// split data string by "base64" for separating image type from base64 string
atob(data.user_info_image.split(";base64,")[1]);
2023-03-19 16:30:02 +00:00
2023-05-16 17:08:31 +00:00
if (selected_callsign.startsWith("BC-")) {
data.user_info_image = defaultGroupIcon;
}
2023-05-16 16:21:57 +00:00
2023-03-19 16:17:29 +00:00
document.getElementById("dx_user_info_image").src =
data.user_info_image;
document.getElementById("user-image-" + selected_callsign).src =
data.user_info_image;
} catch (e) {
console.log(e);
console.log("corrupted image data");
2023-05-16 16:21:57 +00:00
2023-05-16 17:08:31 +00:00
if (selected_callsign.startsWith("BC-")) {
var userIcon = defaultGroupIcon;
2023-05-17 09:06:07 +00:00
document
.getElementById("chatModuleMessage")
.setAttribute("maxlength", 16);
2023-05-16 17:08:31 +00:00
} else {
var userIcon = defaultUserIcon;
2023-05-17 09:06:07 +00:00
document
.getElementById("chatModuleMessage")
.setAttribute("maxlength", 524288);
2023-05-16 17:08:31 +00:00
}
2023-05-16 16:21:57 +00:00
2023-03-19 16:17:29 +00:00
document.getElementById("user-image-" + selected_callsign).src =
2023-05-16 16:21:57 +00:00
userIcon;
document.getElementById("dx_user_info_image").src = userIcon;
2023-03-19 16:17:29 +00:00
}
2023-02-28 19:06:39 +00:00
} else {
// throw error and use placeholder data
// throw new Error("Data not available or corrupted");
document.getElementById("dx_user_info_image").src = defaultUserIcon;
document.getElementById("user-image-" + selected_callsign).src =
defaultUserIcon;
2023-02-28 19:06:39 +00:00
}
2023-02-28 08:08:09 +00:00
// Callsign list elements
document.getElementById(
"chat-" + selected_callsign + "-list-dxgrid"
).innerHTML = "<small>" + data.user_info_gridsquare + "</small>";
document.getElementById("user-image-" + selected_callsign).className =
"p-1 rounded-circle";
document.getElementById("user-image-" + selected_callsign).style =
"width: 60px";
2023-02-28 08:07:38 +00:00
2023-02-28 08:08:09 +00:00
// DX Station tab
2023-02-26 11:20:01 +00:00
document.getElementById("dx_user_info_name").innerHTML =
data.user_info_name;
document.getElementById("dx_user_info_age").innerHTML =
data.user_info_age;
document.getElementById("dx_user_info_gridsquare").innerHTML =
data.user_info_gridsquare;
document.getElementById("dx_user_info_location").innerHTML =
data.user_info_location;
document.getElementById("dx_user_info_email").innerHTML =
data.user_info_email;
document.getElementById("dx_user_info_website").innerHTML =
data.user_info_website;
document.getElementById("dx_user_info_radio").innerHTML =
data.user_info_radio;
document.getElementById("dx_user_info_antenna").innerHTML =
data.user_info_antenna;
document.getElementById("dx_user_info_comments").innerHTML =
data.user_info_comments;
2023-02-28 19:06:39 +00:00
2023-02-26 11:20:01 +00:00
document.getElementById("dx_user_info_gridsquare").className = "";
2023-02-26 13:01:21 +00:00
document.getElementById("dx_user_info_name").className =
"badge bg-secondary";
document.getElementById("dx_user_info_age").className =
"badge bg-secondary";
2023-02-26 11:20:01 +00:00
document.getElementById("dx_user_info_gridsquare").className = "";
document.getElementById("dx_user_info_location").className = "";
document.getElementById("dx_user_info_email").className = "";
document.getElementById("dx_user_info_website").className = "";
document.getElementById("dx_user_info_radio").className = "";
document.getElementById("dx_user_info_antenna").className = "";
document.getElementById("dx_user_info_comments").className = "";
})
.catch(function (err) {
2023-03-22 21:08:42 +00:00
console.log("writing user info to modal failed");
console.log(err);
2023-05-16 17:08:31 +00:00
if (selected_callsign.startsWith("BC-")) {
2023-05-17 09:06:07 +00:00
document
.getElementById("chatModuleMessage")
.setAttribute("maxlength", 16);
2023-05-16 16:21:57 +00:00
var userIcon = defaultGroupIcon;
2023-05-16 17:08:31 +00:00
} else {
var userIcon = defaultUserIcon;
2023-05-17 09:06:07 +00:00
document
.getElementById("chatModuleMessage")
.setAttribute("maxlength", 524288);
2023-05-16 17:08:31 +00:00
}
2023-05-16 16:21:57 +00:00
2023-02-28 08:07:38 +00:00
// Callsign list elements
2023-05-16 17:08:31 +00:00
document.getElementById("user-image-" + selected_callsign).src = userIcon;
2023-02-28 19:07:10 +00:00
document.getElementById("user-image-" + selected_callsign).className =
2023-02-27 17:32:01 +00:00
"p-1 rounded-circle w-100";
document.getElementById("user-image-" + selected_callsign).style =
"height:60px";
2023-02-28 08:08:09 +00:00
document.getElementById(
"chat-" + selected_callsign + "-list-dxgrid"
).innerHTML = "<small>no grid</small>";
2023-02-27 17:32:01 +00:00
2023-02-28 08:07:38 +00:00
// DX Station tab
2023-02-28 19:06:39 +00:00
document.getElementById("dx_user_info_image").src = defaultUserIcon;
2023-02-28 19:07:10 +00:00
document.getElementById("dx_user_info_gridsquare").className =
2023-02-26 11:20:01 +00:00
"placeholder col-4";
document.getElementById("dx_user_info_name").className =
"placeholder col-4";
document.getElementById("dx_user_info_age").className =
"placeholder col-2";
document.getElementById("dx_user_info_gridsquare").className =
"placeholder col-3";
document.getElementById("dx_user_info_location").className =
"placeholder col-3";
document.getElementById("dx_user_info_email").className =
"placeholder col-7";
document.getElementById("dx_user_info_website").className =
"placeholder col-7";
document.getElementById("dx_user_info_radio").className =
"placeholder col-4";
document.getElementById("dx_user_info_antenna").className =
"placeholder col-4";
document.getElementById("dx_user_info_comments").className =
"placeholder col-7";
});
}
2023-02-28 14:20:17 +00:00
function sendSharedFolderList(dxcallsign) {
ipcRenderer.send("read-files-in-folder", {
folder: config.shared_folder_path,
});
2023-02-28 14:20:17 +00:00
console.log(sharedFolderFileList);
2023-02-28 19:07:10 +00:00
let fileListWithCallsign = "";
fileListWithCallsign += dxcallsign;
fileListWithCallsign += split_char;
fileListWithCallsign += JSON.stringify(sharedFolderFileList);
2023-02-28 19:06:39 +00:00
console.log(fileListWithCallsign);
2023-02-28 14:20:17 +00:00
ipcRenderer.send("run-tnc-command", {
command: "responseSharedFolderList",
dxcallsign: dxcallsign,
2023-02-28 19:06:39 +00:00
folderFileList: fileListWithCallsign,
});
}
2023-03-05 21:16:43 +00:00
function sendSharedFolderFile(dxcallsign, filename) {
let filePath = path.join(config.shared_folder_path, filename);
console.log("In function sendSharedFolderFile ", filePath);
2023-03-05 21:16:43 +00:00
//Make sure nothing sneaky is going on
2023-03-05 21:16:03 +00:00
if (!filePath.startsWith(config.shared_folder_path)) {
console.error("File is outside of shared folder path!");
return;
}
2023-03-05 21:16:43 +00:00
2023-03-05 21:16:03 +00:00
if (!fs.existsSync(filePath)) {
2023-03-05 21:16:43 +00:00
console.warn("File doesn't seem to exist");
2023-03-05 21:16:03 +00:00
return;
}
//Read file's data
let fileData = null;
try {
//Has to be binary
2023-03-05 21:16:43 +00:00
let data = fs.readFileSync(filePath);
fileData = data.toString("utf-8");
2023-03-05 21:16:03 +00:00
} catch (err) {
console.log(err);
return;
}
2023-03-05 21:16:43 +00:00
ipcRenderer.send("run-tnc-command", {
command: "responseSharedFile",
dxcallsign: dxcallsign,
file: filename,
filedata: fileData,
});
}
2023-02-26 15:27:55 +00:00
function sendUserData(dxcallsign) {
const userInfoFields = [
"user_info_image",
"user_info_callsign",
"user_info_gridsquare",
"user_info_name",
"user_info_age",
"user_info_location",
"user_info_radio",
"user_info_antenna",
"user_info_email",
"user_info_website",
"user_info_comments",
];
2023-02-26 15:27:55 +00:00
let info = "";
userInfoFields.forEach(function (subelem) {
if (subelem !== "user_info_image") {
info += document.getElementById(subelem).value;
info += split_char;
} else {
info += document.getElementById(subelem).src;
info += split_char;
}
});
2023-02-26 15:27:55 +00:00
console.log(info);
2023-02-26 15:27:55 +00:00
ipcRenderer.send("run-tnc-command", {
command: "responseUserInfo",
dxcallsign: selected_callsign,
userinfo: info,
});
}
2023-02-26 16:54:21 +00:00
//Temporarily disable a button with timeout
function pauseButton(btn, timems) {
btn.disabled = true;
var curText = btn.innerHTML;
if (config.high_graphics.toUpperCase() == "TRUE") {
btn.innerHTML =
'<span class="spinner-grow spinner-grow-sm force-gpu" role="status" aria-hidden="true">';
}
setTimeout(() => {
btn.innerHTML = curText;
btn.disabled = false;
}, timems);
2023-02-26 16:54:49 +00:00
}
2023-03-03 03:06:25 +00:00
ipcRenderer.on("update-config", (event, data) => {
config = data;
});
2023-03-04 12:24:37 +00:00
ipcRenderer.on("action-update-unread-messages", (event) => {
checkForNewMessages().then(function(count) {
ipcRenderer.send("request-update-unread-messages-main",count);
});
});
2023-07-01 21:03:22 +00:00
ipcRenderer.on("action-clean-db", (event) => {
dbClean();
});
2023-03-04 12:24:37 +00:00
// https://stackoverflow.com/a/18650828
function formatBytes(bytes, decimals = 2) {
2023-03-04 12:25:09 +00:00
if (!+bytes) return "0 Bytes";
2023-03-04 12:24:37 +00:00
2023-03-04 12:25:09 +00:00
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
2023-03-04 12:24:37 +00:00
2023-03-04 12:25:09 +00:00
const i = Math.floor(Math.log(bytes) / Math.log(k));
2023-03-04 12:24:37 +00:00
2023-03-04 12:25:09 +00:00
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
}
2023-03-05 06:32:22 +00:00
function sendFileReq(dxcall, file) {
//console.log(file," clicked");
ipcRenderer.send("run-tnc-command", {
command: "requestSharedFile",
dxcallsign: dxcall,
2023-03-05 06:38:36 +00:00
file: file,
});
}
2023-03-16 07:59:32 +00:00
2023-03-16 07:59:54 +00:00
function changeGuiDesign(design) {
console.log(design);
if (
2023-03-16 07:59:32 +00:00
design != "default" &&
design != "default_light" &&
design != "default_dark" &&
design != "default_auto"
) {
var theme_path =
"../node_modules/bootswatch/dist/" + design + "/bootstrap.min.css";
document.getElementById("bootstrap_theme").href = escape(theme_path);
} else if (design == "default" || design == "default_light") {
var theme_path = "../node_modules/bootstrap/dist/css/bootstrap.min.css";
document.getElementById("bootstrap_theme").href = escape(theme_path);
document.documentElement.setAttribute("data-bs-theme", "light");
} else if (design == "default_dark") {
var theme_path = "../node_modules/bootstrap/dist/css/bootstrap.min.css";
document.getElementById("bootstrap_theme").href = escape(theme_path);
document.querySelector("html").setAttribute("data-bs-theme", "dark");
} else if (design == "default_auto") {
var theme_path = "../node_modules/bootstrap/dist/css/bootstrap.min.css";
document.getElementById("bootstrap_theme").href = escape(theme_path);
// https://stackoverflow.com/a/57795495
// check if dark mode or light mode used in OS
if (
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches
) {
// dark mode
document.documentElement.setAttribute("data-bs-theme", "dark");
} else {
document.documentElement.setAttribute("data-bs-theme", "light");
}
// also register event listener for automatic change
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
let newColorScheme = event.matches ? "dark" : "light";
if (newColorScheme == "dark") {
document.documentElement.setAttribute("data-bs-theme", "dark");
} else {
document.documentElement.setAttribute("data-bs-theme", "light");
}
});
} else {
var theme_path = "../node_modules/bootstrap/dist/css/bootstrap.min.css";
document.getElementById("bootstrap_theme").href = escape(theme_path);
document.documentElement.setAttribute("data-bs-theme", "light");
}
//update path to css file
2023-03-16 07:59:54 +00:00
document.getElementById("bootstrap_theme").href = escape(theme_path);
}
2023-05-09 10:27:51 +00:00
function checkForWaitingMessages(dxcall) {
2023-05-09 10:29:28 +00:00
console.log(dxcall);
db.find({
selector: {
dxcallsign: dxcall,
type: "transmit",
status: "failed",
//attempt: { $lt: parseInt(config.max_retry_attempts) }
},
})
2023-05-09 10:27:51 +00:00
.then(function (result) {
// handle result
if (result.docs.length > 0) {
2023-05-09 10:29:28 +00:00
// only want to process the first available item object, then return
// this ensures, we are only sending one message at once
2023-05-09 10:27:51 +00:00
2023-05-09 10:29:28 +00:00
if (typeof result.docs[0].attempt == "undefined") {
2023-05-09 11:24:37 +00:00
db.upsert(result.docs[0]._id, function (doc) {
2023-05-09 10:29:28 +00:00
if (!doc.attempt) {
doc.attempt = 1;
2023-05-09 10:27:51 +00:00
}
2023-05-09 10:29:28 +00:00
doc.attempt++;
return doc;
});
console.log("old message found - adding attempt field");
result.docs[0].attempt = 1;
2023-05-09 10:27:51 +00:00
}
2023-05-09 10:29:28 +00:00
if (result.docs[0].attempt < config.max_retry_attempts) {
console.log("RESENDING MESSAGE TRIGGERED BY BEACON OR PING");
console.log(result.docs[0]);
document
.getElementById("retransmit-msg-" + result.docs[0]._id)
.click();
} else {
console.log("max retries reached...can't auto repeat");
document
.getElementById("msg-" + result.docs[0]._id + "-attempts-badge")
.classList.remove("bg-primary");
document
.getElementById("msg-" + result.docs[0]._id + "-attempts-badge")
.classList.add("bg-danger");
}
return;
} else {
console.log("nope");
}
})
.catch(function (err) {
console.log(err);
});
}
async function checkForNewMessages()
2023-06-11 03:14:25 +00:00
{
var newmsgs;
await db.find({
2023-06-11 03:14:25 +00:00
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);
});
2023-06-11 03:14:25 +00:00
}
//Have the operating system show a notification popup
function showOsPopUp(title, message)
{
2023-06-11 14:40:01 +00:00
if (config.enable_sys_notification == 0) return;
2023-06-11 03:14:25 +00:00
const NOTIFICATION_TITLE = title;
const NOTIFICATION_BODY = message;
new Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY });
2023-06-14 22:03:10 +00:00
}
//Function to clean old beacons and optimize database
async function dbClean()
{
//Only keep the most x latest days of beacons
let beaconKeep = 7;
2023-07-01 16:42:58 +00:00
let itemCount = 0;
2023-06-14 22:03:10 +00:00
let timestampPurge = Math.floor((Date.now()- beaconKeep * 24*60*60*1000) / 1000) ;
2023-07-01 16:42:58 +00:00
if (confirm("Delete beacons and pings older than " + beaconKeep + " days and compact database?")) {
2023-06-14 22:03:10 +00:00
} else {
return;
}
2023-07-01 16:42:58 +00:00
//Items to purge from database
var purgeFilter = [
{ type: "beacon" },
{ type: "ping-ack" },
{ type: "ping" },
];
2023-06-14 22:03:10 +00:00
await db.find({
selector: {
2023-07-01 16:42:58 +00:00
$and: [
{timestamp: { $lt: timestampPurge } },
{ $or: purgeFilter }]
2023-06-14 22:03:10 +00:00
}
})
.then(async function (result) {
2023-07-01 16:42:58 +00:00
//console.log("Purging " + result.docs.length + " beacons received before " + timestampPurge);
itemCount=result.docs.length;
2023-06-14 22:03:10 +00:00
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();
2023-07-01 21:03:22 +00:00
window.alert("Database maintenance is complete. " + itemCount + " items removed from database. It's recommended you now restart the GUI.");
2023-06-14 22:03:10 +00:00
}