Commit graph

7887 commits

Author SHA1 Message Date
Peter Goodhall
a3cb952a98
2.8.14 2026-06-05 13:33:45 +01:00
copilot-swe-agent[bot]
5ad7c2e9da
Merge origin/master into dev 2026-06-05 12:30:23 +00:00
Peter Goodhall
42e6b8a335 Bump migration to 271 and add tag 2.8.14
Update migration_version to 271 and add Migration_tag_2_8_14. The new migration sets options.version to 2.8.14 and resets user_options (version_dialog/confirmed) to 'false' to trigger the version info dialog for users. The down() method reverts options.version back to 2.8.13.
2026-06-05 13:27:15 +01:00
Peter Goodhall
764c61b0a4 Add advanced search status and UI state persistence
Introduce an advanced search status display and persist UI state for the Logbook Advanced view. Adds CSS and a status span to show result/selection counts and transient messages. Implements setAdvancedSearchStatus(), getVisibleColumnIndex(), restoreAdvancedSearchUiState() and persistAdvancedSearchUiState() to update status, handle visible columns dynamically, and save/restore collapsed sections and the QSO results selection via localStorage. Also adds client-side date range validation, sets status messages during load/search/failure, and updates status when rows are selected/unselected. Adjusts band/mode column lookups to respect visible columns.
2026-06-01 21:46:30 +01:00
Peter Goodhall
32dd9af125 Normalize user_options and add defaults
Decode the PHP $options JSON into an object, ensure pota/operator/stationLocation keys exist (each with show:'true') when missing, and emit user_options via json_encode. Replace the previous string-based JS assembly with a robust PHP-side normalization and set $options for the view to the normalized object. Also add a defensive JS check around user_options.operator.show to avoid runtime errors when operator is absent.
2026-06-01 18:23:39 +01:00
Peter Goodhall
5f72af8338 Prefer selected radio CAT over sat defaults
Detect a selected radio and avoid reapplying saved satellite defaults when CAT is in use. Adds checks for a non-zero selected radio, skips restoring sat_name/sat_mode when a radio is selected, clears sat fields and their stored catValue, and triggers a radios change to resync CAT state. Also updates reset-on-escape behavior to preserve/clear satellite fields appropriately to prevent stale values from being restored.
2026-05-29 17:42:30 +01:00
Peter Goodhall
ab219e8cb4 Prevent duplicate Escape handling and fix SAT reset
Avoid double-processing of the Escape key by setting a timestamp (window.cloudlogQsoEscHandledAt) when handling the QSO-escape keydown and short-circuiting subsequent handlers within 500ms. Also broaden the SAT field restore logic in resetQsoEntryOnEscape to restore sat_name/sat_mode when preSatMode exists or when the previous propagation mode was SAT (not just when preSatName is present). These changes prevent accidental duplicate resets and ensure SAT fields are correctly restored.
2026-05-28 22:19:53 +01:00
Peter Goodhall
9894c627db Retry radio sync after saving QSO
After reapplying post-save defaults, schedule a second call to syncFromSelectedRadioAfterReset (250ms delay) in addition to the immediate call. This helps ensure the selected radio state is correctly propagated and avoids timing/race issues with UI or async updates after saving a QSO.
2026-05-28 22:16:42 +01:00
Peter Goodhall
9057e13fc2 Sync radio after post-save reset
Call syncFromSelectedRadioAfterReset() after reapplyPostSaveDefaults() in assets/js/sections/qso.js so the radio state is re-synchronized following a QSO save/reset. This prevents stale UI values and ensures fields reflect the currently selected radio after saving.
2026-05-28 22:16:07 +01:00
Peter Goodhall
5b3272eafc Return upload status and report no Clublog QSOs
Track and return whether any QSOs were actually uploaded to Clublog and log/report when none are pending. index(): introduced $uploaded_any_qsos and aggregate per-user upload results; if nothing uploaded, echo a message and write an info log. uploadUser(): return false on invalid Clublog username (was previously void); added $uploaded_for_user tracking while iterating station profiles and set it when Clublog responds with 'accepted'. uploadUser now returns true when QSOs were uploaded for the user, otherwise false.
2026-05-28 13:42:41 +01:00
Peter Goodhall
0e0244dd73 Resolve file path for Clublog uploads
Use FCPATH to build the upload file path and fall back to DOCUMENT_ROOT plus the configured install directory if the file is missing. Normalizes leading/trailing slashes and casts values to strings to avoid notices, and checks file existence before attempting the fallback. This improves robustness when the app is installed in a subdirectory or when DOCUMENT_ROOT is not set.
2026-05-28 13:40:47 +01:00
Peter Goodhall
538f6ccf8a Clear selectPropagation when prop_mode empty
Trim and store data.prop_mode into propModeFromCat and use it to decide how to update the propagation select. If the value is empty, clear #selectPropagation and remove its stored catValue to avoid carrying stale propagation settings; otherwise call cat2UI with the trimmed value. This prevents leftover propagation mode when CAT provides no prop_mode.
2026-05-27 22:27:52 +01:00
Peter Goodhall
c610e1e378 Preserve satellite fields & save radio default
Prevent CAT polling from overwriting user-entered satellite fields by introducing lockSatelliteFieldsToUserInput and only updating #sat_name, #sat_mode and propagation when not locked. Clear stale sat fields if CAT returns empty values. Reset the lock on radio changes and when UI is reset, and set the lock dynamically on user input (or when propagation is SAT).

Also persist the selected radio as a post-save default: include radio in postSaveDefaults, restore it in reapplyPostSaveDefaults (update selects and localStorage), and trigger sat_name input after restore so the locking logic reacts to restored satellite fields.
2026-05-27 22:04:14 +01:00
Peter Goodhall
c02e0d7a1f Persist qso start_date in post-save defaults
Capture the QSO start_date when a record is saved and include it in postSaveDefaults so it can be reapplied. Added retrieval of start_date from #qso_input on save and updated reapplyPostSaveDefaults to set the start_date input when provided, preserving the user's selected start date after save.
2026-05-25 14:16:26 +01:00
Peter Goodhall
320370e90e Default winkey_websocket to false when unset
Check isset($u->row()->winkey_websocket) before casting to bool and default to false if the property is missing. This prevents PHP notices and ensures a consistent boolean value when the winkey_websocket field is null or not present.
2026-05-21 22:35:46 +01:00
Peter Goodhall
e7045f3d5a Support varying slp permission column names
Add get_slp_permission_column() to detect and cache the permission column name in station_logbooks_permissions (checks permission_level, access_level, then falls back to legacy permission). Replace hardcoded slp.permission_level references with the resolved column (aliasing to permission_level where needed) across show_all(), public_slugs_accessible_by_user(), check_logbook_is_accessible(), get_user_permission(), add_user_to_logbook(), and list_logbook_collaborators() to avoid failures on partially migrated databases.
2026-05-21 16:12:22 +01:00
Peter Goodhall
3ca30c161a Remove redundant qso['lng'] assignments
Delete duplicate qso['lng'] assignments in application/controllers/Api.php. Longitude is stored in qso['long'], so removing the extra qso['lng'] assignments (from plot_latlng and dxcc fallback) avoids redundant/conflicting keys and keeps the QSO data consistent.
2026-05-18 22:02:40 +01:00
Peter Goodhall
318d9a4c6f Prefer VUCC grids for gridsquare and coords
Prefer COL_VUCC_GRIDS over COL_GRIDSQUARE when populating the gridsquare field, and compute plotting coordinates from the grid (via qralatlng) to support VUCC multi-grid line/corner records. Populate lat, long and lng from the grid-derived coordinates, and only fall back to DXCC table coordinates if grid-derived values are not present, avoiding accidental overrides.
2026-05-18 22:00:22 +01:00
Peter Goodhall
769837ce09 Apply user remote_operation option and messaging
Load and interpret the 'remote_operation' user option when no POST value is provided, converting stored 'true'/'1' to 1 and falling back to the existing database value or 0. Ensure post_data always has a default 'user_remote_operation' of '0'. Use a strict check on $post_data['user_remote_operation'] === '1' when persisting the option via user_options_model, and append a concise enabled/disabled status to the success flash message after editing the user.
2026-05-16 16:01:12 +01:00
Peter Goodhall
4f462683a7 Add microphone mute toggle to remote operation
Add a microphone mute control to the remote operation UI and wire it into the audio pipeline and settings. A new checkbox (remoteOperationMicMuteToggle) is added to the view. JavaScript gains a micMuted setting (default true), persistence to localStorage, UI syncing, and an applyMicMuteState() helper which enables/disables audio tracks on the media stream. The setting is applied when a stream is attached and updated immediately when the user toggles the checkbox.
2026-05-16 14:19:50 +01:00
Peter Goodhall
c9e0761383 Persist remote operation secret to account
Add server endpoints to store and retrieve the remote operation link password in the user's account and update the client to use them. Qso controller: added remoteoperationsecret_json and remoteoperationsecret_save which use user_options_model and CI encryption to get/set an encrypted link_password (save enforces a minimum 16-char password, empty value clears it). View and JS: default WebSocket URL changed to wss://relay.cloudlog.org/ws-webrtc; client no longer stores link password in localStorage and instead loads/saves it via the new endpoints (with error handling and UI feedback). Also clear the account secret on reset and stop exposing the password in browser storage.
2026-05-16 13:55:11 +01:00
Peter Goodhall
7c0c7515a5 Add experimental Remote Operation feature
Introduce an experimental browser-based remote audio feature: bump migration version to 270 and add a migration to add a remote_operation flag to the users table. Add server-side support to User and QSO controllers/models to read/save the remote_operation option (stored via user_options_model) and expose isRemoteOperationEnabled to views and session updates. Add UI: a Remote Operation card on the QSO page, a modal component for detailed settings, a toggle in the user edit page, and conditional loading of assets/js/remote-operation.js. Add a large client-side implementation (assets/js/remote-operation.js) implementing WebRTC signalling, device selection, level meters and diagnostics. Minor session/session-update and helper changes to keep UI state in sync.
2026-05-16 13:44:09 +01:00
Peter Goodhall
66e81bbdc4 Add TEVEL2 satellites and migration
Bump migration version to 269, add TEVEL2-1..TEVEL2-9 entries to the Lotw satellite mapping, and add migration 269_set_tevel2_series_to_notsent. The migration sets COL_LOTW_QSL_SENT = 'N' for TEVEL2-1 through TEVEL2-9 so their QSOs are marked not-sent to LoTW; down() is intentionally empty since previous per-QSO sent state cannot be safely restored.
2026-05-16 11:45:03 +01:00
Peter Goodhall
c27442df52 Revamp Winkey macros modal layout
Replace verbose stacked inputs with a compact, responsive grid for F1–F5 macros, add placeholder examples and a macro tokens note, and prefill values in the results view via a $macro_result variable. Also make the modal larger and scrollable and add a close button to improve usability.
2026-05-15 16:17:51 +01:00
Peter Goodhall
cc7593c892 Add WinKey relay settings API and UI persistence
Introduce server endpoints to get/save WinKey WebSocket relay settings and token (winkeyrelaysettings_json, winkeyrelaysettings_save, winkeyrelaytoken_json, winkeyrelaytoken_save) using the user_options_model. Add client-side changes to load settings from the account (with a localStorage fallback), save settings to the account, validate URL/token (ws:// or wss:// and token ≥ 8 chars), and clear legacy localStorage keys after a successful save. Defer WebSocket connect until account settings are loaded and update UI text to reflect that relay settings are stored in the user account and follow login across devices.
2026-05-15 14:19:48 +01:00
Peter Goodhall
64c97e71fd Add Winkey Relay support and settings UI
Introduce optional Winkey Relay transport for CW commands and a browser-based settings UI. Adds localStorage-backed relay config (enabled, url, token, room), a modal to edit/save settings, and validation for URL/token/room. WebSocket logic now switches between direct localhost connection and relay mode, handles relay protocol messages (join, frame, error), authenticates/join on open, and wraps sends via sendWinkeyCommand to support framed relay messages. Updates UI: new Relay button/modal, changed Settings button label/icon, socket status badge updates, and reconnect on save. Keeps compatibility with direct WebSocket server and retains logging and sidetone playback behavior.
2026-05-15 13:48:34 +01:00
Peter Goodhall
7a54c05c05 Add CW sidetone volume and responsive layout
Revamp CW sidetone UI and state handling: reorganize controls into responsive Bootstrap columns, switch the enable control to a form-switch, add a Volume range control and a status badge, and make frequency/volume labels responsive. Update cw-sidetone.js to persist and load a new volume setting, add updateVolumeLabel and updateStatusLabel helpers, and wire volume/status interactions in initControls. Persisted keys in localStorage now include cloudlog.cwSidetone.volume.
2026-05-14 23:00:45 +01:00
Peter Goodhall
d7da056ce3 Enable Enter key to send sendText messages
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.
2026-05-14 22:36:19 +01:00
Peter Goodhall
11ccec5901 Add CW speaker sidetone and UI controls
Introduce a client-side CW sidetone feature: add assets/js/cw-sidetone.js (AudioContext-based morse generator with persistence for enabled/frequency), and wire it into the UI and existing send flows. Include the new script in the footer and add speaker sidetone controls (enable checkbox + frequency slider) to the QSO view. Update winkey.js and websocket macro send handlers to compute a single textToSend, send it as before, and call window.cloudlogCwSidetone.playText(...) when available; also add defensive element existence checks. This provides audible sidetone feedback for CW macros and manual sends while preserving backwards compatibility when the sidetone module is not present.
2026-05-14 22:34:51 +01:00
Peter Goodhall
0fe9cf7ba7 Defer input focus to next event loop
Replace direct sendTextEl.focus() with setTimeout(..., 0) so the input is focused on the next tick. This avoids timing issues where an immediate focus call can be overridden by synchronous handlers (e.g. blur/submit) and ensures the message input reliably regains focus after sending.
2026-05-12 17:10:56 +01:00
Peter Goodhall
0aaf722b6e Focus input after sending message
When sending a WebSocket message, the input clearing logic now caches the sendText element, clears its value and calls focus() so the user can immediately start typing the next message. This improves UX by returning focus to the input and slightly refactors the DOM access into a local constant.
2026-05-12 17:04:20 +01:00
Peter Goodhall
35354db2c5 Check correct flag before clearing cache
Fixes a conditional in Logbook_model.php where the cache-clear check used the wrong variable. The condition now uses $skipexport instead of $skipCacheClear so dashboard cache is skipped appropriately during export operations and cleared otherwise.
2026-05-09 23:52:24 +01:00
Peter Goodhall
77cd61408c Add skipCacheClear option to import
Add a $skipCacheClear parameter to Logbook_model::import() to skip clearing the dashboard cache for each imported record. Bulk import loop now calls import(..., true) and clears the cache once after all records are processed, reducing repeated cache invalidations and improving import performance. Default behavior remains unchanged (parameter defaults to false).
2026-05-09 22:22:40 +01:00
Peter Goodhall
397d32162c Hide htmx loading indicator in dashboard
Add inline CSS to application/views/dashboard/index.php to forcibly hide the .htmx-indicator (display: none !important). This prevents the htmx loading spinner from appearing in the dashboard UI.
2026-05-08 11:33:25 +01:00
Peter Goodhall
e896b6048c Improve QSO view mobile responsiveness
Add responsive styles and layout changes to improve usability on small screens: introduce CSS under @media (max-width:991.98px) to enable horizontal scrolling for tab bars, hide less-important table columns, adjust spacing and button widths, and remove scrollbars. Update column classes (col-sm -> col-lg and many inputs to col-6) so form fields stack better on mobile. Add a collapsible "More QSO Fields" button to surface optional fields on small devices and make the QSO map hidden on small screens (d-none d-md-block). Overall changes improve layout, readability and touch behavior for mobile users.
2026-05-08 11:31:34 +01:00
Peter Goodhall
1aff7dcf50 Make logbook header and table responsive
Add responsive styles and restructure header markup for better mobile layout (flex column on small, row on md+; full-width diary button on small). Update echo_table_header_col() and echo_table_col() to accept an optional CSS class and apply it to th/td elements. Apply Bootstrap responsive utility classes (d-none d-sm-/d-md-/d-lg-table-cell) to hide less-important columns on smaller screens and adjust time column visibility. These changes improve readability on narrow viewports while preserving existing tooltips and badges.
2026-05-07 22:19:02 +01:00
Peter Goodhall
0413d8a6bf Refactor dashboard helpers and improve UX
Move repeated table rendering helpers into a new application/helpers/dashboard_helper.php and load it from the Dashboard controller to remove duplication in views. Improve mobile/responsive dashboard behavior: detect mobile user agent to reduce recent-QSO rows, add mobile-specific quick links, collapse cards for compact display, and adjust HTMX polling intervals and targets. Add htmx loading indicators and last-updated timestamps with a small JS handler, and include minor CSS tweaks. Also add a session validation early-return in radio_display_component and load the user_agent library in the controller.
2026-05-07 22:12:05 +01:00
Peter Goodhall
e25714b37a Update GMDX Summer Challenge to 2026
Advance the GMDX Summer Challenge event to 2026: update controller week end timestamps, and update view copy and table dates/entry link to reflect the new event window (11 May – 5 July 2026). In the model introduce START_DATE (2026-05-11), add validation to ignore empty/null COL_GRIDSQUARE values, and change combined-count logic to normalize gridsquares and group modes into CW / VOICE / DIGITAL so counts are consistent and case-insensitive.
2026-05-06 10:33:35 +01:00
Peter Goodhall
177f605183 Add year filter to DXCC awards
Add a year filter to the DXCC awards UI and backend. Controller: populate worked_years for the view and read/sanitize a year POST value (default 'All'). Model: introduce addYearToQuery() to append a YEAR(col_time_on) clause to existing DXCC queries and call it in relevant query paths; add get_worked_years() to return distinct worked years for the active logbook locations. View: add a year select dropdown to the DXCC awards form. This enables narrowing DXCC results by year.
2026-05-03 22:48:10 +01:00
Peter Goodhall
f5e4b0b1a6 Add .env ignores; remove docs and examples
Update .gitignore to ignore /.env and /PluginDirectory/.env. Remove documentation and example plugin assets under docs/ (including awards-plugin-guide, plugin-manager-guide, plugin-system-phase1, qso-hooks-plugin-guide and example plugin folders/archives) to clean up obsolete docs and sample plugins.
2026-05-03 13:47:07 +01:00
Peter Goodhall
7e40a0288e Add resilient CAT polling with backoff and warnings
Replace the fixed 3s setInterval CAT updater with a scheduled poller that supports exponential backoff, failure counting, and UI warnings. Introduces consecutiveCatPollFailures, catPollTimer, lastSuccessfulCatUpdateAt, and constants for base/max intervals and warning threshold. Adds helper functions to compute delays, schedule polls, handle success/failure, show/clear warning banners, and only poll the currently selected radio. Clears warnings on login error/reset/selection changes and resets failure counters when selection changes to maintain responsive UI.
2026-05-01 10:23:08 +01:00
Peter Goodhall
e6f6dd2265 Disable caching for radio JSON; use $.ajax
Add no-cache HTTP headers in Radio::json to prevent cached responses. Replace client-side $.getJSON with $.ajax(url, {dataType:'json', cache:false}) and preserve the stale-response checks while updating lastProcessedCatRequest only when a response is applied. Also ensure login errors return early. These changes ensure fresh CAT data and avoid stale or cached responses affecting the UI.
2026-05-01 10:22:11 +01:00
Peter Goodhall
fd49056a98 Enforce plugin read-only policy and show alerts
Add server-side read-only policy checks for plugins and surface security alerts to admins. Plugin_manager now validates plugin code (collects PHP files and scans for forbidden file/system/exec functions) during install and before enabling; installs are blocked or plugins auto-disabled on violation with a security alert returned. Plugins controller updated to use session validation for login, enforce admin (user_type 99) access, store/display security alerts via a flash session key, and pass a CSRF token to the view. The plugins index view now renders a warning banner for plugin security alerts. Documentation updated to link and include a new QSO Hooks plugin guide for third-party sync plugins.
2026-04-30 23:03:29 +01:00
Peter Goodhall
d2d8123754 Auto-disable plugins on runtime failures
Automatically disable plugins when runtime errors or invalid plugin entry/metadata are detected. Adds a disable_plugin_after_failure helper to both Cloudlog_hooks and Plugin_manager that marks the plugin as 'disabled' in plugins_model and logs the reason. Cloudlog_hooks now disables plugins for missing hook methods, exceptions in filters/actions, invalid entry paths/class names, include failures, and construction failures. Plugin_manager disables plugins for invalid award method names, instantiation failures, missing award methods, award render exceptions, and include failures. Documentation updated to mention the new auto-disable behavior.
2026-04-29 22:44:10 +01:00
Peter Goodhall
264d6f0b0b Add plugin award menu and settings
Support plugin-provided awards and user-configurable visibility. Controller now loads plugin entries and user options, exposes plugin_award_entries and plugin_award_visibility to views, and adds savePluginAward() to validate input and persist visibility via user_options_model. Views: settings page renders plugin award rows with checkboxes; header only shows plugin awards that are enabled. JS: award_settings.js and awards.js handle plugin award checkbox events, call the new savePluginAward endpoint, and provide saving/feedback UI. Includes input sanitization, slug validation, and preserves existing core award flows.
2026-04-29 22:40:24 +01:00
Peter Goodhall
4cfab6fe4e Add plugin system and Plugin Manager
Introduce a plugin framework and management UI: adds Plugin Manager controller, Plugin_awards controller, Plugin_manager and Cloudlog_hooks libraries, Plugins_model, migration (268) to create the plugins table, and views for plugin manager and award pages. Integrates hooks into Logbook_model (qso.filter.before_save, qso.action.after_save, qso.action.after_edit), updates header to show award plugin entries and a Plugin Manager menu link, and bumps migration_version to 268. Also adds .gitignore rules, plugin index placeholder, docs and example plugin packages. The Plugin Manager supports uploading/installing ZIP packages, safe extraction, manifest validation, enable/disable/delete actions, and CSRF protection.
2026-04-29 22:33:22 +01:00
Peter Goodhall
96eee63bc8 Update upcoming_dxccs.php 2026-04-29 16:52:14 +01:00
Peter Goodhall
0cf4c9bf77 SFLE SAT support fix 2026-04-29 12:54:06 +01:00
Peter Goodhall
d3c5cd454e
SFLE SAT support fix 2026-04-29 12:53:44 +01:00
phl0
f137a2ed26
Handle band and prop_mode properly 2026-04-29 09:27:05 +02:00