diff --git a/config-example.yml b/config-example.yml index f3eaa05..d83874d 100644 --- a/config-example.yml +++ b/config-example.yml @@ -47,7 +47,7 @@ providers: enabled: false - class: "DXCluster" - name: "HRD Dx Cluster" + name: "Cluster" enabled: true host: "hrd.wa9pie.net" port: 8000 diff --git a/views/webpage_home.tpl b/views/webpage_home.tpl index 2d608dd..77533c4 100644 --- a/views/webpage_home.tpl +++ b/views/webpage_home.tpl @@ -1,6 +1,16 @@ % rebase('webpage_base.tpl')
-

Latest spots as of XXXX. Updating in XXX seconds...

+
+
+

Loading...

+
+
+

+ + +

+
+
\ No newline at end of file diff --git a/webassets/js/code.js b/webassets/js/code.js index 8d91a4c..b43350a 100644 --- a/webassets/js/code.js +++ b/webassets/js/code.js @@ -1,25 +1,85 @@ -$.getJSON('/api/spots', function(jsonData) { - let headers = Object.keys(jsonData[0]); - let table = $('').append(''); - ["Time", "DX", "Frequency", "Mode", "Comment", "Source", "DE"].forEach(header => table.find('thead tr').append(``)); +// How often to query the server? +const REFRESH_INTERVAL_SEC = 60; - jsonData.forEach(row => { - let $tr = $(''); - var time = moment(row["time"], moment.ISO_8601); - var time_formatted = time.format("HH:mm") - $tr.append(``); - $tr.append(``); - $tr.append(``); - $tr.append(``); - $tr.append(''); - $tr.append(``); - $tr.append(``); - table.find('tbody').append($tr); +// Storage for the options that the server gives us. This will define our filters. +var options = {}; +// Last time we updated the spots list on display. +var lastUpdateTime; + +// Load spots and populate the table. +function loadSpots() { + $.getJSON('/api/spots', function(jsonData) { + // Store last updated time + lastUpdateTime = moment.utc(); + + // Populate table with headers + let headers = Object.keys(jsonData[0]); + let table = $('
${header}
${time_formatted}${row["dx_flag"]} ${row["dx_call"]}${row["freq"]}${row["mode"]}' + escapeHtml(`${row["comment"]}`) + '${row["source"]}${row["de_flag"]} ${row["de_call"]}
').append(''); + ["UTC", "DX", "Frequency", "Mode", "Comment", "Source", "DE"].forEach(header => table.find('thead tr').append(``)); + + jsonData.forEach(row => { + // Create row + let $tr = $(''); + + // Show in red if QRT + if (row["qrt"] == true) { + $tr.addClass("table-danger"); + } + + // Format a UTC time for display + var time = moment.utc(row["time"], moment.ISO_8601); + var time_formatted = time.format("HH:mm") + + // Populate the table data + $tr.append(``); + $tr.append(``); + $tr.append(``); + $tr.append(``); + $tr.append(''); + $tr.append(``); + $tr.append(``); + table.find('tbody').append($tr); + }); + + // Update DOM + $('#table-container').html(table); + updateRefreshDisplay(); }); +} - $('#table-container').html(table); -}); +// Load server status +function loadStatus() { + $.getJSON('/api/status', function(jsonData) { + $('#status-container').html(jsonData); // todo implement + }); +} +// 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/options', function(jsonData) { + options = jsonData; + console.log(options); //todo remove + loadSpots(); + setInterval(loadSpots, REFRESH_INTERVAL_SEC * 1000) + }); +} + +// Update the refresh timing display +function updateRefreshDisplay() { + if (lastUpdateTime != null) { + let count = REFRESH_INTERVAL_SEC; + let secSinceUpdate = moment.duration(moment().diff(lastUpdateTime)).asSeconds(); + updatingString = "Updating..." + if (secSinceUpdate < REFRESH_INTERVAL_SEC) { + count = REFRESH_INTERVAL_SEC - secSinceUpdate; + updatingString = "Updating in " + count.toFixed(0) + " seconds..."; + } + $("#timing-container").text("Last updated at " + lastUpdateTime.format('hh:mm') + " UTC. " + updatingString); + } +} + +// Utility function to escape HTML characters from a string. function escapeHtml(str) { if (typeof str !== 'string') { return ''; @@ -41,6 +101,7 @@ function escapeHtml(str) { } -// Show/hide info block -function showInfo() { $("#info-container").show(); $("#table-container").hide(); } -function hideInfo() { $("#table-container").show(); $("#info-container").hide(); } \ No newline at end of file +// Startup. Call loadOptions(), this will then trigger loading spots and setting up timers. +loadOptions(); +// Update the refresh timing display every second +setInterval(updateRefreshDisplay, 1000); \ No newline at end of file
${header}
${time_formatted}${row["dx_flag"]} ${row["dx_call"]}${row["freq"]}${row["mode"]}' + escapeHtml(`${row["comment"]}`) + '${row["source"]}${row["de_flag"]} ${row["de_call"]}