mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-09-24 16:24:32 +00:00
First attempt at converting "sig" to "activity" for v3
This commit is contained in:
+13
-13
@@ -29,7 +29,7 @@ const PROVIDER_CREDENTIAL_SCHEMAS = {
|
||||
// Load server options. Once a successful callback is made from this, we can populate the choice boxes in the form and load
|
||||
// any saved values from local storage.
|
||||
function loadOptions() {
|
||||
$.getJSON('/api/v2/options', function (jsonData) {
|
||||
$.getJSON('/api/v3/options', function (jsonData) {
|
||||
// Store options
|
||||
options = jsonData;
|
||||
|
||||
@@ -42,8 +42,8 @@ function loadOptions() {
|
||||
});
|
||||
|
||||
// Populate activity drop-down
|
||||
$.each(options["sigs"], function (i, activity) {
|
||||
$('#sig').append($('<option>', {
|
||||
$.each(options["activities"], function (i, activity) {
|
||||
$('#activity').append($('<option>', {
|
||||
value: activity.name,
|
||||
text: activity.name
|
||||
}));
|
||||
@@ -91,8 +91,8 @@ function updateUpstreamArea() {
|
||||
return;
|
||||
}
|
||||
|
||||
const sig = $("#sig").val();
|
||||
const providers = (sig && options["spot_submit_providers"][sig]) ? options["spot_submit_providers"][sig] : [];
|
||||
const activity = $("#activity").val();
|
||||
const providers = (activity && options["spot_submit_providers"][activity]) ? options["spot_submit_providers"][activity] : [];
|
||||
|
||||
if (providers.length === 0) {
|
||||
$("#upstream-area").hide();
|
||||
@@ -131,8 +131,8 @@ function updateCredentialsButton() {
|
||||
|
||||
// Get the currently selected upstream provider name
|
||||
function getSelectedUpstreamProvider() {
|
||||
const providers = (options && options["spot_submit_providers"] && $("#sig").val())
|
||||
? (options["spot_submit_providers"][$("#sig").val()] || [])
|
||||
const providers = (options && options["spot_submit_providers"] && $("#activity").val())
|
||||
? (options["spot_submit_providers"][$("#activity").val()] || [])
|
||||
: [];
|
||||
if (providers.length === 0) return null;
|
||||
if (providers.length === 1) return providers[0];
|
||||
@@ -197,8 +197,8 @@ function addSpot() {
|
||||
const dx = $("#dx-call").val().toUpperCase();
|
||||
const freqStr = $("#freq").val();
|
||||
const mode = $("#mode")[0].value;
|
||||
const sig = $("#sig")[0].value;
|
||||
const sigRef = $("#sig-ref").val();
|
||||
const activity = $("#activity")[0].value;
|
||||
const activityRef = $("#activity-ref").val();
|
||||
const dxGrid = $("#dx-grid").val();
|
||||
const comment = $("#comment").val();
|
||||
const de = $("#de-call").val().toUpperCase();
|
||||
@@ -208,8 +208,8 @@ function addSpot() {
|
||||
spot["dx_call"] = dx;
|
||||
spot["freq"] = parseFloat(freqStr) * 1000;
|
||||
if (mode !== "") spot["mode"] = mode;
|
||||
if (sig !== "") spot["sig"] = sig;
|
||||
if (sigRef !== "") spot["sig_refs"] = [{sig: sig, id: sigRef}];
|
||||
if (activity !== "") spot["activity"] = activity;
|
||||
if (activityRef !== "") spot["activity_refs"] = [{activity: activity, id: activityRef}];
|
||||
if (dxGrid !== "") spot["dx_grid"] = dxGrid;
|
||||
if (comment !== "") spot["comment"] = comment;
|
||||
spot["de_call"] = de;
|
||||
@@ -232,7 +232,7 @@ function addSpot() {
|
||||
handling["upstream_credentials"] = loadCredentials(upstreamProviderName);
|
||||
}
|
||||
|
||||
$.ajax("/api/v2/spot", {
|
||||
$.ajax("/api/v3/spot", {
|
||||
data: JSON.stringify({spot, handling}),
|
||||
contentType: 'application/json',
|
||||
type: 'POST',
|
||||
@@ -291,7 +291,7 @@ $("#mode").change(function () {
|
||||
});
|
||||
|
||||
// Update upstream area and credentials button when activity changes
|
||||
$("#sig").change(function () {
|
||||
$("#activity").change(function () {
|
||||
updateUpstreamArea();
|
||||
});
|
||||
|
||||
|
||||
+14
-14
@@ -10,7 +10,7 @@ let alerts = [];
|
||||
// to alerts
|
||||
function loadAlerts() {
|
||||
$.ajax({
|
||||
url: '/api/v2/alerts' + buildQueryString(), dataType: 'json', success: function (jsonData) {
|
||||
url: '/api/v3/alerts' + buildQueryString(), dataType: 'json', success: function (jsonData) {
|
||||
// Store last updated time
|
||||
lastUpdateTime = moment.utc();
|
||||
// Store data
|
||||
@@ -24,7 +24,7 @@ function loadAlerts() {
|
||||
// Build a query string for the API, based on the filters that the user has selected.
|
||||
function buildQueryString() {
|
||||
let str = "?";
|
||||
["dx_continent", "source", "sig"].forEach(fn => {
|
||||
["dx_continent", "source", "activity"].forEach(fn => {
|
||||
if (!allFilterOptionsSelected(fn)) {
|
||||
str = str + getQueryStringFor(fn) + "&";
|
||||
}
|
||||
@@ -210,14 +210,14 @@ function addAlertRowsToTable(tbody, alerts) {
|
||||
if (a["dx_calls"] != null) {
|
||||
dx_calls_html = a["dx_calls"].map(call => `<a class='dx-link' href='https://qrz.com/db/${call}' target='_new'>${call}</a>`).join(", ");
|
||||
}
|
||||
if (dx_calls_html === "" && a["sig"] === "Contest") {
|
||||
if (dx_calls_html === "" && a["activity"] === "Contest") {
|
||||
// Contest = true and no DX callsigns, so display "Contest"
|
||||
dx_calls_html = "Contest"
|
||||
}
|
||||
|
||||
// Format DXpedition country
|
||||
let dx_country_html = "";
|
||||
if (a["sig"] === "DXpedition" && a["dx_country"] != null && a["dx_country"] !== "") {
|
||||
if (a["activity"] === "DXpedition" && a["dx_country"] != null && a["dx_country"] !== "") {
|
||||
dx_country_html = `<br/>${a["dx_country"]}`;
|
||||
}
|
||||
|
||||
@@ -252,23 +252,23 @@ function addAlertRowsToTable(tbody, alerts) {
|
||||
|
||||
// Activity or fallback to "General DX"
|
||||
let activityText = "General DX";
|
||||
if (a["sig"]) {
|
||||
activityText = a["sig"];
|
||||
if (a["activity"]) {
|
||||
activityText = a["activity"];
|
||||
}
|
||||
|
||||
// Format activity refs
|
||||
let activityRefs = "";
|
||||
if (a["sig_refs"] != null) {
|
||||
if (a["activity_refs"] != null) {
|
||||
const items = [];
|
||||
for (let i = 0; i < a["sig_refs"].length; i++) {
|
||||
if (a["sig_refs"][i]["url"] != null) {
|
||||
items[i] = `<a href='${encodeURI(a["sig_refs"][i]["url"])}' title='${escapeHtml(a["sig_refs"][i]["name"])}' target='_new' class='activity-ref-link'>${escapeHtml(a["sig_refs"][i]["id"])}</a>`
|
||||
for (let i = 0; i < a["activity_refs"].length; i++) {
|
||||
if (a["activity_refs"][i]["url"] != null) {
|
||||
items[i] = `<a href='${encodeURI(a["activity_refs"][i]["url"])}' title='${escapeHtml(a["activity_refs"][i]["name"])}' target='_new' class='activity-ref-link'>${escapeHtml(a["activity_refs"][i]["id"])}</a>`
|
||||
} else {
|
||||
items[i] = `${escapeHtml(a["sig_refs"][i]["id"])}`
|
||||
items[i] = `${escapeHtml(a["activity_refs"][i]["id"])}`
|
||||
}
|
||||
// If this is a satellite alert the ref will just be the satellite, but DX grid is also important, so
|
||||
// show that if we can.
|
||||
if (a["sig_refs"][i]["sig"] === "Satellite" && a["dx_grid"] != null) {
|
||||
if (a["activity_refs"][i]["activity"] === "Satellite" && a["dx_grid"] != null) {
|
||||
items[i] += " from " + a["dx_grid"];
|
||||
}
|
||||
}
|
||||
@@ -330,7 +330,7 @@ function addAlertRowsToTable(tbody, alerts) {
|
||||
|
||||
// Load server options. Once a successful callback is made from this, we then query alerts.
|
||||
function loadOptions() {
|
||||
$.getJSON('/api/v2/options', function (jsonData) {
|
||||
$.getJSON('/api/v3/options', function (jsonData) {
|
||||
// Store options
|
||||
options = jsonData;
|
||||
|
||||
@@ -338,7 +338,7 @@ function loadOptions() {
|
||||
generateMultiToggleFilterCard("#dx_continent_options", "dx_continent", options["continents"]);
|
||||
generateMultiToggleFilterCard("#source-options", "source", options["alert_providers"]);
|
||||
// Alerts can only ever be tagged with activities that have an alert source, so only offer those as filters here
|
||||
generateActivitiesMultiToggleFilterCard(options["sigs"].filter(o => o["alerts_possible"]), false);
|
||||
generateActivitiesMultiToggleFilterCard(options["activities"].filter(o => o["alerts_possible"]), false);
|
||||
|
||||
// Load URL params. These may select things from the various filter & display options, so the function needs
|
||||
// to be called after these are set up, but if the URL params ask for "embedded mode", this will suppress
|
||||
|
||||
+5
-5
@@ -20,7 +20,7 @@ function loadSpots() {
|
||||
sseAbortController.abort();
|
||||
}
|
||||
$.ajax({
|
||||
url: '/api/v2/spots' + buildQueryString(), dataType: 'json', success: function (jsonData) {
|
||||
url: '/api/v3/spots' + buildQueryString(), dataType: 'json', success: function (jsonData) {
|
||||
// Store data
|
||||
spots = jsonData;
|
||||
// Update bands display
|
||||
@@ -39,7 +39,7 @@ function startSSEConnection() {
|
||||
sseAbortController = new AbortController();
|
||||
|
||||
// No need to include QRZ/HamQTH credentials because the information wouldn't be displayed on the bands panel anyway
|
||||
fetchEventSource('/api/v2/spots/stream' + buildQueryString(), {
|
||||
fetchEventSource('/api/v3/spots/stream' + buildQueryString(), {
|
||||
signal: sseAbortController.signal,
|
||||
openWhenHidden: true,
|
||||
|
||||
@@ -80,7 +80,7 @@ function expireOldSpots() {
|
||||
// in the bands page's version of this, because nothing QRZ.com/HamQTH can provide will affect the display.
|
||||
function buildQueryString() {
|
||||
let str = "?";
|
||||
["dx_continent", "de_continent", "mode", "source", "band", "sig"].forEach(fn => {
|
||||
["dx_continent", "de_continent", "mode", "source", "band", "activity"].forEach(fn => {
|
||||
if (!allFilterOptionsSelected(fn)) {
|
||||
str = str + getQueryStringFor(fn) + "&";
|
||||
}
|
||||
@@ -281,7 +281,7 @@ function removeDuplicatesForBandPanel(spotList) {
|
||||
// Load server options. Once a successful callback is made from this, we then query spots and set up the timer to query
|
||||
// spots repeatedly.
|
||||
function loadOptions() {
|
||||
$.getJSON('/api/v2/options', function (jsonData) {
|
||||
$.getJSON('/api/v3/options', function (jsonData) {
|
||||
// Store options
|
||||
options = jsonData;
|
||||
|
||||
@@ -295,7 +295,7 @@ function loadOptions() {
|
||||
|
||||
// Populate the filters panel
|
||||
generateBandsMultiToggleFilterCard(options["bands"]);
|
||||
generateActivitiesMultiToggleFilterCard(options["sigs"]);
|
||||
generateActivitiesMultiToggleFilterCard(options["activities"]);
|
||||
generateMultiToggleFilterCard("#dx_continent_options", "dx_continent", options["continents"]);
|
||||
generateMultiToggleFilterCard("#de_continent_options", "de_continent", options["continents"]);
|
||||
generateModesMultiToggleFilterCard(options["modes"]);
|
||||
|
||||
+24
-9
@@ -33,6 +33,16 @@ function saveSettings() {
|
||||
// Load settings from local storage and set up the filter selectors. Suppressed if "use local storage" is false.
|
||||
function loadSettings() {
|
||||
if (useLocalStorage) {
|
||||
// Spothole v2 and earlier stored activity filter settings with "sig" in the element IDs, so migrate these to
|
||||
// their new names.
|
||||
Object.keys(localStorage).forEach(function (key) {
|
||||
if (key.startsWith("#filter-button-sig-")) {
|
||||
const newKey = key.replace("#filter-button-sig-", "#filter-button-activity-").replace("-NO_SIG:", "-NO_ACTIVITY:");
|
||||
localStorage.setItem(newKey, localStorage.getItem(key));
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
});
|
||||
|
||||
// Find all local storage entries and push their data to the corresponding UI element
|
||||
Object.keys(localStorage).forEach(function (key) {
|
||||
if (key.startsWith("#") && key.includes(":")) {
|
||||
@@ -67,7 +77,12 @@ function loadURLParams() {
|
||||
updateSelectFromParam(params, "limit", "alerts_to_fetch"); // Only on Alerts page
|
||||
updateSelectFromParam(params, "max_age", "max_spot_age"); // Only on Map & Bands pages
|
||||
updateFilterFromParam(params, "band", "band");
|
||||
updateFilterFromParam(params, "sig", "sig");
|
||||
updateFilterFromParam(params, "activity", "activity");
|
||||
// Spothole v2 and earlier called the "activity" param "sig", so support this for existing embeds
|
||||
if (params.get("activity") == null && params.get("sig") != null) {
|
||||
params.set("activity", params.get("sig").replace("NO_SIG", "NO_ACTIVITY"));
|
||||
updateFilterFromParam(params, "activity", "activity");
|
||||
}
|
||||
updateFilterFromParam(params, "source", "source");
|
||||
updateFilterFromParam(params, "mode", "mode");
|
||||
updateFilterFromParam(params, "dx_continent", "dx_continent");
|
||||
@@ -156,41 +171,41 @@ function buildActivityFilterGrid(activity_options) {
|
||||
const $grid = $('<div class="row row-cols-2 g-1 mb-1">');
|
||||
activity_options.forEach(o => {
|
||||
const domSafeName = o["name"].replace(/^[^A-Za-z0-9]+|[^\w]+/gi, "");
|
||||
$grid.append(`<div class="col"><div class="form-check"><input type="checkbox" class="form-check-input filter-button-sig storeable-checkbox" id="filter-button-sig-${domSafeName}" value="${o['name']}" autocomplete="off" onClick="filtersUpdated()" checked><label class="form-check-label" id="filter-button-label-sig-${domSafeName}" for="filter-button-sig-${domSafeName}" title="${o['description']}"><i class="fa-solid ${o['icon']}"></i> ${o['name']} ${(o["region_flag"] != null) ? o['region_flag'] : ''}</label></div></div>`);
|
||||
$grid.append(`<div class="col"><div class="form-check"><input type="checkbox" class="form-check-input filter-button-activity storeable-checkbox" id="filter-button-activity-${domSafeName}" value="${o['name']}" autocomplete="off" onClick="filtersUpdated()" checked><label class="form-check-label" id="filter-button-label-activity-${domSafeName}" for="filter-button-activity-${domSafeName}" title="${o['description']}"><i class="fa-solid ${o['icon']}"></i> ${o['name']} ${(o["region_flag"] != null) ? o['region_flag'] : ''}</label></div></div>`);
|
||||
});
|
||||
return $grid;
|
||||
}
|
||||
|
||||
// Generate activities filter card. This one is also a special case. includeGeneralDX controls whether the "General
|
||||
// DX" (NO_SIG) option is offered - this doesn't apply on the alerts page, where every alert has an activity.
|
||||
// DX" (NO_ACTIVITY) option is offered - this doesn't apply on the alerts page, where every alert has an activity.
|
||||
function generateActivitiesMultiToggleFilterCard(activity_options, includeGeneralDX = true) {
|
||||
const $list = $('<ul class="list-unstyled filter-section-list ps-0">');
|
||||
|
||||
const traditional = activity_options.filter(o => o["sig_type"] === "TRADITIONAL");
|
||||
const traditional = activity_options.filter(o => o["activity_type"] === "TRADITIONAL");
|
||||
appendActivityFilterSection($list, 'traditional', 'Traditional', true, includeGeneralDX || traditional.length > 0, $body => {
|
||||
if (includeGeneralDX) {
|
||||
$body.append(`<div class="w-100 mb-1"><div class="form-check"><input type="checkbox" class="form-check-input filter-button-sig storeable-checkbox" id="filter-button-sig-NO_SIG" value="NO_SIG" autocomplete="off" onClick="filtersUpdated()" checked><label class="form-check-label" id="filter-button-label-sig-NO_SIG" for="filter-button-sig-NO_SIG"><i class="fa-solid fa-tower-cell"></i> General DX</label></div></div>`);
|
||||
$body.append(`<div class="w-100 mb-1"><div class="form-check"><input type="checkbox" class="form-check-input filter-button-activity storeable-checkbox" id="filter-button-activity-NO_ACTIVITY" value="NO_ACTIVITY" autocomplete="off" onClick="filtersUpdated()" checked><label class="form-check-label" id="filter-button-label-activity-NO_ACTIVITY" for="filter-button-activity-NO_ACTIVITY"><i class="fa-solid fa-tower-cell"></i> General DX</label></div></div>`);
|
||||
}
|
||||
$body.append(buildActivityFilterGrid(traditional));
|
||||
});
|
||||
|
||||
const adventure = activity_options.filter(o => o["sig_type"] === "ADVENTURE");
|
||||
const adventure = activity_options.filter(o => o["activity_type"] === "ADVENTURE");
|
||||
appendActivityFilterSection($list, 'adventure', 'Adventure', true, adventure.length > 0, $body => {
|
||||
$body.append(buildActivityFilterGrid(adventure));
|
||||
});
|
||||
|
||||
const regional = activity_options.filter(o => o["sig_type"] === "REGIONAL");
|
||||
const regional = activity_options.filter(o => o["activity_type"] === "REGIONAL");
|
||||
appendActivityFilterSection($list, 'regional', 'Regional', false, regional.length > 0, $body => {
|
||||
$body.append(buildActivityFilterGrid(regional));
|
||||
});
|
||||
|
||||
const event = activity_options.filter(o => o["sig_type"] === "EVENT");
|
||||
const event = activity_options.filter(o => o["activity_type"] === "EVENT");
|
||||
appendActivityFilterSection($list, 'event', 'Event', false, event.length > 0, $body => {
|
||||
$body.append(buildActivityFilterGrid(event));
|
||||
});
|
||||
|
||||
$("#activity-options").append($list);
|
||||
$("#activity-options").append(`<div class="mt-1"><a href="#" onclick="toggleFilterButtons('sig', true); return false;">All</a> <a href="#" onclick="toggleFilterButtons('sig', false); return false;">None</a></div>`);
|
||||
$("#activity-options").append(`<div class="mt-1"><a href="#" onclick="toggleFilterButtons('activity', true); return false;">All</a> <a href="#" onclick="toggleFilterButtons('activity', false); return false;">None</a></div>`);
|
||||
}
|
||||
|
||||
// Method called when "All" or "None" is clicked
|
||||
|
||||
@@ -10,7 +10,7 @@ let ionosondeChart = null;
|
||||
|
||||
// Load solar conditions
|
||||
function loadSolarConditions() {
|
||||
$.getJSON('/api/v2/solar', function (jsonData) {
|
||||
$.getJSON('/api/v3/solar', function (jsonData) {
|
||||
|
||||
// HF
|
||||
|
||||
@@ -660,7 +660,7 @@ function dxStatsContientChanged() {
|
||||
|
||||
// Fetch DX stats from the API and render
|
||||
function loadDxStats() {
|
||||
$.getJSON('/api/v2/dxstats', function (jsonData) {
|
||||
$.getJSON('/api/v3/dxstats', function (jsonData) {
|
||||
dxStatsData = jsonData;
|
||||
renderDxStats();
|
||||
});
|
||||
|
||||
+13
-13
@@ -45,7 +45,7 @@ function loadSpots() {
|
||||
// 3) Subscribe to the SSE endpoint (with credentials if we have them) so that updates come with augmented
|
||||
// data if they can.
|
||||
$.ajax({
|
||||
url: '/api/v2/spots' + buildQueryString(), dataType: 'json', success: function (jsonData) {
|
||||
url: '/api/v3/spots' + buildQueryString(), dataType: 'json', success: function (jsonData) {
|
||||
// Store data
|
||||
spots = jsonData;
|
||||
// Update map
|
||||
@@ -58,7 +58,7 @@ function loadSpots() {
|
||||
// OK, we have credentials and have loaded once without them so the user has a basic map. Now reload
|
||||
// with the credentials and replace what's on the map, so we can improve the data.
|
||||
$.ajax({
|
||||
url: '/api/v2/spots' + buildQueryString(),
|
||||
url: '/api/v3/spots' + buildQueryString(),
|
||||
dataType: 'json',
|
||||
headers: getCredentialHeaders(),
|
||||
success: function (jsonData2) {
|
||||
@@ -85,7 +85,7 @@ function startSSEConnection() {
|
||||
sseAbortController = new AbortController();
|
||||
|
||||
// SSE is going to fetch only a few spots at a time, so now we include QRZ/HamQTH credentials because the delay won't be significant.
|
||||
fetchEventSource('/api/v2/spots/stream' + buildQueryString(), {
|
||||
fetchEventSource('/api/v3/spots/stream' + buildQueryString(), {
|
||||
headers: getCredentialHeaders(),
|
||||
signal: sseAbortController.signal,
|
||||
openWhenHidden: true,
|
||||
@@ -183,7 +183,7 @@ function removeSpotFromMap(key) {
|
||||
// Build a query string for the API, based on the filters that the user has selected.
|
||||
function buildQueryString() {
|
||||
let str = "?";
|
||||
["dx_continent", "de_continent", "mode", "source", "band", "sig"].forEach(fn => {
|
||||
["dx_continent", "de_continent", "mode", "source", "band", "activity"].forEach(fn => {
|
||||
if (!allFilterOptionsSelected(fn)) {
|
||||
str = str + getQueryStringFor(fn) + "&";
|
||||
}
|
||||
@@ -276,19 +276,19 @@ function getTooltipText(s) {
|
||||
|
||||
// Activity or fallback to source
|
||||
let activitySourceText = s["source"];
|
||||
if (s["sig"]) {
|
||||
activitySourceText = s["sig"];
|
||||
if (s["activity"]) {
|
||||
activitySourceText = s["activity"];
|
||||
}
|
||||
|
||||
// Format activity refs
|
||||
let activityRefs = "";
|
||||
if (s["sig_refs"] != null) {
|
||||
if (s["activity_refs"] != null) {
|
||||
const items = [];
|
||||
for (let i = 0; i < s["sig_refs"].length; i++) {
|
||||
if (s["sig_refs"][i]["url"] != null) {
|
||||
items[i] = `<a href='${s["sig_refs"][i]["url"]}' title='${s["sig_refs"][i]["name"]}' target='_new' class='activity-ref-link'>${s["sig_refs"][i]["id"]}</a>`
|
||||
for (let i = 0; i < s["activity_refs"].length; i++) {
|
||||
if (s["activity_refs"][i]["url"] != null) {
|
||||
items[i] = `<a href='${s["activity_refs"][i]["url"]}' title='${s["activity_refs"][i]["name"]}' target='_new' class='activity-ref-link'>${s["activity_refs"][i]["id"]}</a>`
|
||||
} else {
|
||||
items[i] = `${s["sig_refs"][i]["id"]}`
|
||||
items[i] = `${s["activity_refs"][i]["id"]}`
|
||||
}
|
||||
}
|
||||
activityRefs = items.join(", ");
|
||||
@@ -325,7 +325,7 @@ function getTooltipText(s) {
|
||||
// Load server options. Once a successful callback is made from this, we then query spots and set up the timer to query
|
||||
// spots repeatedly.
|
||||
function loadOptions() {
|
||||
$.getJSON('/api/v2/options', function (jsonData) {
|
||||
$.getJSON('/api/v3/options', function (jsonData) {
|
||||
// Store options
|
||||
options = jsonData;
|
||||
|
||||
@@ -339,7 +339,7 @@ function loadOptions() {
|
||||
|
||||
// Populate the filters panel
|
||||
generateBandsMultiToggleFilterCard(options["bands"]);
|
||||
generateActivitiesMultiToggleFilterCard(options["sigs"]);
|
||||
generateActivitiesMultiToggleFilterCard(options["activities"]);
|
||||
generateMultiToggleFilterCard("#dx_continent_options", "dx_continent", options["continents"]);
|
||||
generateMultiToggleFilterCard("#de_continent_options", "de_continent", options["continents"]);
|
||||
generateModesMultiToggleFilterCard(options["modes"]);
|
||||
|
||||
+12
-12
@@ -20,7 +20,7 @@ function loadSpots() {
|
||||
|
||||
// Make the new query. No credential headers on the first load to keep things quick
|
||||
$.ajax({
|
||||
url: '/api/v2/spots' + buildQueryString(), dataType: 'json', success: function (jsonData) {
|
||||
url: '/api/v3/spots' + buildQueryString(), dataType: 'json', success: function (jsonData) {
|
||||
// Store data
|
||||
spots = jsonData;
|
||||
// Update table
|
||||
@@ -43,7 +43,7 @@ function startSSEConnection() {
|
||||
sseAbortController = new AbortController();
|
||||
|
||||
// SSE is going to fetch only a few spots at a time, so now we include QRZ/HamQTH credentials because the delay won't be significant.
|
||||
fetchEventSource('/api/v2/spots/stream' + buildQueryString(), {
|
||||
fetchEventSource('/api/v3/spots/stream' + buildQueryString(), {
|
||||
headers: getCredentialHeaders(),
|
||||
signal: sseAbortController.signal,
|
||||
openWhenHidden: true,
|
||||
@@ -100,7 +100,7 @@ function startSSEConnection() {
|
||||
// Build a query string for the API, based on the filters that the user has selected.
|
||||
function buildQueryString() {
|
||||
let str = "?";
|
||||
["dx_continent", "de_continent", "mode", "source", "band", "sig"].forEach(fn => {
|
||||
["dx_continent", "de_continent", "mode", "source", "band", "activity"].forEach(fn => {
|
||||
if (!allFilterOptionsSelected(fn)) {
|
||||
str = str + getQueryStringFor(fn) + "&";
|
||||
}
|
||||
@@ -329,19 +329,19 @@ function createNewTableRowsForSpot(s, highlightNew) {
|
||||
|
||||
// Format activity
|
||||
let activityText = "General DX";
|
||||
if (s["sig"]) {
|
||||
activityText = s["sig"];
|
||||
if (s["activity"]) {
|
||||
activityText = s["activity"];
|
||||
}
|
||||
|
||||
// Format activity refs
|
||||
let activityRefs = "";
|
||||
if (s["sig_refs"] != null) {
|
||||
if (s["activity_refs"] != null) {
|
||||
const items = [];
|
||||
for (let i = 0; i < s["sig_refs"].length; i++) {
|
||||
if (s["sig_refs"][i]["url"] != null) {
|
||||
items[i] = `<span style="white-space: nowrap;"><a href='${encodeURI(s["sig_refs"][i]["url"])}' title='${escapeHtml(s["sig_refs"][i]["name"])}' target='_new' class='activity-ref-link'>${escapeHtml(s["sig_refs"][i]["id"])}</a></span>`
|
||||
for (let i = 0; i < s["activity_refs"].length; i++) {
|
||||
if (s["activity_refs"][i]["url"] != null) {
|
||||
items[i] = `<span style="white-space: nowrap;"><a href='${encodeURI(s["activity_refs"][i]["url"])}' title='${escapeHtml(s["activity_refs"][i]["name"])}' target='_new' class='activity-ref-link'>${escapeHtml(s["activity_refs"][i]["id"])}</a></span>`
|
||||
} else {
|
||||
items[i] = `<span style="white-space: nowrap;">${escapeHtml(s["sig_refs"][i]["id"])}</span>`
|
||||
items[i] = `<span style="white-space: nowrap;">${escapeHtml(s["activity_refs"][i]["id"])}</span>`
|
||||
}
|
||||
}
|
||||
activityRefs = items.join(", ");
|
||||
@@ -464,7 +464,7 @@ function createNewTableRowsForSpot(s, highlightNew) {
|
||||
// Load server options. Once a successful callback is made from this, we then query spots and set up the timer to query
|
||||
// spots repeatedly.
|
||||
function loadOptions() {
|
||||
$.getJSON('/api/v2/options', function (jsonData) {
|
||||
$.getJSON('/api/v3/options', function (jsonData) {
|
||||
// Store options
|
||||
options = jsonData;
|
||||
|
||||
@@ -478,7 +478,7 @@ function loadOptions() {
|
||||
|
||||
// Populate the filters panel
|
||||
generateBandsMultiToggleFilterCard(options["bands"]);
|
||||
generateActivitiesMultiToggleFilterCard(options["sigs"]);
|
||||
generateActivitiesMultiToggleFilterCard(options["activities"]);
|
||||
generateMultiToggleFilterCard("#dx_continent_options", "dx_continent", options["continents"]);
|
||||
generateMultiToggleFilterCard("#de_continent_options", "de_continent", options["continents"]);
|
||||
generateModesMultiToggleFilterCard(options["modes"]);
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
// Load server status
|
||||
function loadStatus() {
|
||||
$.getJSON('/api/v2/status', function (jsonData) {
|
||||
$.getJSON('/api/v3/status', function (jsonData) {
|
||||
$("#software_version").text(jsonData["software_version"]);
|
||||
$("#server_owner_callsign").text(jsonData["server_owner_callsign"]);
|
||||
$("#up-since").text(moment().subtract(jsonData["uptime"], 'seconds').fromNow());
|
||||
@@ -54,10 +54,10 @@ function loadStatus() {
|
||||
</div>`);
|
||||
});
|
||||
|
||||
jsonData["sig_ref_data_providers"].forEach(p => {
|
||||
$("#sig_ref_data_providers-status-container").append(`
|
||||
jsonData["activity_ref_data_providers"].forEach(p => {
|
||||
$("#activity_ref_data_providers-status-container").append(`
|
||||
<div class="row row-cols-1 row-cols-md-4 g-4 mb-4 mb-md-2">
|
||||
<div class="col"><strong>${p["sig_name"]}</strong></div>
|
||||
<div class="col"><strong>${p["activity_name"]}</strong></div>
|
||||
<div class="col">Status: ${p["status"]}</div>
|
||||
<div class="col">Last updated: ${(p["enabled"] && p["last_updated"] > 0) ? moment.unix(p["last_updated"]).utc().fromNow() : "N/A"}</div>
|
||||
<div class="col">References: ${p["enabled"] ? p["reference_count"] : "N/A"}</div>
|
||||
|
||||
Reference in New Issue
Block a user