2022-07-20 08:43:57 -04:00
|
|
|
|
var cleared = false;
|
|
|
|
|
var callsign_list = {};
|
2024-02-06 13:50:51 -05:00
|
|
|
|
var callsign_location = {};
|
2022-07-20 08:43:57 -04:00
|
|
|
|
var message_list = {};
|
2023-08-22 13:37:43 -04:00
|
|
|
|
var from_msg_list = {};
|
2023-09-21 16:29:15 -04:00
|
|
|
|
var selected_tab_callsign = null;
|
2022-11-24 11:27:58 -05:00
|
|
|
|
const socket = io("/sendmsg");
|
2022-07-20 08:43:57 -04:00
|
|
|
|
|
2023-09-05 14:14:52 -04:00
|
|
|
|
MSG_TYPE_TX = "tx";
|
|
|
|
|
MSG_TYPE_RX = "rx";
|
|
|
|
|
MSG_TYPE_ACK = "ack";
|
|
|
|
|
|
2024-02-06 13:50:51 -05:00
|
|
|
|
function reload_popovers() {
|
|
|
|
|
$('[data-bs-toggle="popover"]').popover(
|
|
|
|
|
{html: true, animation: true}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function build_location_string(msg) {
|
|
|
|
|
dt = new Date(parseInt(msg['lasttime']) * 1000);
|
|
|
|
|
loc = "Last Location Update: " + dt.toLocaleString();
|
|
|
|
|
loc += "<br>Latitude: " + msg['lat'] + "<br>Longitude: " + msg['lon'];
|
|
|
|
|
loc += "<br>" + "Altitude: " + msg['altitude'] + " m";
|
|
|
|
|
loc += "<br>" + "Speed: " + msg['speed'] + " kph";
|
|
|
|
|
loc += "<br>" + "Bearing: " + msg['course'] + "°";
|
|
|
|
|
loc += "<br>" + "distance: " + msg['distance'] + " km";
|
|
|
|
|
return loc;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-19 20:15:56 -05:00
|
|
|
|
function build_location_string_small(msg) {
|
|
|
|
|
|
|
|
|
|
dt = new Date(parseInt(msg['lasttime']) * 1000);
|
|
|
|
|
|
|
|
|
|
loc = "" + msg['distance'] + "km";
|
|
|
|
|
//loc += "Lat " + msg['lat'] + " Lon " + msg['lon'];
|
|
|
|
|
loc += "@" + msg['course'] + "°";
|
|
|
|
|
//loc += " Distance " + msg['distance'] + " km";
|
|
|
|
|
loc += " " + dt.toLocaleString();
|
|
|
|
|
return loc;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-20 08:43:57 -04:00
|
|
|
|
function size_dict(d){c=0; for (i in d) ++c; return c}
|
|
|
|
|
|
2023-09-15 14:25:35 -04:00
|
|
|
|
function raise_error(msg) {
|
|
|
|
|
$.toast({
|
|
|
|
|
heading: 'Error',
|
|
|
|
|
text: msg,
|
|
|
|
|
loader: true,
|
|
|
|
|
loaderBg: '#9EC600',
|
|
|
|
|
position: 'top-center',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-20 08:43:57 -04:00
|
|
|
|
function init_chat() {
|
|
|
|
|
socket.on('connect', function () {
|
|
|
|
|
console.log("Connected to socketio");
|
|
|
|
|
});
|
|
|
|
|
socket.on('connected', function(msg) {
|
|
|
|
|
console.log("Connected!");
|
|
|
|
|
console.log(msg);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
socket.on("sent", function(msg) {
|
2023-09-05 14:14:52 -04:00
|
|
|
|
if (cleared === false) {
|
2022-07-20 08:43:57 -04:00
|
|
|
|
var msgsdiv = $("#msgsTabsDiv");
|
2023-09-05 14:14:52 -04:00
|
|
|
|
msgsdiv.html('');
|
|
|
|
|
cleared = true;
|
2022-07-20 08:43:57 -04:00
|
|
|
|
}
|
2023-09-05 14:14:52 -04:00
|
|
|
|
msg["type"] = MSG_TYPE_TX;
|
2022-07-20 08:43:57 -04:00
|
|
|
|
sent_msg(msg);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
socket.on("ack", function(msg) {
|
2023-09-05 14:14:52 -04:00
|
|
|
|
msg["type"] = MSG_TYPE_ACK;
|
|
|
|
|
ack_msg(msg);
|
2022-07-20 08:43:57 -04:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
socket.on("new", function(msg) {
|
2023-09-05 14:14:52 -04:00
|
|
|
|
if (cleared === false) {
|
2022-07-20 08:43:57 -04:00
|
|
|
|
var msgsdiv = $("#msgsTabsDiv");
|
|
|
|
|
msgsdiv.html('')
|
2023-09-05 14:14:52 -04:00
|
|
|
|
cleared = true;
|
2022-07-20 08:43:57 -04:00
|
|
|
|
}
|
2023-09-05 14:14:52 -04:00
|
|
|
|
msg["type"] = MSG_TYPE_RX;
|
2022-07-20 08:43:57 -04:00
|
|
|
|
from_msg(msg);
|
|
|
|
|
});
|
|
|
|
|
|
2024-02-06 13:50:51 -05:00
|
|
|
|
socket.on("callsign_location", function(msg) {
|
|
|
|
|
console.log("CALLSIGN Location!");
|
|
|
|
|
console.log(msg);
|
2024-02-19 20:15:56 -05:00
|
|
|
|
now = new Date();
|
|
|
|
|
msg['last_updated'] = now;
|
2024-02-06 13:50:51 -05:00
|
|
|
|
callsign_location[msg['callsign']] = msg;
|
|
|
|
|
|
2024-02-19 20:15:56 -05:00
|
|
|
|
location_id = callsign_location_content(msg['callsign'], true);
|
|
|
|
|
location_string = build_location_string_small(msg);
|
|
|
|
|
$(location_id).html(location_string);
|
|
|
|
|
$(location_id+"Spinner").addClass('d-none');
|
2024-02-06 13:50:51 -05:00
|
|
|
|
save_data();
|
|
|
|
|
});
|
|
|
|
|
|
2022-07-20 08:43:57 -04:00
|
|
|
|
$("#sendform").submit(function(event) {
|
|
|
|
|
event.preventDefault();
|
2023-09-15 14:25:35 -04:00
|
|
|
|
to_call = $('#to_call').val();
|
|
|
|
|
message = $('#message').val();
|
2023-10-05 10:33:07 -04:00
|
|
|
|
path = $('#pkt_path option:selected').val();
|
2023-09-15 14:25:35 -04:00
|
|
|
|
if (to_call == "") {
|
|
|
|
|
raise_error("You must enter a callsign to send a message")
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
if (message == "") {
|
|
|
|
|
raise_error("You must enter a message to send")
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2023-10-05 10:33:07 -04:00
|
|
|
|
msg = {'to': to_call, 'message': message, 'path': path};
|
2024-02-06 13:50:51 -05:00
|
|
|
|
//console.log(msg);
|
2023-09-15 14:25:35 -04:00
|
|
|
|
socket.emit("send", msg);
|
|
|
|
|
$('#message').val('');
|
|
|
|
|
}
|
2022-07-20 08:43:57 -04:00
|
|
|
|
});
|
2022-11-24 11:27:58 -05:00
|
|
|
|
|
2022-11-30 15:17:28 -05:00
|
|
|
|
init_gps();
|
2023-09-05 14:14:52 -04:00
|
|
|
|
// Try and load any existing chat threads from last time
|
|
|
|
|
init_messages();
|
2022-11-24 11:27:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-06 13:50:51 -05:00
|
|
|
|
|
2023-09-08 12:34:13 -04:00
|
|
|
|
function tab_string(callsign, id=false) {
|
|
|
|
|
name = "msgs"+callsign;
|
|
|
|
|
if (id) {
|
|
|
|
|
return "#"+name;
|
|
|
|
|
} else {
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-15 09:13:51 -04:00
|
|
|
|
function tab_li_string(callsign, id=false) {
|
|
|
|
|
//The id of the LI containing the tab
|
|
|
|
|
return tab_string(callsign,id)+"Li";
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-21 16:29:15 -04:00
|
|
|
|
function tab_notification_id(callsign, id=false) {
|
|
|
|
|
// The ID of the span that contains the notification count
|
|
|
|
|
return tab_string(callsign, id)+"notify";
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 12:34:13 -04:00
|
|
|
|
function tab_content_name(callsign, id=false) {
|
|
|
|
|
return tab_string(callsign, id)+"Content";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function tab_content_speech_wrapper(callsign, id=false) {
|
|
|
|
|
return tab_string(callsign, id)+"SpeechWrapper";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function tab_content_speech_wrapper_id(callsign) {
|
|
|
|
|
return "#"+tab_content_speech_wrapper(callsign);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function content_divname(callsign) {
|
|
|
|
|
return "#"+tab_content_name(callsign);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function callsign_tab(callsign) {
|
|
|
|
|
return "#"+tab_string(callsign);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-06 13:50:51 -05:00
|
|
|
|
function callsign_location_popover(callsign, id=false) {
|
|
|
|
|
return tab_string(callsign, id)+"Location";
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-19 20:15:56 -05:00
|
|
|
|
function callsign_location_content(callsign, id=false) {
|
|
|
|
|
return tab_string(callsign, id)+"LocationContent";
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-26 11:58:12 -04:00
|
|
|
|
function bubble_msg_id(msg, id=false) {
|
|
|
|
|
// The id of the div that contains a specific message
|
|
|
|
|
name = msg["from_call"] + "_" + msg["msgNo"];
|
|
|
|
|
if (id) {
|
|
|
|
|
return "#"+name;
|
|
|
|
|
} else {
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-05 14:14:52 -04:00
|
|
|
|
function message_ts_id(msg) {
|
|
|
|
|
//Create a 'id' from the message timestamp
|
2023-09-21 16:29:15 -04:00
|
|
|
|
ts_str = msg["timestamp"].toString();
|
2023-09-05 14:14:52 -04:00
|
|
|
|
ts = ts_str.split(".")[0]*1000;
|
|
|
|
|
id = ts_str.split('.')[0];
|
|
|
|
|
return {'timestamp': ts, 'id': id};
|
|
|
|
|
}
|
2022-07-20 08:43:57 -04:00
|
|
|
|
|
2023-09-05 14:14:52 -04:00
|
|
|
|
function time_ack_from_msg(msg) {
|
|
|
|
|
// Return the time and ack_id from a message
|
|
|
|
|
ts_id = message_ts_id(msg);
|
|
|
|
|
ts = ts_id['timestamp'];
|
|
|
|
|
id = ts_id['id'];
|
|
|
|
|
ack_id = "ack_" + id
|
|
|
|
|
|
|
|
|
|
var d = new Date(ts).toLocaleDateString("en-US")
|
|
|
|
|
var t = new Date(ts).toLocaleTimeString("en-US")
|
|
|
|
|
return {'time': t, 'date': d, 'ack_id': ack_id};
|
|
|
|
|
}
|
2022-07-20 08:43:57 -04:00
|
|
|
|
|
2023-09-05 14:14:52 -04:00
|
|
|
|
function save_data() {
|
|
|
|
|
// Save the relevant data to local storage
|
|
|
|
|
localStorage.setItem('callsign_list', JSON.stringify(callsign_list));
|
|
|
|
|
localStorage.setItem('message_list', JSON.stringify(message_list));
|
2024-02-06 13:50:51 -05:00
|
|
|
|
localStorage.setItem('callsign_location', JSON.stringify(callsign_location));
|
2023-09-05 14:14:52 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function init_messages() {
|
|
|
|
|
// This tries to load any previous conversations from local storage
|
|
|
|
|
callsign_list = JSON.parse(localStorage.getItem('callsign_list'));
|
|
|
|
|
message_list = JSON.parse(localStorage.getItem('message_list'));
|
2024-02-06 13:50:51 -05:00
|
|
|
|
callsign_location = JSON.parse(localStorage.getItem('callsign_location'));
|
2023-09-05 14:14:52 -04:00
|
|
|
|
if (callsign_list == null) {
|
|
|
|
|
callsign_list = {};
|
|
|
|
|
}
|
|
|
|
|
if (message_list == null) {
|
|
|
|
|
message_list = {};
|
|
|
|
|
}
|
2024-02-06 13:50:51 -05:00
|
|
|
|
if (callsign_location == null) {
|
|
|
|
|
callsign_location = {};
|
|
|
|
|
}
|
|
|
|
|
console.log(callsign_list);
|
|
|
|
|
console.log(message_list);
|
|
|
|
|
console.log(callsign_location);
|
2023-09-05 14:14:52 -04:00
|
|
|
|
|
|
|
|
|
// Now loop through each callsign and add the tabs
|
|
|
|
|
first_callsign = null;
|
|
|
|
|
for (callsign in callsign_list) {
|
|
|
|
|
if (first_callsign === null) {
|
|
|
|
|
first_callsign = callsign;
|
2023-09-08 11:19:24 -04:00
|
|
|
|
active = true;
|
|
|
|
|
} else {
|
|
|
|
|
active = false;
|
2023-09-05 14:14:52 -04:00
|
|
|
|
}
|
2023-09-08 11:19:24 -04:00
|
|
|
|
create_callsign_tab(callsign, active);
|
2023-09-05 14:14:52 -04:00
|
|
|
|
}
|
|
|
|
|
// and then populate the messages in order
|
|
|
|
|
for (callsign in message_list) {
|
|
|
|
|
new_callsign = true;
|
|
|
|
|
cleared = true;
|
|
|
|
|
for (id in message_list[callsign]) {
|
|
|
|
|
msg = message_list[callsign][id];
|
|
|
|
|
info = time_ack_from_msg(msg);
|
|
|
|
|
t = info['time'];
|
2023-09-06 11:20:59 -04:00
|
|
|
|
d = info['date'];
|
2023-09-05 14:14:52 -04:00
|
|
|
|
ack_id = false;
|
|
|
|
|
acked = false;
|
|
|
|
|
if (msg['type'] == MSG_TYPE_TX) {
|
|
|
|
|
ack_id = info['ack_id'];
|
|
|
|
|
acked = msg['ack'];
|
|
|
|
|
}
|
2023-09-21 16:29:15 -04:00
|
|
|
|
msg_html = create_message_html(d, t, msg['from_call'], msg['to_call'],
|
|
|
|
|
msg['message_text'], ack_id, msg, acked);
|
2023-09-05 14:14:52 -04:00
|
|
|
|
append_message_html(callsign, msg_html, new_callsign);
|
|
|
|
|
new_callsign = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-15 14:25:35 -04:00
|
|
|
|
|
|
|
|
|
if (first_callsign !== null) {
|
|
|
|
|
callsign_select(first_callsign);
|
|
|
|
|
}
|
2023-09-05 14:14:52 -04:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-15 14:12:55 -04:00
|
|
|
|
function scroll_main_content(callsign=false) {
|
|
|
|
|
var wc = $('#wc-content');
|
|
|
|
|
var d = $('#msgsTabContent');
|
|
|
|
|
var scrollHeight = wc.prop('scrollHeight');
|
|
|
|
|
var clientHeight = wc.prop('clientHeight');
|
|
|
|
|
|
|
|
|
|
if (callsign) {
|
|
|
|
|
div_id = content_divname(callsign);
|
|
|
|
|
c_div = $(content_divname(callsign));
|
|
|
|
|
//console.log("c_div("+div_id+") " + c_div);
|
|
|
|
|
c_height = c_div.height();
|
|
|
|
|
c_scroll_height = c_div.prop('scrollHeight');
|
|
|
|
|
//console.log("callsign height " + c_height + " scrollHeight " + c_scroll_height);
|
|
|
|
|
if (c_height === undefined) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (c_height > clientHeight) {
|
|
|
|
|
wc.animate({ scrollTop: c_scroll_height }, 500);
|
|
|
|
|
} else {
|
|
|
|
|
wc.animate({ scrollTop: 0 }, 500);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (scrollHeight > clientHeight) {
|
|
|
|
|
wc.animate({ scrollTop: wc.prop('scrollHeight') }, 500);
|
|
|
|
|
} else {
|
|
|
|
|
wc.animate({ scrollTop: 0 }, 500);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 11:19:24 -04:00
|
|
|
|
function create_callsign_tab(callsign, active=false) {
|
2023-09-05 14:14:52 -04:00
|
|
|
|
//Create the html for the callsign tab and insert it into the DOM
|
2023-09-08 11:19:24 -04:00
|
|
|
|
var callsignTabs = $("#msgsTabList");
|
|
|
|
|
tab_id = tab_string(callsign);
|
2023-09-15 09:13:51 -04:00
|
|
|
|
tab_id_li = tab_li_string(callsign);
|
2023-09-21 16:29:15 -04:00
|
|
|
|
tab_notify_id = tab_notification_id(callsign);
|
2022-07-20 08:43:57 -04:00
|
|
|
|
tab_content = tab_content_name(callsign);
|
2024-02-06 13:50:51 -05:00
|
|
|
|
popover_id = callsign_location_popover(callsign);
|
2023-09-08 11:19:24 -04:00
|
|
|
|
if (active) {
|
|
|
|
|
active_str = "active";
|
|
|
|
|
} else {
|
|
|
|
|
active_str = "";
|
|
|
|
|
}
|
2022-07-20 08:43:57 -04:00
|
|
|
|
|
2023-09-15 09:13:51 -04:00
|
|
|
|
item_html = '<li class="nav-item" role="presentation" callsign="'+callsign+'" id="'+tab_id_li+'">';
|
2023-09-21 16:29:15 -04:00
|
|
|
|
//item_html += '<button onClick="callsign_select(\''+callsign+'\');" callsign="'+callsign+'" class="nav-link '+active_str+'" id="'+tab_id+'" data-bs-toggle="tab" data-bs-target="#'+tab_content+'" type="button" role="tab" aria-controls="'+callsign+'" aria-selected="true">';
|
|
|
|
|
item_html += '<button onClick="callsign_select(\''+callsign+'\');" callsign="'+callsign+'" class="nav-link position-relative '+active_str+'" id="'+tab_id+'" data-bs-toggle="tab" data-bs-target="#'+tab_content+'" type="button" role="tab" aria-controls="'+callsign+'" aria-selected="true">';
|
2023-09-08 12:34:13 -04:00
|
|
|
|
item_html += callsign+' ';
|
|
|
|
|
item_html += '<span onclick="delete_tab(\''+callsign+'\');">×</span>';
|
|
|
|
|
item_html += '</button></li>'
|
2024-02-06 13:50:51 -05:00
|
|
|
|
|
2022-07-20 08:43:57 -04:00
|
|
|
|
callsignTabs.append(item_html);
|
2023-09-08 11:19:24 -04:00
|
|
|
|
create_callsign_tab_content(callsign, active);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function create_callsign_tab_content(callsign, active=false) {
|
|
|
|
|
var callsignTabsContent = $("#msgsTabContent");
|
|
|
|
|
tab_id = tab_string(callsign);
|
|
|
|
|
tab_content = tab_content_name(callsign);
|
|
|
|
|
wrapper_id = tab_content_speech_wrapper(callsign);
|
|
|
|
|
if (active) {
|
|
|
|
|
active_str = "show active";
|
|
|
|
|
} else {
|
|
|
|
|
active_str = '';
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-19 20:15:56 -05:00
|
|
|
|
location_str = "Unknown Location"
|
|
|
|
|
if (callsign in callsign_location) {
|
|
|
|
|
location_str = build_location_string_small(callsign_location[callsign]);
|
|
|
|
|
location_class = '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
location_id = callsign_location_content(callsign);
|
|
|
|
|
|
2023-09-08 11:19:24 -04:00
|
|
|
|
item_html = '<div class="tab-pane fade '+active_str+'" id="'+tab_content+'" role="tabpanel" aria-labelledby="'+tab_id+'">';
|
2024-02-19 20:15:56 -05:00
|
|
|
|
item_html += '<div class="" style="border: 1px solid #999999;background-color:#aaaaaa;">';
|
|
|
|
|
item_html += '<div class="row" style="padding-top:4px;padding-bottom:4px;background-color:#aaaaaa;margin:0px;">';
|
|
|
|
|
item_html += '<div class="d-flex col-md-10 justify-content-left" style="padding:0px;margin:0px;">';
|
|
|
|
|
item_html += '<button onclick="call_callsign_location(\''+callsign+'\');" style="margin-left:2px;padding: 0px 4px 0px 4px;" type="button" class="btn btn-primary">';
|
|
|
|
|
item_html += '<span id="'+location_id+'Spinner" class="d-none spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>Update</button>';
|
|
|
|
|
item_html += ' <span id="'+location_id+'">'+location_str+'</span></div>';
|
|
|
|
|
item_html += '</div>';
|
2023-09-08 11:19:24 -04:00
|
|
|
|
item_html += '<div class="speech-wrapper" id="'+wrapper_id+'"></div>';
|
|
|
|
|
item_html += '</div>';
|
|
|
|
|
callsignTabsContent.append(item_html);
|
2023-09-05 14:14:52 -04:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 12:34:13 -04:00
|
|
|
|
function delete_tab(callsign) {
|
|
|
|
|
// User asked to delete the tab and the conversation
|
|
|
|
|
tab_id = tab_string(callsign, true);
|
2023-09-15 09:13:51 -04:00
|
|
|
|
tab_id_li = tab_li_string(callsign, true);
|
2023-09-08 12:34:13 -04:00
|
|
|
|
tab_content = tab_content_name(callsign, true);
|
2023-09-15 09:13:51 -04:00
|
|
|
|
$(tab_id_li).remove();
|
2023-09-08 12:34:13 -04:00
|
|
|
|
$(tab_content).remove();
|
|
|
|
|
delete callsign_list[callsign];
|
|
|
|
|
delete message_list[callsign];
|
2024-02-06 13:50:51 -05:00
|
|
|
|
delete callsign_location[callsign];
|
2023-09-08 12:34:13 -04:00
|
|
|
|
|
|
|
|
|
// Now select the first tab
|
|
|
|
|
first_tab = $("#msgsTabList").children().first().children().first();
|
2023-09-15 09:13:51 -04:00
|
|
|
|
console.log(first_tab);
|
2023-09-08 12:34:13 -04:00
|
|
|
|
$(first_tab).click();
|
|
|
|
|
save_data();
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-05 10:33:07 -04:00
|
|
|
|
function add_callsign(callsign, msg) {
|
2023-09-05 14:14:52 -04:00
|
|
|
|
/* Ensure a callsign exists in the left hand nav */
|
|
|
|
|
if (callsign in callsign_list) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
2023-09-08 11:19:24 -04:00
|
|
|
|
len = Object.keys(callsign_list).length;
|
|
|
|
|
if (len == 0) {
|
|
|
|
|
active = true;
|
|
|
|
|
} else {
|
|
|
|
|
active = false;
|
|
|
|
|
}
|
|
|
|
|
create_callsign_tab(callsign, active);
|
2023-10-05 10:33:07 -04:00
|
|
|
|
callsign_list[callsign] = '';
|
2023-09-15 14:25:35 -04:00
|
|
|
|
return true;
|
2022-07-20 08:43:57 -04:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-19 20:15:56 -05:00
|
|
|
|
function update_callsign_path(callsign, msg) {
|
2023-10-05 10:33:07 -04:00
|
|
|
|
//Get the selected path to save for this callsign
|
|
|
|
|
path = msg['path']
|
|
|
|
|
$('#pkt_path').val(path);
|
|
|
|
|
callsign_list[callsign] = path;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-20 08:43:57 -04:00
|
|
|
|
function append_message(callsign, msg, msg_html) {
|
|
|
|
|
new_callsign = false
|
|
|
|
|
if (!message_list.hasOwnProperty(callsign)) {
|
2023-09-05 14:14:52 -04:00
|
|
|
|
message_list[callsign] = {};
|
2022-07-20 08:43:57 -04:00
|
|
|
|
}
|
2023-09-05 14:14:52 -04:00
|
|
|
|
ts_id = message_ts_id(msg);
|
|
|
|
|
id = ts_id['id']
|
|
|
|
|
message_list[callsign][id] = msg;
|
2023-09-21 16:29:15 -04:00
|
|
|
|
if (selected_tab_callsign != callsign) {
|
|
|
|
|
// We need to update the notification for the tab
|
|
|
|
|
tab_notify_id = tab_notification_id(callsign, true);
|
|
|
|
|
// get the current count of notifications
|
|
|
|
|
count = parseInt($(tab_notify_id).text());
|
|
|
|
|
count += 1;
|
|
|
|
|
$(tab_notify_id).text(count);
|
|
|
|
|
$(tab_notify_id).removeClass('visually-hidden');
|
|
|
|
|
}
|
2022-07-20 08:43:57 -04:00
|
|
|
|
|
|
|
|
|
// Find the right div to place the html
|
2023-10-05 10:33:07 -04:00
|
|
|
|
new_callsign = add_callsign(callsign, msg);
|
2024-02-19 20:15:56 -05:00
|
|
|
|
update_callsign_path(callsign, msg);
|
2022-07-20 08:43:57 -04:00
|
|
|
|
append_message_html(callsign, msg_html, new_callsign);
|
2024-02-19 20:15:56 -05:00
|
|
|
|
len = Object.keys(callsign_list).length;
|
|
|
|
|
if (new_callsign && len == 1) {
|
|
|
|
|
//Now click the tab if and only if there is only one tab
|
2023-09-08 11:19:24 -04:00
|
|
|
|
callsign_tab_id = callsign_tab(callsign);
|
2023-09-26 10:31:00 -04:00
|
|
|
|
$(callsign_tab_id).click();
|
|
|
|
|
callsign_select(callsign);
|
2022-07-20 08:43:57 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 11:19:24 -04:00
|
|
|
|
|
2022-07-20 08:43:57 -04:00
|
|
|
|
function append_message_html(callsign, msg_html, new_callsign) {
|
|
|
|
|
var msgsTabs = $('#msgsTabsDiv');
|
|
|
|
|
divname_str = tab_content_name(callsign);
|
|
|
|
|
divname = content_divname(callsign);
|
2023-09-08 11:19:24 -04:00
|
|
|
|
tab_content = tab_content_name(callsign);
|
|
|
|
|
wrapper_id = tab_content_speech_wrapper_id(callsign);
|
|
|
|
|
|
|
|
|
|
$(wrapper_id).append(msg_html);
|
|
|
|
|
|
|
|
|
|
if ($(wrapper_id).children().length > 0) {
|
|
|
|
|
$(wrapper_id).animate({scrollTop: $(wrapper_id)[0].scrollHeight}, "fast");
|
2023-09-05 14:14:52 -04:00
|
|
|
|
}
|
2022-07-20 08:43:57 -04:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-06 11:20:59 -04:00
|
|
|
|
function create_message_html(date, time, from, to, message, ack_id, msg, acked=false) {
|
2023-09-26 11:04:59 -04:00
|
|
|
|
div_id = from + "_" + msg.msgNo;
|
2023-09-06 11:20:59 -04:00
|
|
|
|
if (ack_id) {
|
2023-09-08 11:19:24 -04:00
|
|
|
|
alt = " alt"
|
2023-09-06 11:20:59 -04:00
|
|
|
|
} else {
|
2023-09-08 11:19:24 -04:00
|
|
|
|
alt = ""
|
2023-09-06 11:20:59 -04:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-21 16:29:15 -04:00
|
|
|
|
bubble_class = "bubble" + alt + " text-nowrap"
|
2023-09-08 11:19:24 -04:00
|
|
|
|
bubble_name_class = "bubble-name" + alt
|
2023-09-26 11:58:12 -04:00
|
|
|
|
bubble_msgid = bubble_msg_id(msg);
|
2023-09-06 11:20:59 -04:00
|
|
|
|
date_str = date + " " + time;
|
2023-09-21 16:29:15 -04:00
|
|
|
|
sane_date_str = date_str.replace(/ /g,"").replaceAll("/","").replaceAll(":","");
|
2023-09-06 11:20:59 -04:00
|
|
|
|
|
2024-02-06 13:50:51 -05:00
|
|
|
|
bubble_msg_class = "bubble-message";
|
|
|
|
|
if (ack_id) {
|
|
|
|
|
bubble_arrow_class = "bubble-arrow alt";
|
|
|
|
|
popover_placement = "left";
|
|
|
|
|
} else {
|
|
|
|
|
bubble_arrow_class = "bubble-arrow";
|
|
|
|
|
popover_placement = "right";
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 11:19:24 -04:00
|
|
|
|
msg_html = '<div class="bubble-row'+alt+'">';
|
2024-02-06 13:50:51 -05:00
|
|
|
|
msg_html += '<div id="'+bubble_msgid+'" class="'+ bubble_class + '" ';
|
|
|
|
|
msg_html += 'title="APRS Raw Packet" data-bs-placement="'+popover_placement+'" data-bs-toggle="popover" ';
|
|
|
|
|
msg_html += 'data-bs-trigger="hover" data-bs-content="'+msg['raw']+'">';
|
2023-09-06 11:20:59 -04:00
|
|
|
|
msg_html += '<div class="bubble-text">';
|
|
|
|
|
msg_html += '<p class="'+ bubble_name_class +'">'+from+' ';
|
|
|
|
|
msg_html += '<span class="bubble-timestamp">'+date_str+'</span>';
|
2024-02-06 13:50:51 -05:00
|
|
|
|
|
2023-09-05 14:14:52 -04:00
|
|
|
|
if (ack_id) {
|
|
|
|
|
if (acked) {
|
2023-09-21 16:29:15 -04:00
|
|
|
|
msg_html += '<span class="material-symbols-rounded md-10" id="' + ack_id + '">thumb_up</span>';
|
2023-09-05 14:14:52 -04:00
|
|
|
|
} else {
|
2023-09-21 16:29:15 -04:00
|
|
|
|
msg_html += '<span class="material-symbols-rounded md-10" id="' + ack_id + '">thumb_down</span>';
|
2023-09-05 14:14:52 -04:00
|
|
|
|
}
|
2023-09-06 11:20:59 -04:00
|
|
|
|
}
|
|
|
|
|
msg_html += "</p>";
|
|
|
|
|
msg_html += '<p class="' +bubble_msg_class+ '">'+message+'</p>';
|
|
|
|
|
msg_html += '<div class="'+ bubble_arrow_class + '"></div>';
|
2023-09-08 11:19:24 -04:00
|
|
|
|
msg_html += "</div></div></div>";
|
2022-07-20 08:43:57 -04:00
|
|
|
|
|
2024-02-06 13:50:51 -05:00
|
|
|
|
return msg_html
|
2022-07-20 08:43:57 -04:00
|
|
|
|
}
|
|
|
|
|
|
2023-08-22 13:37:43 -04:00
|
|
|
|
function flash_message(msg) {
|
|
|
|
|
// Callback function to bring a hidden box back
|
2023-09-26 11:58:12 -04:00
|
|
|
|
msg_id = bubble_msg_id(msg, true);
|
|
|
|
|
$(msg_id).fadeOut(100).fadeIn(100).fadeOut(100).fadeIn(100).fadeOut(100).fadeIn(100);
|
2023-08-22 13:37:43 -04:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-05 14:14:52 -04:00
|
|
|
|
function sent_msg(msg) {
|
|
|
|
|
info = time_ack_from_msg(msg);
|
|
|
|
|
t = info['time'];
|
2023-09-06 11:20:59 -04:00
|
|
|
|
d = info['date'];
|
2023-09-05 14:14:52 -04:00
|
|
|
|
ack_id = info['ack_id'];
|
2022-07-20 08:43:57 -04:00
|
|
|
|
|
2023-09-21 16:29:15 -04:00
|
|
|
|
msg_html = create_message_html(d, t, msg['from_call'], msg['to_call'], msg['message_text'], ack_id, msg, false);
|
|
|
|
|
append_message(msg['to_call'], msg, msg_html);
|
2023-09-05 14:14:52 -04:00
|
|
|
|
save_data();
|
2024-04-09 10:07:12 -04:00
|
|
|
|
scroll_main_content(msg['to_call']);
|
2022-07-20 08:43:57 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function from_msg(msg) {
|
2023-09-26 11:58:12 -04:00
|
|
|
|
if (!from_msg_list.hasOwnProperty(msg["from_call"])) {
|
|
|
|
|
from_msg_list[msg["from_call"]] = new Array();
|
2023-08-22 13:37:43 -04:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-26 11:58:12 -04:00
|
|
|
|
if (msg["msgNo"] in from_msg_list[msg["from_call"]]) {
|
2023-08-22 13:37:43 -04:00
|
|
|
|
// We already have this message
|
2024-02-19 20:15:56 -05:00
|
|
|
|
//console.log("We already have this message msgNo=" + msg["msgNo"]);
|
2023-08-22 13:37:43 -04:00
|
|
|
|
// Do some flashy thing?
|
|
|
|
|
flash_message(msg);
|
|
|
|
|
return false
|
|
|
|
|
} else {
|
2023-09-26 11:58:12 -04:00
|
|
|
|
from_msg_list[msg["from_call"]][msg["msgNo"]] = msg
|
2023-08-22 13:37:43 -04:00
|
|
|
|
}
|
2023-09-05 14:14:52 -04:00
|
|
|
|
info = time_ack_from_msg(msg);
|
|
|
|
|
t = info['time'];
|
2023-09-06 11:20:59 -04:00
|
|
|
|
d = info['date'];
|
2023-09-05 14:14:52 -04:00
|
|
|
|
ack_id = info['ack_id'];
|
2022-07-20 08:43:57 -04:00
|
|
|
|
|
2023-09-21 16:29:15 -04:00
|
|
|
|
from = msg['from_call']
|
|
|
|
|
msg_html = create_message_html(d, t, from, false, msg['message_text'], false, msg, false);
|
2022-07-20 08:43:57 -04:00
|
|
|
|
append_message(from, msg, msg_html);
|
2023-09-05 14:14:52 -04:00
|
|
|
|
save_data();
|
2023-09-15 14:12:55 -04:00
|
|
|
|
scroll_main_content(from);
|
2022-07-20 08:43:57 -04:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-05 14:14:52 -04:00
|
|
|
|
function ack_msg(msg) {
|
|
|
|
|
// Acknowledge a message
|
|
|
|
|
// We have an existing entry
|
|
|
|
|
ts_id = message_ts_id(msg);
|
|
|
|
|
id = ts_id['id'];
|
|
|
|
|
//Mark the message as acked
|
2023-09-21 16:29:15 -04:00
|
|
|
|
callsign = msg['to_call'];
|
2023-09-05 14:14:52 -04:00
|
|
|
|
// Ensure the message_list has this callsign
|
|
|
|
|
if (!message_list.hasOwnProperty(callsign)) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
// Ensure the message_list has this id
|
|
|
|
|
if (!message_list[callsign].hasOwnProperty(id)) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if (message_list[callsign][id]['ack'] == true) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
message_list[callsign][id]['ack'] = true;
|
|
|
|
|
ack_id = "ack_" + id
|
2022-07-20 08:43:57 -04:00
|
|
|
|
|
2023-09-05 14:14:52 -04:00
|
|
|
|
if (msg['ack'] == true) {
|
|
|
|
|
var ack_div = $('#' + ack_id);
|
2023-09-06 11:20:59 -04:00
|
|
|
|
ack_div.html('thumb_up');
|
2023-09-05 14:14:52 -04:00
|
|
|
|
}
|
2022-07-20 08:43:57 -04:00
|
|
|
|
|
2023-09-15 09:13:51 -04:00
|
|
|
|
//$('.ui.accordion').accordion('refresh');
|
2023-09-05 14:14:52 -04:00
|
|
|
|
save_data();
|
2023-09-15 14:12:55 -04:00
|
|
|
|
scroll_main_content();
|
2022-07-20 08:43:57 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function callsign_select(callsign) {
|
2023-09-21 16:29:15 -04:00
|
|
|
|
var tocall = $("#to_call");
|
|
|
|
|
tocall.val(callsign);
|
|
|
|
|
scroll_main_content(callsign);
|
|
|
|
|
selected_tab_callsign = callsign;
|
|
|
|
|
tab_notify_id = tab_notification_id(callsign, true);
|
|
|
|
|
$(tab_notify_id).addClass('visually-hidden');
|
|
|
|
|
$(tab_notify_id).text(0);
|
2023-10-05 10:33:07 -04:00
|
|
|
|
// Now update the path
|
|
|
|
|
$('#pkt_path').val(callsign_list[callsign]);
|
2022-07-20 08:43:57 -04:00
|
|
|
|
}
|
2024-02-19 20:15:56 -05:00
|
|
|
|
|
|
|
|
|
function call_callsign_location(callsign) {
|
|
|
|
|
msg = {'callsign': callsign};
|
|
|
|
|
socket.emit("get_callsign_location", msg);
|
|
|
|
|
location_id = callsign_location_content(callsign, true)+"Spinner";
|
|
|
|
|
$(location_id).removeClass('d-none');
|
|
|
|
|
}
|