mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2025-10-27 16:59:25 +00:00
Fix table display on mobile #20, fix typo
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
While there are several other web-based interfaces to DX clusters, and sites that aggregate spots from various outfoor activity programmes for amateur radio, (S)pothole differentiates itself by supporting a large number of data sources, and by being "API first" rather than just providing a web front-end. This allows other software to be built on top of it.
|
While there are several other web-based interfaces to DX clusters, and sites that aggregate spots from various outdoor activity programmes for amateur radio, (S)pothole differentiates itself by supporting a large number of data sources, and by being "API first" rather than just providing a web front-end. This allows other software to be built on top of it.
|
||||||
|
|
||||||
The API is deliberately well-defined with an OpenAPI specification and auto-generated API documentation. The API delivers spots in a consistent format regardless of the data source, freeing developers from needing to know how each individual data source presents its data.
|
The API is deliberately well-defined with an OpenAPI specification and auto-generated API documentation. The API delivers spots in a consistent format regardless of the data source, freeing developers from needing to know how each individual data source presents its data.
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div id="info-container" class="mt-4">
|
<div id="info-container" class="mt-4">
|
||||||
<h3>About (S)pothole</h3>
|
<h3>About (S)pothole</h3>
|
||||||
<p>(S)pothole is a utility to aggregate "spots" from amateur radio DX clusters and xOTA spotting sites, and provide an open JSON API as well as a website to browse the data.</p>
|
<p>(S)pothole is a utility to aggregate "spots" from amateur radio DX clusters and xOTA spotting sites, and provide an open JSON API as well as a website to browse the data.</p>
|
||||||
<p>While there are several other web-based interfaces to DX clusters, and sites that aggregate spots from various outfoor activity programmes for amateur radio, (S)pothole differentiates itself by supporting a large number of data sources, and by being "API first" rather than just providing a web front-end. This allows other software to be built on top of it.</p>
|
<p>While there are several other web-based interfaces to DX clusters, and sites that aggregate spots from various outdoor activity programmes for amateur radio, (S)pothole differentiates itself by supporting a large number of data sources, and by being "API first" rather than just providing a web front-end. This allows other software to be built on top of it.</p>
|
||||||
<p>The API is deliberately well-defined with an <a href="/apidocs/openapi.yml">OpenAPI specification</a> and auto-generated <a href="/apidocs">API documentation</a>. The API delivers spots in a consistent format regardless of the data source, freeing developers from needing to know how each individual data source presents its data.</p>
|
<p>The API is deliberately well-defined with an <a href="/apidocs/openapi.yml">OpenAPI specification</a> and auto-generated <a href="/apidocs">API documentation</a>. The API delivers spots in a consistent format regardless of the data source, freeing developers from needing to know how each individual data source presents its data.</p>
|
||||||
<p>(S)pothole itself is also open source, Public Domain licenced code that anyone can take and modify. <a href="https://git.ianrenton.com/ian/metaspot/">The source code is here</a>.</p>
|
<p>(S)pothole itself is also open source, Public Domain licenced code that anyone can take and modify. <a href="https://git.ianrenton.com/ian/metaspot/">The source code is here</a>.</p>
|
||||||
<p>Supported data sources include DX Clusters, the Reverse Beacon Network (RBN), the APRS Internet Service (APRS-IS), POTA, SOTA, WWFF, GMA, WWBOTA, HEMA, and Parks 'n' Peaks.</p>
|
<p>Supported data sources include DX Clusters, the Reverse Beacon Network (RBN), the APRS Internet Service (APRS-IS), POTA, SOTA, WWFF, GMA, WWBOTA, HEMA, and Parks 'n' Peaks.</p>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ info:
|
|||||||
description: |-
|
description: |-
|
||||||
(S)pothole is a utility to aggregate "spots" from amateur radio DX clusters and xOTA spotting sites, and provide an open JSON API as well as a website to browse the data.
|
(S)pothole is a utility to aggregate "spots" from amateur radio DX clusters and xOTA spotting sites, and provide an open JSON API as well as a website to browse the data.
|
||||||
|
|
||||||
While there are other web-based interfaces to DX clusters, and sites that aggregate spots from various outfoor activity programmes for amateur radio, (S)pothole differentiates itself by supporting a large number of data sources, and by being "API first" rather than just providing a web front-end. This allows other software to be built on top of it. (S)pothole itself is also open source, Public Domain licenced code that anyone can take and modify.
|
While there are other web-based interfaces to DX clusters, and sites that aggregate spots from various outdoor activity programmes for amateur radio, (S)pothole differentiates itself by supporting a large number of data sources, and by being "API first" rather than just providing a web front-end. This allows other software to be built on top of it. (S)pothole itself is also open source, Public Domain licenced code that anyone can take and modify.
|
||||||
contact:
|
contact:
|
||||||
email: ian@ianrenton.com
|
email: ian@ianrenton.com
|
||||||
license:
|
license:
|
||||||
|
|||||||
@@ -9,6 +9,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Custom version of Bootstrap table colouring to colour 2 in every 4 rows, because of our second row per spot that
|
||||||
|
appears on mobile */
|
||||||
|
.table-striped-custom > tbody > tr:nth-of-type(4n+3) > *,
|
||||||
|
.table-striped-custom > tbody > tr:nth-of-type(4n+4) > * {
|
||||||
|
--bs-table-color-type: var(--bs-table-striped-color);
|
||||||
|
--bs-table-bg-type: var(--bs-table-striped-bg);
|
||||||
|
}
|
||||||
|
|
||||||
td.nowrap {
|
td.nowrap {
|
||||||
text-wrap: nowrap;
|
text-wrap: nowrap;
|
||||||
}
|
}
|
||||||
@@ -71,3 +79,20 @@ a.dx-link {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tr.table-faded td a.dx-link {
|
||||||
|
color: lightgray;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 991.99px) {
|
||||||
|
.hideonmobile {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.hidenotonmobile {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -59,8 +59,15 @@ function allFilterOptionsSelected(parameter) {
|
|||||||
// Update the spots table
|
// Update the spots table
|
||||||
function updateTable() {
|
function updateTable() {
|
||||||
// Populate table with headers
|
// Populate table with headers
|
||||||
let table = $('<table class="table table-striped table-hover">').append('<thead><tr class="table-primary"></tr></thead><tbody></tbody>');
|
let table = $('<table class="table table-striped-custom table-hover">').append('<thead><tr class="table-primary"></tr></thead><tbody></tbody>');
|
||||||
["UTC", "DX", "Frequency", "Mode", "Comment", "Source", "Ref.", "DE"].forEach(header => table.find('thead tr').append(`<th>${header}</th>`));
|
table.find('thead tr').append(`<th>UTC</th>`);
|
||||||
|
table.find('thead tr').append(`<th>DX</th>`);
|
||||||
|
table.find('thead tr').append(`<th>Freq<span class='hideonmobile'>uency</span></th>`);
|
||||||
|
table.find('thead tr').append(`<th>Mode</th>`);
|
||||||
|
table.find('thead tr').append(`<th class='hideonmobile'>Comment</th>`);
|
||||||
|
table.find('thead tr').append(`<th class='hideonmobile'>Source</th>`);
|
||||||
|
table.find('thead tr').append(`<th class='hideonmobile'>Ref.</th>`);
|
||||||
|
table.find('thead tr').append(`<th class='hideonmobile'>DE</th>`);
|
||||||
|
|
||||||
if (spots.length == 0) {
|
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>');
|
table.find('tbody').append('<tr class="table-danger"><td colspan="100" style="text-align:center;">No spots match your filters.</td></tr>');
|
||||||
@@ -70,7 +77,7 @@ function updateTable() {
|
|||||||
// Create row
|
// Create row
|
||||||
let $tr = $('<tr>');
|
let $tr = $('<tr>');
|
||||||
|
|
||||||
// Show in red if QRT
|
// Show faded out if QRT
|
||||||
if (s["qrt"] == true) {
|
if (s["qrt"] == true) {
|
||||||
$tr.addClass("table-faded");
|
$tr.addClass("table-faded");
|
||||||
}
|
}
|
||||||
@@ -90,7 +97,7 @@ function updateTable() {
|
|||||||
var khz = Math.floor((s["freq"] - (mhz * 1000000.0)) / 1000.0);
|
var khz = Math.floor((s["freq"] - (mhz * 1000000.0)) / 1000.0);
|
||||||
var hz = Math.floor(s["freq"] - (mhz * 1000000.0) - (khz * 1000.0));
|
var hz = Math.floor(s["freq"] - (mhz * 1000000.0) - (khz * 1000.0));
|
||||||
var hz_string = (hz > 0) ? hz.toFixed(0) : "";
|
var hz_string = (hz > 0) ? hz.toFixed(0) : "";
|
||||||
var freq_string = `<span class='freq-mhz'>${mhz.toFixed(0)}</span><span class='freq-khz'>${khz.toFixed(0).padStart(3, '0')}</span><span class='freq-hz'>${hz_string}</span>`
|
var freq_string = `<span class='freq-mhz'>${mhz.toFixed(0)}</span><span class='freq-khz'>${khz.toFixed(0).padStart(3, '0')}</span><span class='freq-hz hideonmobile'>${hz_string}</span>`
|
||||||
|
|
||||||
// Format the mode
|
// Format the mode
|
||||||
mode_string = s["mode"];
|
mode_string = s["mode"];
|
||||||
@@ -98,7 +105,7 @@ function updateTable() {
|
|||||||
mode_string = "???"
|
mode_string = "???"
|
||||||
}
|
}
|
||||||
if (s["mode_source"] == "BANDPLAN") {
|
if (s["mode_source"] == "BANDPLAN") {
|
||||||
mode_string = mode_string + "<span class='mode-q'><i class='fa-solid fa-circle-question' title='The mode was not reported via the spotting service. This is a guess based on the frequency.'></i></span>"
|
mode_string = mode_string + "<span class='mode-q hideonmobile'><i class='fa-solid fa-circle-question' title='The mode was not reported via the spotting service. This is a guess based on the frequency.'></i></span>"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format comment
|
// Format comment
|
||||||
@@ -132,14 +139,22 @@ function updateTable() {
|
|||||||
|
|
||||||
// Populate the row
|
// Populate the row
|
||||||
$tr.append(`<td class='nowrap'>${time_formatted}</td>`);
|
$tr.append(`<td class='nowrap'>${time_formatted}</td>`);
|
||||||
$tr.append(`<td class='nowrap'><span class='flag-wrapper' title='${dx_country}'>${s["dx_flag"]}</span><a class='dx-link' href='https://qrz.com/db/${s["dx_call"]}' target='_new'>${s["dx_call"]}</a></td>`);
|
$tr.append(`<td class='nowrap'><span class='flag-wrapper hideonmobile' title='${dx_country}'>${s["dx_flag"]}</span><a class='dx-link' href='https://qrz.com/db/${s["dx_call"]}' target='_new'>${s["dx_call"]}</a></td>`);
|
||||||
$tr.append(`<td class='nowrap'><span class='band-bullet band-bullet-${cssFormattedBandName}' title='${bandFullName}'>■</span>${freq_string}</td>`);
|
$tr.append(`<td class='nowrap'><span class='band-bullet band-bullet-${cssFormattedBandName}' title='${bandFullName}'>■</span>${freq_string}</td>`);
|
||||||
$tr.append(`<td class='nowrap'>${mode_string}</td>`);
|
$tr.append(`<td class='nowrap'>${mode_string}</td>`);
|
||||||
$tr.append(`<td>${commentText}</td>`);
|
$tr.append(`<td class='hideonmobile'>${commentText}</td>`);
|
||||||
$tr.append(`<td class='nowrap'><span class='icon-wrapper'><i class='fa-solid fa-${s["icon"]}'></i></span> ${s["source"]}</td>`);
|
$tr.append(`<td class='nowrap hideonmobile'><span class='icon-wrapper'><i class='fa-solid fa-${s["icon"]}'></i></span> ${s["source"]}</td>`);
|
||||||
$tr.append(`<td class='nowrap'>${sig_refs}</td>`);
|
$tr.append(`<td class='nowrap hideonmobile'>${sig_refs}</td>`);
|
||||||
$tr.append(`<td class='nowrap'><span class='flag-wrapper' title='${de_country}'>${de_flag}</span>${s["de_call"]}</td>`);
|
$tr.append(`<td class='nowrap hideonmobile'><span class='flag-wrapper' title='${de_country}'>${de_flag}</span>${s["de_call"]}</td>`);
|
||||||
table.find('tbody').append($tr);
|
table.find('tbody').append($tr);
|
||||||
|
|
||||||
|
// Second row for mobile view only, containing source, ref & comment
|
||||||
|
$tr2 = $("<tr class='hidenotonmobile'>");
|
||||||
|
if (s["qrt"] == true) {
|
||||||
|
$tr2.addClass("table-faded");
|
||||||
|
}
|
||||||
|
$tr2.append(`<td colspan="100"><span class='icon-wrapper'><i class='fa-solid fa-${s["icon"]}'></i></span> ${sig_refs} ${commentText}</td>`);
|
||||||
|
table.find('tbody').append($tr2);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update DOM
|
// Update DOM
|
||||||
|
|||||||
Reference in New Issue
Block a user