Move Display-like settings into Display panel, add input for grid locator and (not yet implemented) toggles for columns. #19

This commit is contained in:
Ian Renton
2025-10-12 10:06:09 +01:00
parent 3500ec7e03
commit b61f08768c
8 changed files with 260 additions and 68 deletions

View File

@@ -55,7 +55,7 @@ spot-providers:
-
class: "DXCluster"
name: "W3LPL Cluster"
enabled: true
enabled: false
host: "w3lpl.net"
port: 7373
login_prompt: "Please enter your call: "

View File

@@ -179,7 +179,6 @@ def get_qrzcq_data_for_callsign(call):
# Iterate in reverse order - see comments on the data structure itself
for entry in reversed(QRZCQ_CALLSIGN_LOOKUP_DATA):
if call.startswith(entry["prefix"]):
print(call + " " + str(entry))
return entry
return None

View File

@@ -7,7 +7,8 @@
</div>
<div class="col-auto">
<p class="d-inline-flex gap-1">
<button id="filters-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button"><i class="fa-solid fa-filter"></i> Filters</button>
<button id="filters-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleFiltersPanel();"><i class="fa-solid fa-filter"></i> Filters</button>
<button id="display-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleDisplayPanel();"><i class="fa-solid fa-desktop"></i> Display</button>
</p>
</div>
</div>
@@ -16,10 +17,10 @@
<div class="card-header text-white bg-primary">
<div class="row">
<div class="col-auto me-auto">
filters
Filters
</div>
<div class="col-auto d-inline-flex">
<button id="close-filters-button" type="button" class="btn-close btn-close-white" aria-label="Close"></button>
<button id="close-filters-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeFiltersPanel();"></button>
</div>
</div>
@@ -29,24 +30,94 @@
</div>
</div>
<div id="table-container"></div>
<div id="display-area" class="appearing-panel card mb-3">
<div class="card-header text-white bg-primary">
<div class="row">
<div class="col-auto me-auto">
Display
</div>
<div class="col-auto d-inline-flex">
<button id="close-display-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeDisplayPanel();"></button>
</div>
</div>
<p>
<span class="form-check form-switch d-inline-block">
<input class="form-check-input storeable-checkbox" type="checkbox" role="switch" id="useLocalTime" onclick="localTimeUpdated();">
<label class="form-check-label" for="useLocalTime">Local time</label>
</span>
<span class="ms-5">Alerts to view:
<select id="alerts-to-fetch" class="storeable-select form-select ms-2" onclick="filtersUpdated();" style="width: 5em;display: inline-block;">
</div>
<div class="card-body">
<div id="display-container" class="row row-cols-1 row-cols-md-3 g-4">
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">Time Zone</h5>
<p class="card-text spothole-card-text"> Use
<select id="timeZone" class="storeable-select form-select ms-2 me-2 d-inline-block" oninput="timeZoneUpdated();" style="width: 8em; display: inline-block;">
<option value="UTC" selected>UTC</option>
<option value="local">Local time</option>
</select>
</p>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">Number of Alerts</h5>
<p class="card-text spothole-card-text">Show up to
<select id="alerts-to-fetch" class="storeable-select form-select ms-2" oninput="filtersUpdated();" style="width: 5em;display: inline-block;">
<option value="25">25</option>
<option value="50">50</option>
<option value="100" selected>100</option>
<option value="200">200</option>
<option value="500">500</option>
</select>
</span>
alerts
</p>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">Table Data</h5>
<div class="form-group">
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowStartTime" value="tableShowStartTime" checked disabled>
<label class="form-check-label" for="tableShowStartTime">Start Time</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowEndTime" value="tableShowEndTime" checked disabled>
<label class="form-check-label" for="tableShowEndTime">End Time</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowDX" value="tableShowDX" checked disabled>
<label class="form-check-label" for="tableShowDX">DX</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowFreqsModes" value="tableShowFreqsModes" checked disabled>
<label class="form-check-label" for="tableShowFreqsModes">Frequencies & Modes</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowComment" value="tableShowComment" checked disabled>
<label class="form-check-label" for="tableShowComment">Comment</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowSource" value="tableShowSource" checked disabled>
<label class="form-check-label" for="tableShowSource">Source</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowRef" value="tableShowRef" checked disabled>
<label class="form-check-label" for="tableShowRef">Ref.</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="table-container"></div>
</div>
<script src="/js/common.js"></script>
<script src="/js/alerts.js"></script>

View File

@@ -22,7 +22,8 @@
</div>
<div class="col-auto">
<p class="d-inline-flex gap-1">
<button id="filters-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button"><i class="fa-solid fa-filter"></i> Filters</button>
<button id="filters-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleFiltersPanel();"><i class="fa-solid fa-filter"></i> Filters</button>
<button id="display-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleDisplayPanel();"><i class="fa-solid fa-desktop"></i> Display</button>
</p>
</div>
</div>
@@ -31,10 +32,10 @@
<div class="card-header text-white bg-primary">
<div class="row">
<div class="col-auto me-auto">
filters
Filters
</div>
<div class="col-auto d-inline-flex">
<button id="close-filters-button" type="button" class="btn-close btn-close-white" aria-label="Close"></button>
<button id="close-filters-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeFiltersPanel();"></button>
</div>
</div>
@@ -45,23 +46,112 @@
</div>
</div>
<div id="table-container"></div>
<div id="display-area" class="appearing-panel card mb-3">
<div class="card-header text-white bg-primary">
<div class="row">
<div class="col-auto me-auto">
Display
</div>
<div class="col-auto d-inline-flex">
<button id="close-display-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeDisplayPanel();"></button>
</div>
</div>
<p>
<span class="form-check form-switch d-inline-block">
<input class="form-check-input storeable-checkbox" type="checkbox" role="switch" id="useLocalTime" onclick="localTimeUpdated();">
<label class="form-check-label" for="useLocalTime">Local time</label>
</span>
<span class="ms-5">Spots to view:
<select id="spots-to-fetch" class="storeable-select form-select ms-2 d-inline-block" onclick="filtersUpdated();" style="width: 5em;">
</div>
<div class="card-body">
<div id="display-container" class="row row-cols-1 row-cols-md-4 g-4">
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">Time Zone</h5>
<p class="card-text spothole-card-text"> Use
<select id="timeZone" class="storeable-select form-select ms-2 me-2 d-inline-block" oninput="timeZoneUpdated();" style="width: 8em; display: inline-block;">
<option value="UTC" selected>UTC</option>
<option value="local">Local time</option>
</select>
</p>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">Number of Spots</h5>
<p class="card-text spothole-card-text">Show up to
<select id="spots-to-fetch" class="storeable-select form-select ms-2 me-2 d-inline-block" oninput="filtersUpdated();" style="width: 5em; display: inline-block;">
<option value="10">10</option>
<option value="25">25</option>
<option value="50" selected>50</option>
<option value="100">100</option>
</select>
</span>
spots
</p>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">Table Data</h5>
<div class="form-group">
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowTime" value="tableShowTime" checked disabled>
<label class="form-check-label" for="tableShowTime">Time</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowDX" value="tableShowDX" checked disabled>
<label class="form-check-label" for="tableShowDX">DX</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowFreq" value="tableShowFreq" checked disabled>
<label class="form-check-label" for="tableShowFreq">Frequency</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowMode" value="tableShowMode" checked disabled>
<label class="form-check-label" for="tableShowMode">Mode</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowComment" value="tableShowComment" checked disabled>
<label class="form-check-label" for="tableShowComment">Comment</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowBearing" value="tableShowBearing" disabled>
<label class="form-check-label" for="tableShowBearing">Bearing</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowSource" value="tableShowSource" checked disabled>
<label class="form-check-label" for="tableShowSource">Source</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowRef" value="tableShowRef" checked disabled>
<label class="form-check-label" for="tableShowRef">Ref.</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowDE" value="tableShowDE" checked disabled>
<label class="form-check-label" for="tableShowDE">DE</label>
</div>
</div>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">Location</h5>
<div class="form-group spothole-card-text">
<label for="userGrid">Your grid:</label>
<input type="text" class="storeable-text form-control" id="userGrid" placeholder="AA00aa" style="width: 10em; display: inline-block;">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="table-container"></div>
</div>
<script src="/js/common.js"></script>
<script src="/js/spots.js"></script>

View File

@@ -47,7 +47,7 @@ div.appearing-panel {
display: none;
}
p.filter-card-text {
.spothole-card-text {
line-height: 2.5em !important;
}

View File

@@ -39,7 +39,7 @@ function buildQueryString() {
// Update the alerts table
function updateTable() {
// Use local time instead of UTC?
var useLocalTime = $("#useLocalTime")[0].checked;
var useLocalTime = $("#timeZone")[0].value == "local";
// Populate table with headers
let table = $('<table class="table table-striped-custom table-hover">').append('<thead><tr class="table-primary"></tr></thead><tbody></tbody>');
@@ -89,7 +89,7 @@ function addAlertRowsToTable(tbody, alerts) {
let $tr = $('<tr>');
// Use local time instead of UTC?
var useLocalTime = $("#useLocalTime")[0].checked;
var useLocalTime = $("#timeZone")[0].value == "local";
// Get times for the alert, and convert to local time if necessary.
var start_time_unix = moment.unix(a["start_time"]);
@@ -226,7 +226,7 @@ function generateMaxDurationDropdownFilterCard(band_options) {
let $card = $("<div class='card'>");
let $card_body = $("<div class='card-body'>");
$card_body.append(`<h5 class='card-title'>Duration Limit <i class='fa-solid fa-circle-question' title='Some users create long-duration alerts for the period they will be generally in and around xOTA references, when they are not indending to be on the air most of the time. Use this control to restrict the maximum duration of spots that the software will display, and exclude any with a long duration, to avoid these filling up the list. By default, we allow DXpeditions to be displayed even if they are longer than this limit, because on a DXpedition the operators typically ARE on the air most of the time.'></i></h5>`);
$p = $("<p class='card-text filter-card-text'>");
$p = $("<p class='card-text spothole-card-text'>");
$p.append("Hide any alerts lasting more than:<br/>");
$p.append(`<select id="max-duration" class="storeable-select form-select" onclick="filtersUpdated();" style="width: 8em; display: inline-block;">
<option value="10800">3 hours</option>
@@ -237,7 +237,7 @@ function generateMaxDurationDropdownFilterCard(band_options) {
<option value="9999999999">No limit</option>
</select>`);
$p2 = $("<p class='card-text filter-card-text' style='line-height: 1.5em !important;'>");
$p2 = $("<p class='card-text spothole-card-text' style='line-height: 1.5em !important;'>");
$p2.append(`<input class="form-check-input storeable-checkbox" type="checkbox" value="" onclick="filtersUpdated();" id="dxpeditions_skip_max_duration_check" checked><label class="form-check-label ms-2" for="dxpeditions_skip_max_duration_check">Allow DXpeditions that are longer</label>`);
// Compile HTML elements to return
$card_body.append($p);
@@ -252,15 +252,32 @@ function filtersUpdated() {
loadAlerts();
saveSettings();
}
// Set up UI element event listeners, after the document is ready
function setUpEventListeners() {
$("#filters-button").click(function() {
// React to toggling/closing panels
function toggleFiltersPanel() {
// If we are going to display the filters panel, hide the display panel
if (!$("#filters-area").is(":visible") && $("#display-area").is(":visible")) {
$("#display-area").hide();
$("#display-button").button("toggle");
}
$("#filters-area").toggle();
});
$("#close-filters-button").click(function() {
}
function closeFiltersPanel() {
$("#filters-button").button("toggle");
$("#filters-area").hide();
});
}
function toggleDisplayPanel() {
// If we are going to display status, load the data for the status panel, and hide the filters panel
if (!$("#display-area").is(":visible") && $("#filters-area").is(":visible")) {
$("#filters-area").hide();
$("#filters-button").button("toggle");
}
$("#display-area").toggle();
}
function closeDisplayPanel() {
$("#display-button").button("toggle");
$("#display-area").hide();
}
// Startup
@@ -269,6 +286,4 @@ $(document).ready(function() {
loadOptions();
// Update the refresh timing display every second
setInterval(updateRefreshDisplay, 1000);
// Set up event listeners
setUpEventListeners();
});

View File

@@ -34,7 +34,7 @@ function generateMultiToggleFilterCard(displayName, filterQuery, options) {
let $card = $("<div class='card'>");
let $card_body = $("<div class='card-body'>");
$card_body.append(`<h5 class='card-title'>${displayName}</h5>`);
$p = $("<p class='card-text filter-card-text'>");
$p = $("<p class='card-text spothole-card-text'>");
// Create a button for each option
options.forEach(o => {
$p.append(`<input type="checkbox" class="btn-check filter-button-${filterQuery} storeable-checkbox" name="options" id="filter-button-${filterQuery}-${o}" value="${o}" autocomplete="off" onClick="filtersUpdated()" checked><label class="btn btn-outline-primary" for="filter-button-${filterQuery}-${o}">${o}</label> `);
@@ -98,7 +98,7 @@ function escapeHtml(str) {
}
// When the "use local time" field is changed, reload the table and save settings
function localTimeUpdated() {
function timeZoneUpdated() {
updateTable();
saveSettings();
}
@@ -108,10 +108,13 @@ function saveSettings() {
// Find all storeable UI elements, store a key of "element id:property name" mapped to the value of that
// property. For a checkbox, that's the "checked" property.
$(".storeable-checkbox").each(function() {
localStorage.setItem("#" + $(this)[0].id + ":checked", $(this)[0].checked);
localStorage.setItem("#" + $(this)[0].id + ":checked", JSON.stringify($(this)[0].checked));
});
$(".storeable-select").each(function() {
localStorage.setItem("#" + $(this)[0].id + ":value", $(this)[0].value);
localStorage.setItem("#" + $(this)[0].id + ":value", JSON.stringify($(this)[0].value));
});
$(".storeable-text").each(function() {
localStorage.setItem("#" + $(this)[0].id + ":value", JSON.stringify($(this)[0].value));
});
}

View File

@@ -32,7 +32,7 @@ function buildQueryString() {
// Update the spots table
function updateTable() {
// Use local time instead of UTC?
var useLocalTime = $("#useLocalTime")[0].checked;
var useLocalTime = $("#timeZone")[0].value == "local";
// Populate table with headers
let table = $('<table class="table table-striped-custom table-hover">').append('<thead><tr class="table-primary"></tr></thead><tbody></tbody>');
@@ -211,7 +211,7 @@ function generateBandsMultiToggleFilterCard(band_options) {
let $card = $("<div class='card'>");
let $card_body = $("<div class='card-body'>");
$card_body.append(`<h5 class='card-title'>Bands</h5>`);
$p = $("<p class='card-text filter-card-text'>");
$p = $("<p class='card-text spothole-card-text'>");
// Create a button for each option
band_options.forEach(o => {
// CSS doesn't like IDs with decimal points in, so we need to replace that in the same way as when we originally
@@ -234,15 +234,31 @@ function filtersUpdated() {
saveSettings();
}
// Set up UI element event listeners, after the document is ready
function setUpEventListeners() {
$("#filters-button").click(function() {
// React to toggling/closing panels
function toggleFiltersPanel() {
// If we are going to display the filters panel, hide the display panel
if (!$("#filters-area").is(":visible") && $("#display-area").is(":visible")) {
$("#display-area").hide();
$("#display-button").button("toggle");
}
$("#filters-area").toggle();
});
$("#close-filters-button").click(function() {
}
function closeFiltersPanel() {
$("#filters-button").button("toggle");
$("#filters-area").hide();
});
}
function toggleDisplayPanel() {
// If we are going to display status, load the data for the status panel, and hide the filters panel
if (!$("#display-area").is(":visible") && $("#filters-area").is(":visible")) {
$("#filters-area").hide();
$("#filters-button").button("toggle");
}
$("#display-area").toggle();
}
function closeDisplayPanel() {
$("#display-button").button("toggle");
$("#display-area").hide();
}
// Display the intro box, unless the user has already dismissed it once.
@@ -261,8 +277,6 @@ $(document).ready(function() {
loadOptions();
// Update the refresh timing display every second
setInterval(updateRefreshDisplay, 1000);
// Set up event listeners
setUpEventListeners();
// Display intro box
displayIntroBox();
});