Tag Cloudlog as 2.6.19

Tag Cloudlog as 2.6.19
这个提交包含在:
Peter Goodhall 2025-06-11 15:27:18 +01:00 提交者 GitHub
当前提交 5f51d60f49
找不到此签名对应的密钥
GPG 密钥 ID: B5690EEEBB952194
共有 23 个文件被更改,包括 846 次插入349 次删除

查看文件

@ -22,7 +22,7 @@ $config['migration_enabled'] = TRUE;
|
*/
$config['migration_version'] = 196;
$config['migration_version'] = 199;
/*
|--------------------------------------------------------------------------

查看文件

@ -1,12 +1,15 @@
<?php if (! defined('BASEPATH')) exit('No direct script access allowed');
class Activated_gridmap extends CI_Controller {
class Activated_gridmap extends CI_Controller
{
function __construct() {
function __construct()
{
parent::__construct();
}
public function index() {
public function index()
{
$data['page_title'] = "Activated Gridsquare Map";
$this->load->model('bands');
@ -44,7 +47,8 @@ class Activated_gridmap extends CI_Controller {
$this->load->view('interface_assets/footer', $footerData);
}
public function getGridsjs() {
public function getGridsjs()
{
$band = $this->security->xss_clean($this->input->post('band'));
$mode = $this->security->xss_clean($this->input->post('mode'));
$qsl = $this->security->xss_clean($this->input->post('qsl'));

查看文件

@ -37,27 +37,33 @@ class Clublog extends CI_Controller {
$this->load->model('clublog_model');
// Retrieve all station profiles for the user with their QSO counts
$station_profiles = $this->clublog_model->all_with_count($clean_userid);
if($station_profiles->num_rows()){
foreach ($station_profiles->result() as $station_row)
{
// Only process stations that have QSOs to upload
if($station_row->qso_total > 0) {
// Get QSOs for this station that haven't been uploaded to Clublog yet
$data['qsos'] = $this->clublog_model->get_clublog_qsos($station_row->station_id);
if($data['qsos']->num_rows()){
// Generate ADIF file content from the view template
$string = $this->load->view('adif/data/clublog', $data, TRUE);
// Generate a unique ID for the temporary file
$ranid = uniqid();
// Write the ADIF data to a temporary file
if ( ! write_file('uploads/clublog'.$ranid.$station_row->station_id.'.adi', $string)) {
echo 'Unable to write the file - Make the folder Upload folder has write permissions.';
}
else {
// Get details of the created ADIF file
$file_info = get_file_info('uploads/clublog'.$ranid.$station_row->station_id.'.adi');
// initialise the curl request
// Initialize the CURL request to Clublog's API endpoint
$request = curl_init('https://clublog.org/putlogs.php');
if($this->config->item('directory') != "") {
@ -138,13 +144,12 @@ class Clublog extends CI_Controller {
$this->clublog_model->mark_qsos_sent($clean_station_id);
}
function markallnotsent() {
function markallnotsent($station_id) {
$clean_station_id = $this->security->xss_clean($station_id);
$this->load->model('clublog_model');
$this->clublog_model->mark_all_qsos_notsent($clean_station_id);
}
// Find DXCC
function find_dxcc($callsign) {
$clean_callsign = $this->security->xss_clean($callsign);

查看文件

@ -576,6 +576,12 @@ class User extends CI_Controller
$data['user_winkey'] = $q->winkey;
}
if ($this->input->post('user_winkey_websocket')) {
$data['user_winkey_websocket'] = $this->input->post('user_winkey_websocket', true);
} else {
$data['user_winkey_websocket'] = $q->winkey_websocket;
}
$this->load->model('user_options_model');
$callbook_type_object = $this->user_options_model->get_options('callbook')->result();
@ -730,7 +736,13 @@ class User extends CI_Controller
$this->load->view('interface_assets/footer');
} else {
unset($data);
switch ($this->user_model->edit($this->input->post())) {
$post_data = $this->input->post();
if (!isset($post_data['user_winkey_websocket'])) {
$post_data['user_winkey_websocket'] = '0';
}
switch ($this->user_model->edit($post_data)) {
// Check for errors
case EUSERNAMEEXISTS:
$data['username_error'] = 'Username <b>' . $this->input->post('user_name', true) . '</b> already in use!';
@ -892,6 +904,7 @@ class User extends CI_Controller
$data['user_quicklog_enter'] = $this->input->post('user_quicklog_enter');
$data['language'] = $this->input->post('language');
$data['user_winkey'] = $this->input->post('user_winkey');
$data['user_winkey_websocket'] = $this->input->post('user_winkey_websocket');
$data['user_hamsat_key'] = $this->input->post('user_hamsat_key');
$data['user_hamsat_workable_only'] = $this->input->post('user_hamsat_workable_only');

查看文件

@ -0,0 +1,30 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/*
* This adds a field to user-table to hold winkey websocket setting
*/
// Migration: 197_add_winkey_websocket
class Migration_add_winkey_websocket extends CI_Migration {
public function up()
{
// Check if winkey_websocket exists in the user table if not create a boolean field
if (!$this->db->field_exists('winkey_websocket', 'users')) {
$fields = array(
'winkey_websocket boolean default 0',
);
$this->dbforge->add_column('users', $fields);
}
}
public function down()
{
if ($this->db->field_exists('winkey_websocket', 'users')) {
$this->dbforge->drop_column('users', 'winkey_websocket');
}
}
}

查看文件

@ -0,0 +1,36 @@
<?php
defined('BASEPATH') or exit('No direct script access allowed');
class Migration_sat_name_change_hadesicm_so125 extends CI_Migration
{
public function up()
{
// update column COL_SAT_NAME to SO-125 if its HADES-ICM
$this->db->set('COL_SAT_NAME', 'SO-125');
$this->db->where('COL_SAT_NAME', 'HADES-ICM');
$this->db->update($this->config->item('table_name'));
log_message('info', 'Migration: Updated COL_SAT_NAME to SO-125 for HADES-ICM');
// update column COL_LOTW_QSL_SENT to N if its SO-125
$this->db->set('COL_LOTW_QSL_SENT', 'N');
$this->db->where('COL_SAT_NAME', 'SO-125');
$this->db->update($this->config->item('table_name'));
log_message('info', 'Migration: Set COL_LOTW_QSL_SENT to N for SO-125');
}
public function down()
{
//Change back to HADES-ICM
$this->db->set('COL_SAT_NAME', 'HADES-ICM');
$this->db->where('COL_SAT_NAME', 'SO-125');
$this->db->update($this->config->item('table_name'));
log_message('info', 'Migration: Reverted COL_SAT_NAME back to HADES-ICM');
// Set COL_LOTW_QSL_SENT back to N for HADES-ICM
$this->db->set('COL_LOTW_QSL_SENT', 'N');
$this->db->where('COL_SAT_NAME', 'HADES-ICM');
$this->db->update($this->config->item('table_name'));
log_message('info', 'Migration: Reverted COL_LOTW_QSL_SENT back to N for HADES-ICM');
}
}

查看文件

@ -0,0 +1,30 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/*
* Tag Cloudlog as 2.6.19
*/
class Migration_tag_2_6_19 extends CI_Migration {
public function up()
{
// Tag Cloudlog 2.6.19
$this->db->where('option_name', 'version');
$this->db->update('options', array('option_value' => '2.6.19'));
// Trigger Version Info Dialog
$this->db->where('option_type', 'version_dialog');
$this->db->where('option_name', 'confirmed');
$this->db->update('user_options', array('option_value' => 'false'));
}
public function down()
{
$this->db->where('option_name', 'version');
$this->db->update('options', array('option_value' => '2.6.18'));
}
}

查看文件

@ -267,6 +267,7 @@ class User_Model extends CI_Model {
'user_quicklog_enter' => xss_clean($fields['user_quicklog_enter']),
'language' => xss_clean($fields['language']),
'winkey' => xss_clean($fields['user_winkey']),
'winkey_websocket' => xss_clean($fields['user_winkey_websocket']),
);
$this->db->query("replace into user_options (user_id, option_type, option_name, option_key, option_value) values (" . $fields['id'] . ", 'hamsat','hamsat_key','api','".xss_clean($fields['user_hamsat_key'])."');");
@ -426,6 +427,7 @@ class User_Model extends CI_Model {
'active_station_logbook' => $u->row()->active_station_logbook,
'language' => isset($u->row()->language) ? $u->row()->language: 'english',
'isWinkeyEnabled' => $u->row()->winkey,
'isWinkeyWebsocketEnabled' => (bool)$u->row()->winkey_websocket,
'hasQrzKey' => $this->hasQrzKey($u->row()->user_id),
'callbook_type' => $callbook_type,
'callbook_username' => $callbook_username,

查看文件

@ -1125,11 +1125,222 @@ if ($this->session->userdata('user_id') != null) {
<?php if ($this->uri->segment(1) == "qso") { ?>
<script src="<?php echo base_url(); ?>assets/js/sections/qso.js"></script>
<?php if ($this->session->userdata('isWinkeyEnabled')) { ?>
<?php if ($this->session->userdata('isWinkeyEnabled') && !$this->session->userdata('isWinkeyWebsocketEnabled')) { ?>
<script src="<?php echo base_url(); ?>assets/js/winkey.js"></script>
<?php }
<?php } elseif ($this->session->userdata('isWinkeyEnabled') && $this->session->userdata('isWinkeyWebsocketEnabled')) { ?>
<script>
console.log('Winkey Websocket enabled');
</script>
if ($this->optionslib->get_option('dxcache_url') != '') { ?>
<script>
let ws = null;
function connectWebSocket() {
if (ws !== null) {
ws.close();
}
const chatRoom = "cw_room";
const wsUrl = `ws://localhost:8181?chatRoom=${encodeURIComponent(chatRoom)}`;
ws = new WebSocket(wsUrl);
ws.onopen = function() {
document.getElementById('cw_socket_status').className = 'badge bg-success';
document.getElementById('cw_socket_status').innerHTML = `Status: Connected`;
logMessage(`Connected to WebSocket server in room: ${chatRoom}`);
};
ws.onclose = function() {
document.getElementById('cw_socket_status').className = 'badge bg-secondary';
document.getElementById('cw_socket_status').innerHTML = 'Status: Disconnected';
logMessage('Disconnected from WebSocket server');
ws = null;
};
ws.onerror = function(error) {
logMessage('WebSocket Error: ' + error);
};
ws.onmessage = function(event) {
logMessage('Received: ' + event.data);
};
}
function disconnectWebSocket() {
if (ws !== null) {
ws.close();
}
}
function sendMessage() {
if (ws === null) {
alert('Please connect to the WebSocket server first');
return;
}
const message = document.getElementById('message').value;
if (message.trim() === '') {
alert('Please enter a message');
return;
}
// Prefix the message with "CW:" to indicate it's a CW message
const cwMessage = 'CW:' + message;
ws.send(cwMessage);
logMessage('Sent: ' + cwMessage);
// Clear the input field
document.getElementById('message').value = '';
}
function logMessage(message) {
const messageLog = document.getElementById('messageLog');
messageLog.value += message + '\n';
// Auto-scroll to bottom
messageLog.scrollTop = messageLog.scrollHeight;
}
// Support for Enter key in the input field
document.getElementById('message').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
sendMessage();
}
});
</script>
<script>
connectWebSocket();
function morsekey_func1() {
console.log("F1: " + UpdateMacros(function1Macro));
const cwMessage = 'CW:' + UpdateMacros(function1Macro);
ws.send(cwMessage);
}
function morsekey_func2() {
console.log("F2: " + UpdateMacros(function2Macro));
const cwMessage = 'CW:' + UpdateMacros(function2Macro);
ws.send(cwMessage);
}
function morsekey_func3() {
console.log("F3: " + UpdateMacros(function3Macro));
const cwMessage = 'CW:' + UpdateMacros(function3Macro);
ws.send(cwMessage);
}
function morsekey_func4() {
console.log("F4: " + UpdateMacros(function4Macro));
const cwMessage = 'CW:' + UpdateMacros(function4Macro);
ws.send(cwMessage);
}
function morsekey_func5() {
console.log("F5: " + UpdateMacros(function5Macro));
const cwMessage = 'CW:' + UpdateMacros(function5Macro);
ws.send(cwMessage);
}
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();
}
});
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 => response.json())
.then(data => {
function1Name = data.function1_name;
function1Macro = data.function1_macro;
function2Name = data.function2_name;
function2Macro = data.function2_macro;
function3Name = data.function3_name;
function3Macro = data.function3_macro;
function4Name = data.function4_name;
function4Macro = data.function4_macro;
function5Name = data.function5_name;
function5Macro = data.function5_macro;
const morsekey_func1_Button = document.getElementById('morsekey_func1');
morsekey_func1_Button.textContent = 'F1 (' + function1Name + ')';
const morsekey_func2_Button = document.getElementById('morsekey_func2');
morsekey_func2_Button.textContent = 'F2 (' + function2Name + ')';
const morsekey_func3_Button = document.getElementById('morsekey_func3');
morsekey_func3_Button.textContent = 'F3 (' + function3Name + ')';
const morsekey_func4_Button = document.getElementById('morsekey_func4');
morsekey_func4_Button.textContent = 'F4 (' + function4Name + ')';
const morsekey_func5_Button = document.getElementById('morsekey_func5');
morsekey_func5_Button.textContent = 'F5 (' + function5Name + ')';
});
}
function sendMyMessage() {
const message = document.getElementById('sendText').value;
if (message.trim() === '') {
alert('Please enter a message');
return;
}
const cwMessage = 'CW:' + message;
ws.send(cwMessage);
logMessage('Sent: ' + cwMessage);
// Clear the input field
document.getElementById('sendText').value = '';
}
</script>
<?php } ?>
<?php if ($this->optionslib->get_option('dxcache_url') != '') { ?>
<script type="text/javascript">
var dxcluster_provider = '<?php echo base_url(); ?>index.php/dxcluster';
$(document).ready(function() {
@ -1470,7 +1681,7 @@ if ($this->session->userdata('user_id') != null) {
$('#notice-alerts').delay(1000).fadeOut(5000);
function setRst(mode) {
if (mode == 'JT65' || mode == 'JT65B' || mode == 'JT6C' || mode == 'JTMS' || mode == 'ISCAT' || mode == 'MSK144' || mode == 'JTMSK' || mode == 'QRA64' || mode == 'FT8' || mode == 'FT4' || mode == 'JS8' || mode == 'JT9' || mode == 'JT9-1' || mode == 'ROS') {
if (mode == 'JT65' || mode == 'JT65B' || mode == 'JT6C' || mode == 'JTMS' || mode == 'ISCAT' || mode == 'MSK144' || mode == 'JTMSK' || mode == 'QRA64' || mode == 'FT8' || mode == 'FT4' || mode == 'JS8' || mode == 'JT9' || mode == 'JT9-1' || mode == 'ROS' || mode == 'Q65' || mode == 'FST4' || mode == 'FST4W') {
$('#rst_sent').val('-5');
$('#rst_rcvd').val('-5');
} else if (mode == 'FSK441' || mode == 'JT6M') {
@ -1622,6 +1833,28 @@ if ($this->session->userdata('user_id') != null) {
// Event listeners
$(document).ready(() => {
/**
* Prevents multiple form submissions by tracking submission state
*
* This script prevents duplicate QSO (contact) submissions by:
* - Maintaining an isSubmitting flag to track form submission state
* - Adding an event listener to the 'qso_input' form
* - Preventing form submission if a submission is already in progress
* - Setting the flag to true when a valid submission begins
*
* @since Unknown
* @global boolean isSubmitting Flag to track if form is currently being submitted
*/
let isSubmitting = false;
document.getElementById('qso_input').addEventListener('submit', function(e) {
if (isSubmitting) {
e.preventDefault();
return false;
}
isSubmitting = true;
});
// Update frequency every three seconds for the selected radio
setInterval(() => {
const selectedRadioID = $('select.radios option:selected').val();

查看文件

@ -673,9 +673,49 @@
<!-- Winkey Starts -->
<?php if ($this->session->userdata('isWinkeyEnabled') && $this->session->userdata('isWinkeyWebsocketEnabled')) { ?>
<div id="winkey" class="card winkey-settings" style="margin-bottom: 10px;">
<div class="card-header">
<h4 style="font-size: 16px; font-weight: bold;" class="card-title">Winkey Web Sockets
<div id="cw_socket_status" class="badge text-bg-danger">
Status: Disconnected
</div>
<button type="button" class="btn btn-secondary"
hx-get="<?php echo base_url(); ?>index.php/qso/winkeysettings"
hx-target="#modals-here"
hx-trigger="click"
class="btn btn-primary"
_="on htmx:afterOnLoad wait 10ms then add .show to #modal then add .show to #modal-backdrop"><i class="fas fa-cog"></i> Settings</button>
</h4>
</div>
<div id="modals-here"></div>
<div id="winkey_buttons" class="card-body">
<button id="morsekey_func1" onclick="morsekey_func1()" class="btn btn-warning">F1</button>
<button id="morsekey_func2" onclick="morsekey_func2()" class="btn btn-warning">F2</button>
<button id="morsekey_func3" onclick="morsekey_func3()" class="btn btn-warning">F3</button>
<button id="morsekey_func4" onclick="morsekey_func4()" class="btn btn-warning">F4</button>
<button id="morsekey_func5" onclick="morsekey_func5()" class="btn btn-warning">F5</button>
<br><br>
<input id="sendText" type="text"><input onclick="sendMyMessage()" id="sendButton" type="button" value="Send" class="btn btn-success">
<div>
<strong>Message Log:</strong>
<textarea id="messageLog" class="form-control mt-2" rows="4" readonly></textarea>
</div>
</div>
</div>
<?php } ?>
<?php
// if isWinkeyEnabled in session data is true
if ($this->session->userdata('isWinkeyEnabled')) { ?>
// if isWinkeyEnabled in session data is true and isWinkeyWebsocketEnabled is false
if ($this->session->userdata('isWinkeyEnabled') && !$this->session->userdata('isWinkeyWebsocketEnabled')) { ?>
<div id="winkey" class="card winkey-settings" style="margin-bottom: 10px;">
<div class="card-header">

查看文件

@ -8,7 +8,10 @@
</div>
<?php } ?>
<div class="d-flex justify-content-between align-items-center mb-3">
<h2><?php echo $page_title; ?></h2>
<a href="<?php echo site_url('station/create'); ?>" class="btn btn-primary"><i class="fas fa-plus"></i> <?php echo lang('station_location_create'); ?></a>
</div>
<div class="card">
<div class="card-body">
@ -16,8 +19,6 @@
<p class="card-text"><?php echo lang('station_location_header_ln2'); ?></p>
<p class="card-text"><?php echo lang('station_location_header_ln3'); ?></p>
<p><a href="<?php echo site_url('station/create'); ?>" class="btn btn-primary"><i class="fas fa-plus"></i> <?php echo lang('station_location_create'); ?></a></p>
<?php if ($stations->num_rows() > 0) { ?>
<?php if($current_active == 0) { ?>
@ -28,8 +29,7 @@
<?php if (($is_there_qsos_with_no_station_id >= 1) && ($is_admin)) { ?>
<div class="alert alert-danger" role="alert">
<span class="badge rounded-pill text-bg-warning"><?php echo lang('general_word_warning'); ?></span> <?php echo lang('station_location_warning_reassign'); ?>
</br>
<span class="badge rounded-pill text-bg-warning"><?php echo lang('general_word_warning'); ?></span> <?php echo lang('station_location_warning_reassign'); ?> <br>
<?php echo lang('station_location_reassign_at'); ?> <a href="<?php echo site_url('maintenance/'); ?>" class="btn btn-warning"><i class="fas fa-sync"></i><?php echo lang('account_word_admin') . "/" . lang('general_word_maintenance'); ?></a>
</div>
<?php } ?>
@ -73,17 +73,16 @@
<?php if($row->user_id == "") { ?>
<a href="<?php echo site_url('station/claim_user')."/".$row->station_id; ?>" class="btn btn-outline-primary btn-sm"><i class="fas fa-user-plus"></i> <?php echo lang('station_location_claim_ownership'); ?></a>
<?php } ?>
<a href="<?php echo site_url('station/edit')."/".$row->station_id; ?>" title=<?php echo lang('admin_edit'); ?> class="btn btn-outline-primary btn-sm"><i class="fas fa-edit"></i></a>
<a href="<?php echo site_url('station/edit')."/".$row->station_id; ?>" title="<?php echo lang('admin_edit'); ?>" class="btn btn-outline-primary btn-sm"><i class="fas fa-edit"></i></a>
</td>
<td style="text-align: center; vertical-align: middle;">
<a href="<?php echo site_url('station/copy')."/".$row->station_id; ?>" title=<?php echo lang('admin_copy'); ?> class="btn btn-outline-primary btn-sm"><i class="fas fa-copy"></i></a>
<a href="<?php echo site_url('station/copy')."/".$row->station_id; ?>" title="<?php echo lang('admin_copy'); ?>" class="btn btn-outline-primary btn-sm"><i class="fas fa-copy"></i></a>
</td>
<td style="text-align: center; vertical-align: middle;">
<a href="<?php echo site_url('station/deletelog')."/".$row->station_id; ?>" class="btn btn-danger btn-sm" title=<?php echo lang('station_location_emptylog'); ?> onclick="return confirm('<?php echo lang('station_location_confirm_del_qso'); ?>');"><i class="fas fa-trash-alt"></i></a></td>
<td style="text-align: center; vertical-align: middle;"> <a href="<?php echo site_url('station/deletelog')."/".$row->station_id; ?>" class="btn btn-danger btn-sm" title="<?php echo lang('station_location_emptylog'); ?>" onclick="return confirm('<?php echo lang('station_location_confirm_del_qso'); ?>');"><i class="fas fa-trash-alt"></i></a>
</td>
<td style="text-align: center; vertical-align: middle;">
<?php if($row->station_active != 1) { ?>
<a href="<?php echo site_url('station/delete')."/".$row->station_id; ?>" class="btn btn-danger btn-sm" title=<?php echo lang('admin_delete'); ?> onclick="return confirm('<?php echo lang('station_location_confirm_del_stationlocation'); ?> <?php echo $row->station_profile_name; ?> <?php echo lang('station_location_confirm_del_stationlocation_qso'); ?>');"><i class="fas fa-trash-alt"></i></a>
<a href="<?php echo site_url('station/delete')."/".$row->station_id; ?>" class="btn btn-danger btn-sm" title="<?php echo lang('admin_delete'); ?>" onclick="return confirm('<?php echo lang('station_location_confirm_del_stationlocation'); ?> <?php echo $row->station_profile_name; ?> <?php echo lang('station_location_confirm_del_stationlocation_qso'); ?>');"><i class="fas fa-trash-alt"></i></a>
<?php } ?>
</td>
</tr>

查看文件

@ -61,5 +61,3 @@
</div>
</div>
</div>

查看文件

@ -46,45 +46,56 @@
<!-- Account Information -->
<div class="col-md">
<div class="card">
<div class="card-header"><?php echo lang('account_account_information'); ?></div>
<div class="card-header">
<?php echo lang('account_account_information'); ?>
</div>
<div class="card-body">
<div class="mb-3">
<label><?php echo lang('account_username'); ?></label>
<label class="form-label"><?php echo lang('account_username'); ?></label>
<div class="input-group">
<span class="input-group-text"><i class="fa fa-user"></i></span>
<input class="form-control" type="text" name="user_name" value="<?php if (isset($user_name)) {
echo $user_name;
} ?>" />
</div>
<?php if (isset($username_error)) {
echo "<small class=\"error\">" . $username_error . "</small>";
echo "<small class=\"text-danger\"><i class=\"fa fa-exclamation-circle\"></i> " . $username_error . "</small>";
} ?>
</div>
<div class="mb-3">
<label><?php echo lang('account_email_address'); ?></label>
<input class="form-control" type="text" name="user_email" value="<?php if (isset($user_email)) {
<label class="form-label"><?php echo lang('account_email_address'); ?></label>
<div class="input-group">
<span class="input-group-text"><i class="fa fa-envelope"></i></span>
<input class="form-control" type="email" name="user_email" value="<?php if (isset($user_email)) {
echo $user_email;
} ?>" />
</div>
<?php if (isset($email_error)) {
echo "<small class=\"error\">" . $email_error . "</small>";
echo "<small class=\"text-danger\"><i class=\"fa fa-exclamation-circle\"></i> " . $email_error . "</small>";
} ?>
</div>
<div class="mb-3">
<label><?php echo lang('account_password'); ?></label>
<label class="form-label"><?php echo lang('account_password'); ?></label>
<div class="input-group">
<span class="input-group-text"><i class="fa fa-lock"></i></span>
<input class="form-control" type="password" name="user_password" />
<span class="input-group-btn"><button class="btn btn-default btn-pwd-showhide" type="button"><i class="fa fa-eye-slash"></i></button></span>
<button class="btn btn-outline-secondary btn-pwd-showhide" type="button"><i class="fa fa-eye-slash"></i></button>
</div>
<?php if (isset($password_error)) {
echo "<small class=\"error\">" . $password_error . "</small>";
echo "<small class=\"text-danger\"><i class=\"fa fa-exclamation-circle\"></i> " . $password_error . "</small>";
} else { ?>
<small class="form-text text-muted"><?php echo lang('account_leave_blank_to_keep_existing_password'); ?></small>
<small class="form-text text-muted"><i class="fa fa-info-circle"></i> <?php echo lang('account_leave_blank_to_keep_existing_password'); ?></small>
<?php } ?>
</div>
<hr />
<hr class="my-4" />
<div class="mb-3">
<label><?php echo lang('account_user_role'); ?></label>
<label class="form-label"><?php echo lang('account_user_role'); ?></label>
<?php if ($this->session->userdata('user_type') == 99) { ?>
<div class="input-group">
<span class="input-group-text"><i class="fa fa-users"></i></span>
<select class="form-select" name="user_type">
<?php
$levels = $this->config->item('auth_level');
@ -93,9 +104,13 @@
}
?>
</select>
</div>
<?php } else {
$l = $this->config->item('auth_level');
echo $l[$user_type];
echo '<div class="input-group">
<span class="input-group-text"><i class="fa fa-user-tag"></i></span>
<input type="text" class="form-control" value="' . $l[$user_type] . '" disabled>
</div>';
} ?>
</div>
</div>
@ -281,27 +296,37 @@
<div class="card-body">
<div class="mb-3">
<div class="form-check form-switch">
<input name="user_dashboard_enable_dxpedition_card" class="form-check-input" type="checkbox" role="switch" id="DashboardUpcomingDXpeditionCheck" <?php if ($dashboard_upcoming_dx_card) { echo 'checked'; } ?>>
<input name="user_dashboard_enable_dxpedition_card" class="form-check-input" type="checkbox" role="switch" id="DashboardUpcomingDXpeditionCheck" <?php if ($dashboard_upcoming_dx_card) {
echo 'checked';
} ?>>
<label class="form-check-label" for="DashboardUpcomingDXpeditionCheck">Enable Upcoming DXPedition Card</label>
</div>
<div class="form-check form-switch">
<input name="user_dashboard_enable_qslcards_card" class="form-check-input" type="checkbox" role="switch" id="DashboardQSLCardCheck" <?php if ($dashboard_qslcard_card) { echo 'checked'; } ?>>
<input name="user_dashboard_enable_qslcards_card" class="form-check-input" type="checkbox" role="switch" id="DashboardQSLCardCheck" <?php if ($dashboard_qslcard_card) {
echo 'checked';
} ?>>
<label class="form-check-label" for="DashboardQSLCardCheck">Enable QSL Cards Card</label>
</div>
<div class="form-check form-switch">
<input name="user_dashboard_enable_eqslcards_card" class="form-check-input" type="checkbox" role="switch" id="DashboardeQSLCardCheck" <?php if ($dashboard_eqslcard_card) { echo 'checked'; } ?>>
<input name="user_dashboard_enable_eqslcards_card" class="form-check-input" type="checkbox" role="switch" id="DashboardeQSLCardCheck" <?php if ($dashboard_eqslcard_card) {
echo 'checked';
} ?>>
<label class="form-check-label" for="DashboardeQSLCardCheck">Enable eQSL Cards Card</label>
</div>
<div class="form-check form-switch">
<input name="user_dashboard_enable_lotw_card" class="form-check-input" type="checkbox" role="switch" id="DashboardlotwCardCheck" <?php if ($dashboard_lotw_card) { echo 'checked'; } ?>>
<input name="user_dashboard_enable_lotw_card" class="form-check-input" type="checkbox" role="switch" id="DashboardlotwCardCheck" <?php if ($dashboard_lotw_card) {
echo 'checked';
} ?>>
<label class="form-check-label" for="DashboardlotwCardCheck">Enable Logbook of the World Card</label>
</div>
<div class="form-check form-switch">
<input name="user_dashboard_enable_vuccgrids_card" class="form-check-input" type="checkbox" role="switch" id="DashboardvuccgridsCardCheck" <?php if ($dashboard_vuccgrids_card) { echo 'checked'; } ?>>
<input name="user_dashboard_enable_vuccgrids_card" class="form-check-input" type="checkbox" role="switch" id="DashboardvuccgridsCardCheck" <?php if ($dashboard_vuccgrids_card) {
echo 'checked';
} ?>>
<label class="form-check-label" for="DashboardvuccgridsCardCheck">Enable VUCC-Grids Card</label>
</div>
</div>
@ -1166,21 +1191,29 @@
<div class="card-header"><?php echo lang('account_winkeyer'); ?> <span class="badge text-bg-danger float-end"><?php echo lang('admin_experimental'); ?></span></div>
<div class="card-body">
<div class="mb-3">
<label><?php echo lang('account_winkeyer_enabled'); ?></label>
<div class="form-check form-switch">
<?php if (!isset($user_winkey)) {
$user_winkey = '0';
} ?>
<select class="form-select" name="user_winkey" id="user_winkeyer">
<option value="0" <?php if ($user_winkey == 0) {
echo 'selected="selected"';
} ?>><?php echo lang('general_word_no'); ?></option>
<option value="1" <?php if ($user_winkey == 1) {
echo 'selected="selected"';
} ?>><?php echo lang('general_word_yes'); ?></option>
</select>
<small class="form-text text-muted"><?php echo lang('account_winkeyer_hint'); ?></small>
<input name="user_winkey" class="form-check-input" type="checkbox" role="switch" id="user_winkeyer" value="1" <?php if ($user_winkey == 1) {
echo 'checked';
} ?>>
<label class="form-check-label" for="user_winkeyer"><?php echo lang('account_winkeyer_enabled'); ?></label>
</div>
</div>
<hr />
<div class="mb-3">
<div class="form-check form-switch">
<input name="user_winkey_websocket" class="form-check-input" type="checkbox" role="switch" id="user_winkey_websocket" value="1" <?php if ($user_winkey_websocket == 1) {
echo 'checked';
} ?>>
<label class="form-check-label" for="user_winkey_websocket">Winkey Web Sockets</label>
</div>
</div>
<small class="form-text text-muted d-block mt-3"><?php echo lang('account_winkeyer_hint'); ?></small>
</div>
</div>
</div>
</div>

查看文件

@ -12,37 +12,50 @@
<table class="profile">
<tr>
<td width="100px">Username</td>
<td><?php if(isset($user_name)) { echo $user_name; } ?></td>
<td><?php if (isset($user_name)) {
echo $user_name;
} ?></td>
</tr>
<tr>
<td>Level</td>
<td><?php $l = $this->config->item('auth_level'); echo $l[$user_type]; ?></td>
<td><?php $l = $this->config->item('auth_level');
echo $l[$user_type]; ?></td>
</tr>
<tr>
<td>E-mail</td>
<td><?php if(isset($user_email)) { echo $user_email; } ?></td>
<td><?php if (isset($user_email)) {
echo $user_email;
} ?></td>
</tr>
<tr>
<td>Callsign</td>
<td><?php if(isset($user_callsign)) { echo $user_callsign; } ?></td>
<td><?php if (isset($user_callsign)) {
echo $user_callsign;
} ?></td>
</tr>
<tr>
<td>Gridsquare</td>
<td><?php if(isset($user_locator)) { echo $user_locator; } ?></td>
<td><?php if (isset($user_locator)) {
echo $user_locator;
} ?></td>
</tr>
<tr>
<td>First name</td>
<td><?php if(isset($user_firstname)) { echo $user_firstname; } ?></td>
<td><?php if (isset($user_firstname)) {
echo $user_firstname;
} ?></td>
</tr>
<tr>
<td>Last name</td>
<td><?php if(isset($user_lastname)) { echo $user_lastname; } ?></td>
<td><?php if (isset($user_lastname)) {
echo $user_lastname;
} ?></td>
</tr>
</table>

查看文件

@ -174,14 +174,13 @@ function handleInput() {
/^[A-Z0-9]{1,3}\/[A-Z]{2}-\d{3}|[AENOS]*[FNSUACA]-\d{3}|(?!.*FF)[A-Z0-9]{1,3}-\d{4,5}|[A-Z0-9]{1,3}[F]{2}-\d{4}$/i
)
) {
sotaWwff = item.toUpperCase();
} else if (
sotaWwff = item.toUpperCase(); } else if (
item.match(
/([a-zA-Z0-9]{1,3}[0-9][a-zA-Z0-9]{0,3}[a-zA-Z])|.*\/([a-zA-Z0-9]{1,3}[0-9][a-zA-Z0-9]{0,3}[a-zA-Z])|([a-zA-Z0-9]{1,3}[0-9][a-zA-Z0-9]{0,3}[a-zA-Z])\/.*/
)
) {
callsign = item.toUpperCase();
} else if (itemNumber > 0 && item.match(/^\d{1,3}$/)) {
} else if (itemNumber > 0 && (item.match(/^\d{1,3}$/) || item.match(/^[+-]\d{1,2}$/))) {
if (rst_s === null) {
rst_s = item;
} else {
@ -566,6 +565,15 @@ function getReportByMode(rst, mode) {
return "599";
}
// Handle digital modes with dB signal reports (e.g., -09, +00)
if ((mode.toUpperCase() === "FT8" || mode.toUpperCase() === "FT4" || mode.toUpperCase() === "JS8" ||
mode.toUpperCase() === "JT65" || mode.toUpperCase() === "JT65B" || mode.toUpperCase() === "JT6C" ||
mode.toUpperCase() === "JTMS" || mode.toUpperCase() === "ISCAT" || mode.toUpperCase() === "MSK144" ||
mode.toUpperCase() === "JTMSK" || mode.toUpperCase() === "QRA64" || mode.toUpperCase() === "JT9" ||
mode.toUpperCase() === "JT9-1" || mode.toUpperCase() === "ROS" || mode.toUpperCase() === "Q65" ||
mode.toUpperCase() === "FST4" || mode.toUpperCase() === "FST4W") && rst.match(/^[+-]\d{1,2}$/)) {
return rst;
}
if (settingsMode === "SSB") {
if (rst.length === 1) {

查看文件

@ -88,6 +88,45 @@ async function clickConnect() {
//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"
@ -182,9 +221,11 @@ async function disconnect() {
statusBar.innerText = "Disconnected";
connectButton.innerText = "Connect"
//Close the port.
if (port) {
await port.close();
port = null;
}
}
//When the send button is pressed
function clickSend() {

查看文件

@ -511,6 +511,18 @@
]
}
},
"SO-125":{
"Modes":{
"V/U":[
{
"Uplink_Mode":"FM",
"Uplink_Freq":"145875000",
"Downlink_Mode":"FM",
"Downlink_Freq":"436666000"
}
]
}
},
"SONATE-2":{
"Modes":{
"V":[