mirror of
https://github.com/magicbug/Cloudlog
synced 2026-08-13 17:49:35 -04:00
Add Enter key handling for the CW free-text input (sendText) so pressing Enter sends the message. Replaced the old 'message' keypress handler in footer.php with a DOMContentLoaded listener that binds keydown on #sendText and calls sendMyMessage() (preventing default). Also added matching keydown handling in assets/js/winkey.js to call clickSend() when Enter is pressed on the sendText element.
424 lines
12 KiB
JavaScript
424 lines
12 KiB
JavaScript
// Lets see if CW is selected
|
|
const ModeSelected = document.getElementById('mode');
|
|
|
|
$('#winkey_buttons').hide();
|
|
|
|
if (location.protocol !== 'https:') {
|
|
// Do something if the page is being served over HTTP
|
|
$('#winkey').hide(); // Hide the CW buttons
|
|
}
|
|
|
|
function toggleWinkeyVisibility() {
|
|
const winkeyElement = document.getElementById('winkey');
|
|
if (ModeSelected && winkeyElement) {
|
|
if (ModeSelected.value === 'CW') {
|
|
$('#winkey').show();
|
|
} else {
|
|
$('#winkey').hide();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check initial mode
|
|
toggleWinkeyVisibility();
|
|
|
|
// Listen for mode changes
|
|
if (ModeSelected) {
|
|
ModeSelected.addEventListener('change', toggleWinkeyVisibility);
|
|
}
|
|
|
|
|
|
|
|
let function1Name, function1Macro, function2Name, function2Macro, function3Name, function3Macro, function4Name, function4Macro, function5Name, function5Macro;
|
|
|
|
getMacros();
|
|
|
|
document.addEventListener('keydown', function(event) {
|
|
|
|
if (event.key === 'F1') {
|
|
event.preventDefault();
|
|
morsekey_func1();
|
|
}
|
|
|
|
if (event.key === 'F2') {
|
|
event.preventDefault();
|
|
morsekey_func2();
|
|
}
|
|
|
|
if (event.key === 'F3') {
|
|
event.preventDefault();
|
|
morsekey_func3();
|
|
}
|
|
|
|
if (event.key === 'F4') {
|
|
event.preventDefault();
|
|
morsekey_func4();
|
|
}
|
|
|
|
if (event.key === 'F5') {
|
|
event.preventDefault();
|
|
morsekey_func5();
|
|
}
|
|
});
|
|
|
|
let sendText = document.getElementById("sendText");
|
|
let sendButton = document.getElementById("sendButton");
|
|
let receiveText = document.getElementById("receiveText");
|
|
let connectButton = document.getElementById("connectButton");
|
|
let statusBar = document.getElementById("statusBar");
|
|
|
|
//Couple the elements to the Events
|
|
if (connectButton) {
|
|
connectButton.addEventListener("click", clickConnect)
|
|
}
|
|
if (sendButton) {
|
|
sendButton.addEventListener("click", clickSend)
|
|
}
|
|
if (sendText) {
|
|
sendText.addEventListener("keydown", function(event) {
|
|
if (event.key === "Enter") {
|
|
event.preventDefault();
|
|
clickSend();
|
|
}
|
|
});
|
|
}
|
|
// statusButton.addEventListener("click", clickStatus)
|
|
|
|
//When the connectButton is pressed
|
|
async function clickConnect() {
|
|
if (port) {
|
|
//if already connected, disconnect
|
|
disconnect();
|
|
$('#winkey_buttons').hide();
|
|
} else {
|
|
//otherwise connect
|
|
await connect();
|
|
$('#winkey_buttons').show();
|
|
}
|
|
}
|
|
|
|
//Define outputstream, inputstream and port so they can be used throughout the sketch
|
|
var outputStream, inputStream, port;
|
|
|
|
// Auto-reconnect functionality
|
|
async function autoReconnect() {
|
|
try {
|
|
// Get previously connected ports
|
|
const ports = await navigator.serial.getPorts();
|
|
if (ports.length > 0) {
|
|
// Try to reconnect to the first available port
|
|
port = ports[0];
|
|
await port.open({ baudRate: 1200 });
|
|
await port.setSignals({ dataTerminalReady: true });
|
|
|
|
statusBar.innerText = "Auto-reconnected";
|
|
connectButton.innerText = "Disconnect";
|
|
|
|
let decoder = new TextDecoderStream();
|
|
inputDone = port.readable.pipeTo(decoder.writable);
|
|
inputStream = decoder.readable;
|
|
|
|
const encoder = new TextEncoderStream();
|
|
outputDone = encoder.readable.pipeTo(port.writable);
|
|
outputStream = encoder.writable;
|
|
|
|
writeToByte("0x00, 0x02");
|
|
writeToByte("0x02, 0x00");
|
|
|
|
$('#winkey_buttons').show();
|
|
|
|
reader = inputStream.getReader();
|
|
readLoop();
|
|
}
|
|
} catch (e) {
|
|
console.log("Auto-reconnect failed:", e);
|
|
// If auto-reconnect fails, just continue with normal flow
|
|
}
|
|
}
|
|
|
|
// Call auto-reconnect when page loads
|
|
window.addEventListener('load', autoReconnect);
|
|
navigator.serial.addEventListener('connect', e => {
|
|
statusBar.innerText = `Connected to ${e.port}`;
|
|
connectButton.innerText = "Disconnect"
|
|
});
|
|
|
|
navigator.serial.addEventListener('disconnect', e => {
|
|
statusBar.innerText = `Disconnected`;
|
|
connectButton.innerText = "Connect"
|
|
});
|
|
|
|
let debug = 0;
|
|
let speed = 24;
|
|
let minSpeed = 20;
|
|
let maxSpeed = 40;
|
|
|
|
//Connect to the serial
|
|
async function connect() {
|
|
|
|
//Optional filter to only see relevant boards
|
|
const filter = {
|
|
usbVendorId: 0x2341 // Arduino SA
|
|
};
|
|
|
|
//Try to connect to the Serial port
|
|
try {
|
|
port = await navigator.serial.requestPort(/*{ filters: [filter] }*/);
|
|
// Continue connecting to |port|.
|
|
|
|
// - Wait for the port to open.
|
|
await port.open({ baudRate: 1200 });
|
|
await port.setSignals({ dataTerminalReady: true });
|
|
|
|
statusBar.innerText = "Connected";
|
|
connectButton.innerText = "Disconnect"
|
|
|
|
let decoder = new TextDecoderStream();
|
|
inputDone = port.readable.pipeTo(decoder.writable);
|
|
inputStream = decoder.readable;
|
|
|
|
const encoder = new TextEncoderStream();
|
|
outputDone = encoder.readable.pipeTo(port.writable);
|
|
outputStream = encoder.writable;
|
|
|
|
writeToByte("0x00, 0x02");
|
|
writeToByte("0x02, 0x00");
|
|
|
|
$('#winkey_buttons').show();
|
|
|
|
reader = inputStream.getReader();
|
|
readLoop();
|
|
} catch (e) {
|
|
//If the pipeTo error appears; clarify the problem by giving suggestions.
|
|
if (e == "TypeError: Cannot read property 'pipeTo' of undefined") {
|
|
e += "\n Use Google Chrome and enable-experimental-web-platform-features"
|
|
}
|
|
connectButton.innerText = "Connect"
|
|
statusBar.innerText = e;
|
|
}
|
|
}
|
|
|
|
//Write to the Serial port
|
|
async function writeToStream(line) {
|
|
var enc = new TextEncoder(); // always utf-8
|
|
|
|
const writer = outputStream.getWriter();
|
|
writer.write(line);
|
|
writer.releaseLock();
|
|
}
|
|
|
|
async function writeToByte(line) {
|
|
const writer = outputStream.getWriter();
|
|
const data = new Uint8Array([line]);
|
|
writer.write(data);
|
|
writer.releaseLock();
|
|
}
|
|
|
|
//Disconnect from the Serial port
|
|
async function disconnect() {
|
|
|
|
if (reader) {
|
|
await reader.cancel();
|
|
await inputDone.catch(() => { });
|
|
reader = null;
|
|
inputDone = null;
|
|
}
|
|
if (outputStream) {
|
|
await outputStream.getWriter().close();
|
|
await outputDone;
|
|
outputStream = null;
|
|
outputDone = null;
|
|
}
|
|
statusBar.innerText = "Disconnected";
|
|
connectButton.innerText = "Connect"
|
|
//Close the port.
|
|
if (port) {
|
|
await port.close();
|
|
port = null;
|
|
}
|
|
}
|
|
|
|
//When the send button is pressed
|
|
function clickSend() {
|
|
const textToSend = sendText.value;
|
|
writeToStream(textToSend);
|
|
writeToStream("\r");
|
|
if (window.cloudlogCwSidetone) {
|
|
window.cloudlogCwSidetone.playText(textToSend, speed);
|
|
}
|
|
|
|
//and clear the input field, so it's clear it has been sent
|
|
sendText.value = "";
|
|
|
|
}
|
|
|
|
function morsekey_func1() {
|
|
const textToSend = UpdateMacros(function1Macro);
|
|
console.log("F1: " + textToSend);
|
|
writeToStream(textToSend);
|
|
if (window.cloudlogCwSidetone) {
|
|
window.cloudlogCwSidetone.playText(textToSend, speed);
|
|
}
|
|
//and clear the input field, so it's clear it has been sent
|
|
sendText.value = "";
|
|
}
|
|
|
|
function morsekey_func2() {
|
|
const textToSend = UpdateMacros(function2Macro);
|
|
console.log("F2: " + textToSend);
|
|
writeToStream(textToSend);
|
|
if (window.cloudlogCwSidetone) {
|
|
window.cloudlogCwSidetone.playText(textToSend, speed);
|
|
}
|
|
//and clear the input field, so it's clear it has been sent
|
|
sendText.value = "";
|
|
}
|
|
|
|
function morsekey_func3() {
|
|
const textToSend = UpdateMacros(function3Macro);
|
|
console.log("F3: " + textToSend);
|
|
writeToStream(textToSend);
|
|
if (window.cloudlogCwSidetone) {
|
|
window.cloudlogCwSidetone.playText(textToSend, speed);
|
|
}
|
|
//and clear the input field, so it's clear it has been sent
|
|
sendText.value = "";
|
|
}
|
|
|
|
function morsekey_func4() {
|
|
const textToSend = UpdateMacros(function4Macro);
|
|
console.log("F4: " + textToSend);
|
|
writeToStream(textToSend);
|
|
if (window.cloudlogCwSidetone) {
|
|
window.cloudlogCwSidetone.playText(textToSend, speed);
|
|
}
|
|
//and clear the input field, so it's clear it has been sent
|
|
sendText.value = "";
|
|
}
|
|
|
|
function morsekey_func5() {
|
|
const textToSend = UpdateMacros(function5Macro);
|
|
console.log("F5: " + textToSend);
|
|
writeToStream(textToSend);
|
|
if (window.cloudlogCwSidetone) {
|
|
window.cloudlogCwSidetone.playText(textToSend, speed);
|
|
}
|
|
//and clear the input field, so it's clear it has been sent
|
|
sendText.value = "";
|
|
}
|
|
|
|
|
|
|
|
//Read the incoming data
|
|
async function readLoop() {
|
|
while (true) {
|
|
const { value, done } = await reader.read();
|
|
if (done === true){
|
|
break;
|
|
}
|
|
|
|
console.log(value);
|
|
//When recieved something add it to the big textarea
|
|
receiveText.value += value;
|
|
//Scroll to the bottom of the text field
|
|
receiveText.scrollTop = receiveText.scrollHeight;
|
|
}
|
|
}
|
|
|
|
function closeModal() {
|
|
var container = document.getElementById("modals-here")
|
|
var backdrop = document.getElementById("modal-backdrop")
|
|
var modal = document.getElementById("modal")
|
|
|
|
modal.classList.remove("show")
|
|
backdrop.classList.remove("show")
|
|
|
|
getMacros();
|
|
|
|
setTimeout(function() {
|
|
container.removeChild(backdrop)
|
|
container.removeChild(modal)
|
|
}, 200)
|
|
}
|
|
|
|
function UpdateMacros(macrotext) {
|
|
|
|
// Get the values from the form set to uppercase
|
|
let CALL = document.getElementById("callsign").value.toUpperCase();
|
|
let RSTS = document.getElementById("rst_sent").value;
|
|
|
|
let newString;
|
|
newString = macrotext.replace(/\[MYCALL\]/g, my_call);
|
|
newString = newString.replace(/\[CALL\]/g, CALL);
|
|
newString = newString.replace(/\[RSTS\]/g, RSTS);
|
|
console.log(newString);
|
|
return newString;
|
|
}
|
|
|
|
// Call url and store the returned json data as variables
|
|
function getMacros() {
|
|
fetch(base_url + 'index.php/qso/cwmacros_json')
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('HTTP ' + response.status + ': ' + response.statusText);
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
// Handle case where no macros are saved yet
|
|
if (data.status === 'not found') {
|
|
// Set default values
|
|
function1Name = 'CQ';
|
|
function1Macro = 'CQ CQ CQ DE [MYCALL] [MYCALL] K';
|
|
function2Name = 'REPT';
|
|
function2Macro = '[CALL] DE [MYCALL] [RSTS] [RSTS] K';
|
|
function3Name = 'TU';
|
|
function3Macro = '[CALL] TU 73 DE [MYCALL] K';
|
|
function4Name = 'QRZ';
|
|
function4Macro = 'QRZ DE [MYCALL] K';
|
|
function5Name = 'TEST';
|
|
function5Macro = 'TEST DE [MYCALL] K';
|
|
} else {
|
|
// Use saved values or defaults if empty
|
|
function1Name = data.function1_name || 'F1';
|
|
function1Macro = data.function1_macro || '';
|
|
function2Name = data.function2_name || 'F2';
|
|
function2Macro = data.function2_macro || '';
|
|
function3Name = data.function3_name || 'F3';
|
|
function3Macro = data.function3_macro || '';
|
|
function4Name = data.function4_name || 'F4';
|
|
function4Macro = data.function4_macro || '';
|
|
function5Name = data.function5_name || 'F5';
|
|
function5Macro = data.function5_macro || '';
|
|
}
|
|
|
|
// Update button labels
|
|
const morsekey_func1_Button = document.getElementById('morsekey_func1');
|
|
if (morsekey_func1_Button) {
|
|
morsekey_func1_Button.textContent = 'F1 (' + function1Name + ')';
|
|
}
|
|
|
|
const morsekey_func2_Button = document.getElementById('morsekey_func2');
|
|
if (morsekey_func2_Button) {
|
|
morsekey_func2_Button.textContent = 'F2 (' + function2Name + ')';
|
|
}
|
|
|
|
const morsekey_func3_Button = document.getElementById('morsekey_func3');
|
|
if (morsekey_func3_Button) {
|
|
morsekey_func3_Button.textContent = 'F3 (' + function3Name + ')';
|
|
}
|
|
|
|
const morsekey_func4_Button = document.getElementById('morsekey_func4');
|
|
if (morsekey_func4_Button) {
|
|
morsekey_func4_Button.textContent = 'F4 (' + function4Name + ')';
|
|
}
|
|
|
|
const morsekey_func5_Button = document.getElementById('morsekey_func5');
|
|
if (morsekey_func5_Button) {
|
|
morsekey_func5_Button.textContent = 'F5 (' + function5Name + ')';
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error loading CW macros:', error);
|
|
});
|
|
}
|