Add ability to tag callsigns as worked. Closes #41

This commit is contained in:
Ian Renton
2026-01-31 09:34:37 +00:00
parent 47b4ddb5c8
commit 7b409bcb67
13 changed files with 96 additions and 24 deletions

View File

@@ -145,7 +145,8 @@ function updateBands() {
// Now each spot is tagged with how far down the div it should go, add them to the DOM.
spotList.forEach(s => {
bandSpotsDiv.append(`<div class="band-spot" style="top: ${s['pxDownBandLabel']}px; border-top: 1px solid ${bandToColor(s['band'])}; border-left: 5px solid ${bandToColor(s['band'])}; border-bottom: 1px solid ${bandToColor(s['band'])}; border-right: 1px solid ${bandToColor(s['band'])};"><span class="band-spot-call">${s.dx_call}${s.dx_ssid != null ? "-" + s.dx_ssid : ""}</span><span class="band-spot-info">${s.dx_call}${s.dx_ssid != null ? "-" + s.dx_ssid : ""} ${(s.freq/1000000).toFixed(3)} ${s.mode}</span></div>`);
let worked = alreadyWorked(s["dx_call"], s["band"], s["mode"]);
bandSpotsDiv.append(`<div class="band-spot" style="top: ${s['pxDownBandLabel']}px; border-top: 1px solid ${bandToColor(s['band'])}; border-left: 5px solid ${bandToColor(s['band'])}; border-bottom: 1px solid ${bandToColor(s['band'])}; border-right: 1px solid ${bandToColor(s['band'])}; text-decoration: ${worked ? 'line-through' : 'none'};"><span class="band-spot-call">${s.dx_call}${s.dx_ssid != null ? "-" + s.dx_ssid : ""}</span><span class="band-spot-info">${s.dx_call}${s.dx_ssid != null ? "-" + s.dx_ssid : ""} ${(s.freq/1000000).toFixed(3)} ${s.mode}</span></div>`);
});
// Work out how tall the canvas should be. Normally this is matching the normal band column height, but if some

View File

@@ -105,6 +105,7 @@ function updateTable() {
var showType = $("#tableShowType")[0].checked;
var showRef = $("#tableShowRef")[0].checked;
var showDE = $("#tableShowDE")[0].checked;
var showWorkedCheckbox = $("#tableShowWorkedCheckbox")[0].checked;
// Populate table with headers
let table = $("#table");
@@ -136,12 +137,18 @@ function updateTable() {
if (showDE) {
table.find('thead tr').append(`<th class='hideonmobile'>DE</th>`);
}
if (showWorkedCheckbox) {
table.find('thead tr').append(`<th class='hideonmobile'></th>`);
}
table.find('tbody').empty();
if (spots.length == 0) {
table.find('tbody').append('<tr class="table-danger"><td colspan="100" style="text-align:center;">No spots match your filters.</td></tr>');
}
// We are regenerating the entire table not just adding a new row, so reset the row counter
rowCount = 0;
let spotsNewestFirst = spots.toReversed();
spotsNewestFirst.forEach(s => addSpotToTopOfTable(s, false));
}
@@ -174,6 +181,7 @@ function createNewTableRowsForSpot(s, highlightNew) {
var showType = $("#tableShowType")[0].checked;
var showRef = $("#tableShowRef")[0].checked;
var showDE = $("#tableShowDE")[0].checked;
var showWorkedCheckbox = $("#tableShowWorkedCheckbox")[0].checked;
// Create row
let $tr = $('<tr>');
@@ -185,8 +193,9 @@ function createNewTableRowsForSpot(s, highlightNew) {
$tr.addClass("table-active");
}
// Show faded out if QRT
if (s["qrt"] == true) {
// Show faded out if QRT or already worked
let alreadyWorkedThis = alreadyWorked(s["dx_call"], s["band"], s["mode"]);
if (s["qrt"] == true || alreadyWorkedThis) {
$tr.addClass("table-faded");
}
@@ -308,6 +317,9 @@ function createNewTableRowsForSpot(s, highlightNew) {
// Format band name
var bandFullName = s['band'] ? s['band'] + " band": "Unknown band";
// Format "worked" checkbox
var workedCheckbox = `<input type="checkbox" ${alreadyWorkedThis ? "checked" : ""} onClick="setWorkedState('${s['dx_call']}', '${s['band']}', '${s['mode']}', ${alreadyWorkedThis ? "false" : "true"});">`;
// Populate the row
if (showTime) {
$tr.append(`<td class='nowrap'>${time_formatted}</td>`);
@@ -336,6 +348,9 @@ function createNewTableRowsForSpot(s, highlightNew) {
if (showDE) {
$tr.append(`<td class='nowrap hideonmobile'><span class='flag-wrapper' title='${de_country}'>${de_flag}</span>${de_call}</td>`);
}
if (showWorkedCheckbox) {
$tr.append(`<td class='nowrap hideonmobile'>${workedCheckbox}</td>`);
}
// Second row for mobile view only, containing type, ref & comment
$tr2 = $("<tr class='hidenotonmobile'>");
@@ -344,7 +359,7 @@ function createNewTableRowsForSpot(s, highlightNew) {
if (rowCount % 2 == 1) {
$tr2.addClass("table-active");
}
if (s["qrt"] == true) {
if (s["qrt"] == true || alreadyWorkedThis) {
$tr2.addClass("table-faded");
}
if (highlightNew) {
@@ -367,6 +382,9 @@ function createNewTableRowsForSpot(s, highlightNew) {
if (showDE) {
$td2floatright.append(` de ${de_call} &nbsp;`);
}
if (showWorkedCheckbox) {
$td2floatright.append(` ${workedCheckbox} &nbsp;`);
}
$td2.append($td2floatright);
$td2.append(`</div><div style="clear: both;"></div>`);
if (showComment) {
@@ -481,6 +499,27 @@ function displayIntroBox() {
});
}
// Mark a callsign-band-mode combination as worked (or unmark it). Persist this to localStorage.
function setWorkedState(callsign, band, mode, nowWorked) {
let combo = callsign + "-" + band + "-" + mode;
if (nowWorked && !worked.includes(combo)) {
worked.push(combo);
updateTable();
localStorage.setItem("worked", JSON.stringify(worked));
} else if (!nowWorked && worked.includes(combo)) {
worked.splice(worked.indexOf(combo), 1);
updateTable();
localStorage.setItem("worked", JSON.stringify(worked));
}
}
// Clear the list of worked calls
function clearWorked() {
worked = [];
updateTable();
localStorage.setItem("worked", JSON.stringify(worked));
}
// Startup
$(document).ready(function() {
// Call loadOptions(), this will then trigger loading spots and setting up timers.

View File

@@ -1,5 +1,10 @@
// Storage for the spot data that the server gives us.
var spots = []
// List of people the user has worked. Each entry has the format callsign-band-mode. These can be added to the list by
// ticking the checkbox on a row of the table, and cleared from the Display menu. Where a row would be added to the
// table and the callsign-band-mode is in this list, it is shown struck through as already worked. This is persisted
// to localStorage.
let worked = []
// Dynamically add CSS code for the band toggle buttons to be in the appropriate colour.
// Some band names contain decimal points which are not allowed in CSS classes, so we text-replace them to "p".
@@ -118,10 +123,24 @@ function setBandColorSchemeFromUI() {
window.location.reload();
}
// Query if a callsign-band-mode combination as has already been worked
function alreadyWorked(callsign, band, mode) {
return worked.includes(callsign + "-" + band + "-" + mode);
}
// Reload spots on becoming visible. This forces a refresh when used as a PWA and the user switches back to the PWA
// after some time has passed with it in the background.
addEventListener("visibilitychange", (event) => {
if (!document.hidden) {
loadSpots();
}
});
// Startup
$(document).ready(function() {
// Load worked list
var tmpWorked = JSON.parse(localStorage.getItem("worked"));
if (tmpWorked) {
worked = tmpWorked;
}
});