From 7f4fa703641f42edaee42fb4f0f8671802297ea0 Mon Sep 17 00:00:00 2001 From: "Stanislav Lechev [0xAF]" Date: Mon, 20 Nov 2023 04:59:59 +0200 Subject: [PATCH] chat system implementation in the web --- htdocs/css/openwebrx.css | 21 +++++++++++- htdocs/index.html | 26 ++++++++++----- htdocs/lib/UI.js | 15 +++++++++ htdocs/openwebrx.js | 71 +++++++++++++++++++++++++++++++++++----- 4 files changed, 115 insertions(+), 18 deletions(-) diff --git a/htdocs/css/openwebrx.css b/htdocs/css/openwebrx.css index 1228d1fd..a253c644 100644 --- a/htdocs/css/openwebrx.css +++ b/htdocs/css/openwebrx.css @@ -309,11 +309,30 @@ input[type=range]:disabled { #openwebrx-log-scroll { /*overflow-y:auto;*/ - height: 125px; + height: 155px; max-width: 619px; width: 100%; } +#openwebrx-messages .nickname { + color: #bbb; + font-weight: bold; +} + +#openwebrx-messages .chatmessage { +} + +#openwebrx-chat-inputs { + height: 1.5rem; + position: absolute; + bottom: 0; + width: 99% +} + +#openwebrx-log-scroll .nano-content, #openwebrx-log-scroll .nano-pane { + height: 126px; +} + .nano .nano-pane { background: #444; } .nano .nano-slider { background: #eee !important; } diff --git a/htdocs/index.html b/htdocs/index.html index b4840be8..15f33032 100644 --- a/htdocs/index.html +++ b/htdocs/index.html @@ -163,15 +163,25 @@
-
-
-
OpenWebRX+ client log
-
- Author contact: Marat Fayzullin | - OpenWebRX homepage +
+
+
+
OpenWebRX+ message log
+
+ Author: Marat Fayzullin | + OpenWebRX, + Support and information: Groups.io Mailinglist +
+
+
+
+
+
+
+ + +
Send
-
Support and information: Groups.io Mailinglist
-
diff --git a/htdocs/lib/UI.js b/htdocs/lib/UI.js index 63d6ec23..d62006af 100644 --- a/htdocs/lib/UI.js +++ b/htdocs/lib/UI.js @@ -25,6 +25,7 @@ UI.sections = { // Load UI settings from local storage. UI.loadSettings = function() { + this.setNickname(LS.has('nickname')? LS.loadStr('nickname') : ''); this.setTheme(LS.has('ui_theme')? LS.loadStr('ui_theme') : 'default'); this.setOpacity(LS.has('ui_opacity')? LS.loadInt('ui_opacity') : 100); this.toggleFrame(LS.has('ui_frame')? LS.loadBool('ui_frame') : false); @@ -238,3 +239,17 @@ UI.setTheme = function(theme) { $('body').addClass('has-theme'); } }; + +// Set user interface theme. +UI.setNickname = function(nickname) { + // Do not set twice + if (this.nickname === nickname) return; + + // Save current theme name + this.nickname = nickname; + LS.save('nickname', nickname); + + // Set input + $('#chatCallsign').val(nickname); +}; + diff --git a/htdocs/openwebrx.js b/htdocs/openwebrx.js index a3b4cdfb..b73eecd0 100644 --- a/htdocs/openwebrx.js +++ b/htdocs/openwebrx.js @@ -121,8 +121,13 @@ function jumpBySteps(steps) { } function recvChatMessage(sender, text, color = "white") { - divlog('' + sender + ': ' - + text + '', false); + toggle_panel("openwebrx-panel-log", true); //show panel + $('#openwebrx-messages')[0].innerHTML += + "[" + sender + "]: " + + "" + text + "
"; + var nano = $('#openwebrx-log-scroll'); + nano.nanoScroller(); + nano.nanoScroller({scroll: 'bottom'}); } function sendChatMessage(text, sender = "") { @@ -131,6 +136,47 @@ function sendChatMessage(text, sender = "") { })); } +var lastChatMsg = ""; +function chatSendMessage () { + var callsign = $('#chatCallsign').val(); + UI.setNickname(callsign); + var msg = $('#chatMessage').val().trim(); + if (msg.length > 0) { + lastChatMsg = msg; + sendChatMessage(msg, callsign); + } + $('#chatMessage').val(''); +} + +function chatKeyDown (event) { + // basic support of last msg + // TODO: make msg history to browse with up/down arrows + + var input = $('#chatMessage'); + if (event.key == "Enter") { + chatSendMessage(); + } else if (event.key == "ArrowUp") { + input.focus().val(lastChatMsg); + } else if (event.key == "ArrowDown") { + input.focus().val(''); + } +} + +// focus the chat input when the log window is clicked, +// this needs to be handled onLoad, since jQuery is not loaded yet. +document.addEventListener("DOMContentLoaded", function (event) { + $('.nano-content').mouseup(function () { + const selection = window.getSelection().toString(); + if (selection === '') { + // it's a click, we focus on the msg input + $('#chatMessage').focus(); + } else { + // it's a mouse text-selection, ignore it. + } + }); + $('#chatMessage').on('keydown', chatKeyDown) +}); + var waterfall_min_level; var waterfall_max_level; var waterfall_min_level_default; @@ -977,9 +1023,9 @@ function on_ws_recv(evt) { ); var versionInfo = 'Unknown server'; if (params.server && params.server === 'openwebrx' && params.version) { - versionInfo = 'OpenWebRX+ version: ' + params.version; + versionInfo = 'OpenWebRX+ version: ' + params.version + ""; } - divlog('Server acknowledged WebSocket connection, ' + versionInfo); + divlog('Server acknowledged WebSocket connection, ' + versionInfo + ""); } else { try { var json = JSON.parse(evt.data); @@ -1021,15 +1067,17 @@ function on_ws_recv(evt) { fft_size = config['fft_size']; waterfall_clear(); } + var streams_msg = ""; if ('audio_compression' in config) { var audio_compression = config['audio_compression']; audioEngine.setCompression(audio_compression); - divlog("Audio stream is " + ((audio_compression === "adpcm") ? "compressed" : "uncompressed") + "."); + streams_msg = "Audio stream is " + ((audio_compression === "adpcm") ? "compressed" : "uncompressed") + ". "; } if ('fft_compression' in config) { fft_compression = config['fft_compression']; - divlog("FFT stream is " + ((fft_compression === "adpcm") ? "compressed" : "uncompressed") + "."); + streams_msg += "FFT stream is " + ((fft_compression === "adpcm") ? "compressed" : "uncompressed") + "."; } + if (streams_msg.length) divlog(streams_msg); if ('max_clients' in config) $('#openwebrx-bar-clients').progressbar().setMaxClients(config['max_clients']); @@ -1283,7 +1331,7 @@ function waterfall_measure_minmax_do(what) { function on_ws_opened() { $('#openwebrx-error-overlay').hide(); ws.send("SERVER DE CLIENT client=openwebrx.js type=receiver"); - divlog("WebSocket opened to " + ws.url); + divlog("WebSocket opened to " + ws.url + ""); if (!networkSpeedMeasurement) { networkSpeedMeasurement = new Measurement(); networkSpeedMeasurement.report(60000, 1000, function(rate){ @@ -1311,7 +1359,7 @@ function divlog(what, is_error) { what = "" + what + ""; toggle_panel("openwebrx-panel-log", true); //show panel if any error is present } - $('#openwebrx-debugdiv')[0].innerHTML += what + "
"; + $('#openwebrx-messages')[0].innerHTML += what + "
"; var nano = $('#openwebrx-log-scroll'); nano.nanoScroller(); nano.nanoScroller({scroll: 'bottom'}); @@ -1324,7 +1372,7 @@ var mute = false; var audio_buffer_maximal_length_sec = 1; //actual number of samples are calculated from sample rate function onAudioStart(apiType){ - divlog('Web Audio API succesfully initialized, using ' + apiType + ' API, sample rate: ' + audioEngine.getSampleRate() + " Hz"); + divlog('Web Audio API initialized, with ' + apiType + ' API, sample rate: ' + audioEngine.getSampleRate() + "Hz"); hideOverlay(); @@ -1679,6 +1727,11 @@ function toggle_panel(what, on) { } item.style.transitionDuration = "600ms"; item.style.transitionDelay = "0ms"; + if (what === "openwebrx-panel-log") { + setTimeout(function () { + $('#chatMessage').focus(); + }, 50); + } } function first_show_panel(panel) {