1
0
mirror of https://github.com/craigerl/aprsd.git synced 2025-07-30 20:32:27 -04:00

Reworked webchat with new UI

This patch reworks the webchat UI to work in both desktop
and mobile layouts.  Comprimises were made, but there is 1
codebase now between both desktop and mobile.
This patch also includes the new imessage/sms chat look.
This commit is contained in:
Hemna 2023-09-08 11:19:24 -04:00
parent 29f21a9469
commit 14e984c9b4
3 changed files with 118 additions and 159 deletions

View File

@ -1,6 +1,6 @@
body { body {
background: #eeeeee; background: #eeeeee;
margin: 2em; margin: 1em;
text-align: center; text-align: center;
font-family: system-ui, sans-serif; font-family: system-ui, sans-serif;
} }
@ -11,34 +11,13 @@ footer {
height: 10vh; height: 10vh;
} }
.ui.segment {
background: #eeeeee;
}
ul.list {
list-style-type: disc;
}
ul.list li {
list-style-position: outside;
}
#left {
margin-right: 2px;
height: 300px;
}
#right {
height: 300px;
}
#center {
height: 300px;
}
#title { #title {
font-size: 4em; font-size: 4em;
} }
#version{ #version{
font-size: .5em; font-size: .5em;
} }
#uptime, #aprsis { #uptime, #aprsis {
font-size: 1em; font-size: 1em;
} }
@ -66,29 +45,3 @@ ul.list li {
width: 16px; width: 16px;
height: 16px; height: 16px;
} }
#msgsTabsDiv .ui.tab {
margin:0px;
padding:0px;
display: block;
}
#msgsTabsDiv .header, .tiny.text, .content, .break,
.thumbs.down.outline.icon,
.phone.volume.icon
{
display: inline-block;
float: left;
position: relative;
}
#msgsTabsDiv .tiny.text {
width:100px;
}
#msgsTabsDiv .tiny.header {
width:100px;
text-align: left;
}
#msgsTabsDiv .break {
margin: 2px;
text-align: left;
}

View File

@ -105,9 +105,12 @@ function init_messages() {
console.log("Adding callsign " + callsign); console.log("Adding callsign " + callsign);
if (first_callsign === null) { if (first_callsign === null) {
first_callsign = callsign; first_callsign = callsign;
active = true;
console.log("first_callsign " + first_callsign) console.log("first_callsign " + first_callsign)
} else {
active = false;
} }
create_callsign_tab(callsign); create_callsign_tab(callsign, active);
} }
// and then populate the messages in order // and then populate the messages in order
for (callsign in message_list) { for (callsign in message_list) {
@ -131,27 +134,54 @@ function init_messages() {
} }
//Click on the very first tab //Click on the very first tab
/*
if (first_callsign !== null) { if (first_callsign !== null) {
click_div = '#'+tab_string(first_callsign); callsign_tab_id = callsign_tab(first_callsign);
var click_timer = setTimeout(function() { var click_timer = setTimeout(function() {
console.log("Click on first tab " + click_div); console.log("Click on first tab " + callsign_tab_id);
$(click_div).click(); $(callsign_tab_id).click();
clearTimeout(click_timer); clearTimeout(click_timer);
}, 500); }, 500);
} }
*/
} }
function create_callsign_tab(callsign) { function create_callsign_tab(callsign, active=false) {
//Create the html for the callsign tab and insert it into the DOM //Create the html for the callsign tab and insert it into the DOM
console.log("create_callsign_tab " + callsign) console.log("create_callsign_tab " + callsign)
var callsignTabs = $("#callsignTabs"); var callsignTabs = $("#msgsTabList");
tab_name = tab_string(callsign); tab_id = tab_string(callsign);
tab_content = tab_content_name(callsign); tab_content = tab_content_name(callsign);
divname = content_divname(callsign); if (active) {
active_str = "active";
} else {
active_str = "";
}
item_html = '<div class="tablinks" id="'+tab_name+'" onclick="openCallsign(event, \''+callsign+'\');">'+callsign+'</div>'; item_html = '<li class="nav-item" role="presentation">';
item_html += '<button 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">'+callsign+'</button>';
item_html += '</li>';
console.log(item_html); console.log(item_html);
callsignTabs.append(item_html); callsignTabs.append(item_html);
create_callsign_tab_content(callsign, active);
}
function create_callsign_tab_content(callsign, active=false) {
console.log("create_callsign_tab_content for CALLSIGN=" + callsign)
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 = '';
}
item_html = '<div class="tab-pane fade '+active_str+'" id="'+tab_content+'" role="tabpanel" aria-labelledby="'+tab_id+'">';
item_html += '<div class="speech-wrapper" id="'+wrapper_id+'"></div>';
item_html += '</div>';
callsignTabsContent.append(item_html);
} }
function add_callsign(callsign) { function add_callsign(callsign) {
@ -159,7 +189,13 @@ function add_callsign(callsign) {
if (callsign in callsign_list) { if (callsign in callsign_list) {
return false return false
} }
create_callsign_tab(callsign); len = Object.keys(callsign_list).length;
if (len == 0) {
active = true;
} else {
active = false;
}
create_callsign_tab(callsign, active);
callsign_list[callsign] = true; callsign_list[callsign] = true;
return true return true
} }
@ -179,9 +215,9 @@ function append_message(callsign, msg, msg_html) {
new_callsign = add_callsign(callsign); new_callsign = add_callsign(callsign);
append_message_html(callsign, msg_html, new_callsign); append_message_html(callsign, msg_html, new_callsign);
if (new_callsign) { if (new_callsign) {
//click on the new tab //Now click the tab
click_div = '#'+tab_string(callsign); callsign_tab_id = callsign_tab(callsign);
$(click_div).click(); $(callsign_tab_id).click();
} }
} }
@ -193,50 +229,57 @@ function tab_content_name(callsign) {
return tab_string(callsign)+"Content"; return tab_string(callsign)+"Content";
} }
function tab_content_speech_wrapper(callsign) {
return tab_string(callsign)+"SpeechWrapper";
}
function tab_content_speech_wrapper_id(callsign) {
return "#"+tab_content_speech_wrapper(callsign);
}
function content_divname(callsign) { function content_divname(callsign) {
return "#"+tab_content_name(callsign); return "#"+tab_content_name(callsign);
} }
function callsign_tab(callsign) {
return "#"+tab_string(callsign);
}
function append_message_html(callsign, msg_html, new_callsign) { function append_message_html(callsign, msg_html, new_callsign) {
var msgsTabs = $('#msgsTabsDiv'); var msgsTabs = $('#msgsTabsDiv');
console.log("append_message_html " + callsign + " " + msg_html + " " + new_callsign); console.log("append_message_html " + callsign + " new callsign? " + new_callsign);
divname_str = tab_content_name(callsign); divname_str = tab_content_name(callsign);
divname = content_divname(callsign); divname = content_divname(callsign);
if (new_callsign) { tab_content = tab_content_name(callsign);
// we have to add a new DIV wrapper_id = tab_content_speech_wrapper_id(callsign);
console.log("new callsign, create msg_div_html ");
msg_div_html = '<div class="speech-wrapper" id="'+divname_str+'">'+msg_html+'</div>';
console.log(msg_div_html);
msgsTabs.append(msg_div_html);
} else {
var msgDiv = $(divname);
console.log("Appending ("+ msg_html + ") to " + divname);
console.log(msgDiv);
msgDiv.append(msg_html);
console.log(msgDiv);
}
console.log("divname " + divname);
console.log($(divname).length);
if ($(divname).length > 0) { console.log("Appending ("+ msg_html + ") to " + wrapper_id);
$(divname).animate({scrollTop: $(divname)[0].scrollHeight}, "fast"); $(wrapper_id).append(msg_html);
console.log($(wrapper_id).html());
console.log("wrapper_id " + wrapper_id);
console.log($(wrapper_id).children().length);
if ($(wrapper_id).children().length > 0) {
$(wrapper_id).animate({scrollTop: $(wrapper_id)[0].scrollHeight}, "fast");
} }
$(divname).trigger('click');
} }
function create_message_html(date, time, from, to, message, ack_id, msg, acked=false) { function create_message_html(date, time, from, to, message, ack_id, msg, acked=false) {
div_id = from + "_" + msg.id; div_id = from + "_" + msg.id;
if (ack_id) { if (ack_id) {
bubble_class = "bubble alt" alt = " alt"
bubble_name_class = "bubble-name alt"
} else { } else {
bubble_class = "bubble" alt = ""
bubble_name_class = "bubble-name"
} }
bubble_class = "bubble" + alt
bubble_name_class = "bubble-name" + alt
date_str = date + " " + time; date_str = date + " " + time;
msg_html = '<div class="'+ bubble_class + '">'; msg_html = '<div class="bubble-row'+alt+'">';
msg_html += '<div class="'+ bubble_class + '">';
msg_html += '<div class="bubble-text">'; msg_html += '<div class="bubble-text">';
msg_html += '<p class="'+ bubble_name_class +'">'+from+'&nbsp;&nbsp;'; msg_html += '<p class="'+ bubble_name_class +'">'+from+'&nbsp;&nbsp;';
msg_html += '<span class="bubble-timestamp">'+date_str+'</span>'; msg_html += '<span class="bubble-timestamp">'+date_str+'</span>';
@ -257,7 +300,7 @@ function create_message_html(date, time, from, to, message, ack_id, msg, acked=f
msg_html += '<p class="' +bubble_msg_class+ '">'+message+'</p>'; msg_html += '<p class="' +bubble_msg_class+ '">'+message+'</p>';
msg_html += '<div class="'+ bubble_arrow_class + '"></div>'; msg_html += '<div class="'+ bubble_arrow_class + '"></div>';
msg_html += "</div></div>"; msg_html += "</div></div></div>";
return msg_html return msg_html
} }
@ -355,34 +398,3 @@ function callsign_select(callsign) {
var tocall = $("#to_call"); var tocall = $("#to_call");
tocall.val(callsign); tocall.val(callsign);
} }
function reset_Tabs() {
tabcontent = document.getElementsByClassName("speech-wrapper");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
}
function openCallsign(evt, callsign) {
// This is called when a callsign tab is clicked
var i, tabcontent, tablinks;
tab_content = tab_content_name(callsign);
console.log("openCallsign " + tab_content);
tabs = document.getElementsByClassName("speech-wrapper");
console.log(tabs);
for (i = 0; i < tabs.length; i++) {
tabs[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablinks");
console.log(tablinks);
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
//$(tab_content).style.display = "block";
document.getElementById(tab_content).style.display = "block";
evt.target.className += " active";
callsign_select(callsign);
}

View File

@ -10,10 +10,8 @@
<!-- <script src="https://cdn.socket.io/4.1.2/socket.io.min.js" integrity="sha384-toS6mmwu70G0fw54EGlWWeA4z3dyJ+dlXBtSURSKN4vyRFOcxd3Bzjj/AoOwY+Rg" crossorigin="anonymous"></script> --> <!-- <script src="https://cdn.socket.io/4.1.2/socket.io.min.js" integrity="sha384-toS6mmwu70G0fw54EGlWWeA4z3dyJ+dlXBtSURSKN4vyRFOcxd3Bzjj/AoOwY+Rg" crossorigin="anonymous"></script> -->
<script src="/static/js/upstream/socket.io.min.js"></script> <script src="/static/js/upstream/socket.io.min.js"></script>
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.9.0/semantic.min.css"> --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous">
<link rel="stylesheet" href="/static/css/upstream/semantic.min.css"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm" crossorigin="anonymous"></script>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.9.0/semantic.min.js"></script> -->
<script src="/static/js/upstream/semantic.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@24,200,1,200"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@24,200,1,200">
@ -36,7 +34,7 @@
console.log(initial_stats); console.log(initial_stats);
start_update(); start_update();
init_chat(); init_chat();
reset_Tabs(); //reset_Tabs();
console.log("latitude", latitude); console.log("latitude", latitude);
console.log("longitude", longitude); console.log("longitude", longitude);
@ -55,49 +53,45 @@
</head> </head>
<body> <body>
<div class='ui text container'> <div class='container text-center'>
<h1 class='ui dividing header'>APRSD WebChat {{ version }}</h1> <div class="row">
</div> <div class="column">
<h1>APRSD WebChat {{ version }}</h1>
<div class='ui grid text container'> </div>
<div class='left floated ten wide column'>
<span style='color: green'>{{ callsign }}</span>
connected to
<span style='color: blue' id='aprs_connection'>{{ aprs_connection|safe }}</span>
</div> </div>
<div class="row">
<div class='right floated four wide column'> <div class="column">
<span id='uptime'>NONE</span> <span style='color: green'>{{ callsign }}</span>
connected to
<span style='color: blue' id='aprs_connection'>{{ aprs_connection|safe }}</span>
<span id='uptime'>NONE</span>
</div>
</div> </div>
</div> <div class="row">
<form class="row gx-3 gy-2 align-items-center" id="sendform" name="sendmsg" action="">
<div class="ui container"> <div class="col-sm-3">
<h3 class="ui dividing header">Send Message</h3> <label for="to_call" class="visually-hidden">Callsign</label>
<div id="sendMsgDiv" class="ui mini text"> <input type="text" class="form-control mb-2 mr-sm-2" name="to_call" id="to_call" placeholder="To Callsign" size="11" maxlength="9">
<form id="sendform" name="sendmsg" action="">
<div class="ui corner labeled input">
<label for="to_call" class="ui label">Callsign</label>
<input type="text" name="to_call" id="to_call" placeholder="To Callsign" size="11" maxlength="9">
<div class="ui corner label">
<i class="asterisk icon"></i>
</div>
</div> </div>
<div class="ui labeled input"> <div class="col-sm-3">
<label for="message" class="ui label">Message</label> <label for="message" class="visually-hidden">Message</label>
<input type="text" name="message" id="message" size="40" maxlength="40"> <input type="text" class="form-control mb-2 mr-sm-2" name="message" id="message" size="40" maxlength="40" placeholder="Message">
</div>
<div class="col-auto">
<input type="submit" name="submit" class="btn btn-primary mb-2" id="send_msg" value="Send" />
<button type="button" class="btn btn-primary mb-2" id="send_beacon" value="Send GPS Beacon">Send GPS Beacon</button>
<button type="button" class="btn btn-primary mb-2" id="wipe_local" value="wipe local storage">Wipe LocalStorage</button>
</div> </div>
<input type="submit" name="submit" class="ui button" id="send_msg" value="Send" />
<button type="button" class="ui button" id="send_beacon" value="Send GPS Beacon">Send GPS Beacon</button>
<button type="button" class="ui button" id="wipe_local" value="wipe local storage">Wipe LocalStorage</button>
</form> </form>
</div> </div>
</div>
<div class="ui grid"> <div class="row">
<div class="two wide column"> <div class="container-sm" style="max-width: 800px;">
<div class="tab" id="callsignTabs"></div> <ul class="nav nav-tabs" id="msgsTabList" role="tablist">
</div> </ul>
<div class="seven wide column ui raised segment" id="msgsTabsDiv" style="height:450px;padding:0px;"> <div class="tab-content" id="msgsTabContent">
</div>
</div>
</div> </div>
</div> </div>