up
This commit is contained in:
@@ -499,6 +499,8 @@ async function shutdownApp() {
|
||||
try {
|
||||
await spotCache.init();
|
||||
|
||||
soundManager.setEnabled(false);
|
||||
|
||||
// ✅ Charger les données du cache immédiatement
|
||||
const cachedSpots = await spotCache.getSpots();
|
||||
if (cachedSpots.length > 0) {
|
||||
@@ -627,6 +629,7 @@ async function shutdownApp() {
|
||||
{dxccProgress}
|
||||
{logs}
|
||||
on:toast={(e) => showToast(e.detail.message, e.detail.type)}
|
||||
on:clearLogs={() => logs = []}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
|
||||
export let stats;
|
||||
export let solarData;
|
||||
@@ -7,15 +7,20 @@
|
||||
export let cacheLoaded = false;
|
||||
export let soundManager;
|
||||
|
||||
let soundEnabled = true;
|
||||
let soundEnabled = false; // ✅ Initialisé à false
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function toggleSound() {
|
||||
soundEnabled = !soundEnabled;
|
||||
soundManager.setEnabled(soundEnabled);
|
||||
}
|
||||
// ✅ Synchroniser avec le soundManager au montage
|
||||
onMount(() => {
|
||||
soundEnabled = soundManager.isEnabled();
|
||||
});
|
||||
|
||||
function toggleSound() {
|
||||
soundEnabled = !soundEnabled;
|
||||
soundManager.setEnabled(soundEnabled);
|
||||
}
|
||||
|
||||
function getSFIColor(sfi) {
|
||||
const value = parseInt(sfi);
|
||||
if (isNaN(value)) return 'text-slate-500';
|
||||
@@ -58,89 +63,102 @@
|
||||
<h1 class="text-2xl font-bold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent">
|
||||
FlexDXCluster
|
||||
</h1>
|
||||
<div class="flex items-center gap-3 text-xs text-slate-400">
|
||||
<span>{stats.myCallsign || 'N/A'} • <span>{stats.totalContacts}</span> Contacts</span>
|
||||
<div class="flex items-center gap-2 text-xs text-slate-400">
|
||||
<!-- Callsign & Contacts -->
|
||||
<span class="font-semibold text-blue-400">{stats.myCallsign || 'N/A'}</span>
|
||||
<span class="text-slate-600">•</span>
|
||||
<span>{stats.totalContacts} QSOs</span>
|
||||
|
||||
<!-- Spots count -->
|
||||
<span class="text-slate-600">•</span>
|
||||
<span class="text-pink-400 font-semibold">{stats.totalSpots || 0}</span>
|
||||
<span>spots</span>
|
||||
|
||||
<span class="text-slate-600">|</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="font-semibold text-amber-400">SFI:</span>
|
||||
|
||||
<!-- Solar data compacts -->
|
||||
<span class="flex items-center gap-0.5">
|
||||
<span class="text-amber-400">SFI</span>
|
||||
<span class={getSFIColor(solarData.sfi)}>{solarData.sfi}</span>
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="font-semibold text-yellow-400">SSN:</span>
|
||||
|
||||
<span class="flex items-center gap-0.5">
|
||||
<span class="text-yellow-400">SSN</span>
|
||||
<span class={getSunspotsColor(solarData.sunspots)}>{solarData.sunspots}</span>
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="font-semibold text-red-400">A:</span>
|
||||
|
||||
<span class="flex items-center gap-0.5">
|
||||
<span class="text-red-400">A</span>
|
||||
<span class={getAIndexColor(solarData.aIndex)}>{solarData.aIndex}</span>
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="font-semibold text-purple-400">K:</span>
|
||||
|
||||
<span class="flex items-center gap-0.5">
|
||||
<span class="text-purple-400">K</span>
|
||||
<span class={getKIndexColor(solarData.kIndex)}>{solarData.kIndex}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex items-center gap-2">
|
||||
{#if wsStatus === 'connected'}
|
||||
<span class="inline-flex items-center gap-2 px-3 py-1.5 rounded-full text-xs font-semibold bg-green-500/20 text-green-400">
|
||||
<span class="w-2 h-2 bg-green-500 rounded-full animate-pulse"></span>
|
||||
WebSocket
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-semibold bg-green-500/20 text-green-400">
|
||||
<span class="w-1.5 h-1.5 bg-green-500 rounded-full animate-pulse"></span>
|
||||
WS
|
||||
</span>
|
||||
{:else if wsStatus === 'connecting'}
|
||||
<span class="inline-flex items-center gap-2 px-3 py-1.5 rounded-full text-xs font-semibold bg-orange-500/20 text-orange-400">
|
||||
<span class="w-2 h-2 bg-orange-500 rounded-full animate-pulse"></span>
|
||||
Connecting...
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-semibold bg-orange-500/20 text-orange-400">
|
||||
<span class="w-1.5 h-1.5 bg-orange-500 rounded-full animate-pulse"></span>
|
||||
WS
|
||||
</span>
|
||||
{:else}
|
||||
<span class="inline-flex items-center gap-2 px-3 py-1.5 rounded-full text-xs font-semibold bg-red-500/20 text-red-400">
|
||||
<span class="w-2 h-2 bg-red-500 rounded-full"></span>
|
||||
Disconnected
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-semibold bg-red-500/20 text-red-400">
|
||||
<span class="w-1.5 h-1.5 bg-red-500 rounded-full"></span>
|
||||
WS
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
<span class="inline-flex items-center gap-2 px-3 py-1.5 rounded-full text-xs font-semibold {stats.clusterStatus === 'connected' ? 'bg-green-500/20 text-green-400' : 'bg-red-500/20 text-red-400'}">
|
||||
<span class="w-2 h-2 {stats.clusterStatus === 'connected' ? 'bg-green-500 animate-pulse' : 'bg-red-500'} rounded-full"></span>
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-semibold {stats.clusterStatus === 'connected' ? 'bg-green-500/20 text-green-400' : 'bg-red-500/20 text-red-400'}">
|
||||
<span class="w-1.5 h-1.5 {stats.clusterStatus === 'connected' ? 'bg-green-500 animate-pulse' : 'bg-red-500'} rounded-full"></span>
|
||||
Cluster
|
||||
</span>
|
||||
|
||||
<span class="inline-flex items-center gap-2 px-3 py-1.5 rounded-full text-xs font-semibold {stats.flexStatus === 'connected' ? 'bg-green-500/20 text-green-400' : 'bg-red-500/20 text-red-400'}">
|
||||
<span class="w-2 h-2 {stats.flexStatus === 'connected' ? 'bg-green-500 animate-pulse' : 'bg-red-500'} rounded-full"></span>
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-semibold {stats.flexStatus === 'connected' ? 'bg-green-500/20 text-green-400' : 'bg-red-500/20 text-red-400'}">
|
||||
<span class="w-1.5 h-1.5 {stats.flexStatus === 'connected' ? 'bg-green-500 animate-pulse' : 'bg-red-500'} rounded-full"></span>
|
||||
Flex
|
||||
</span>
|
||||
|
||||
{#if cacheLoaded}
|
||||
<span class="inline-flex items-center gap-2 px-3 py-1.5 rounded-full text-xs font-semibold bg-purple-500/20 text-purple-400">
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-semibold bg-purple-500/20 text-purple-400" title="Data loaded from cache">
|
||||
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"></path>
|
||||
</svg>
|
||||
Cached
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
<button
|
||||
on:click={toggleSound}
|
||||
title="{soundEnabled ? 'Disable' : 'Enable'} sound alerts"
|
||||
class="px-3 py-1.5 rounded transition-colors {soundEnabled ? 'bg-blue-600 hover:bg-blue-700' : 'bg-slate-700 hover:bg-slate-600'} flex items-center gap-2">
|
||||
class="px-2.5 py-1 rounded transition-colors {soundEnabled ? 'bg-blue-600 hover:bg-blue-700' : 'bg-slate-700 hover:bg-slate-600'} flex items-center gap-1.5">
|
||||
{#if soundEnabled}
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
|
||||
<svg class="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M9.383 3.076A1 1 0 0110 4v12a1 1 0 01-1.707.707L4.586 13H2a1 1 0 01-1-1V8a1 1 0 011-1h2.586l3.707-3.707a1 1 0 011.09-.217zM14.657 2.929a1 1 0 011.414 0A9.972 9.972 0 0119 10a9.972 9.972 0 01-2.929 7.071 1 1 0 01-1.414-1.414A7.971 7.971 0 0017 10c0-2.21-.894-4.208-2.343-5.657a1 1 0 010-1.414zm-2.829 2.828a1 1 0 011.415 0A5.983 5.983 0 0115 10a5.984 5.984 0 01-1.757 4.243 1 1 0 01-1.415-1.415A3.984 3.984 0 0013 10a3.983 3.983 0 00-1.172-2.828 1 1 0 010-1.415z" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
{:else}
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
|
||||
<svg class="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M9.383 3.076A1 1 0 0110 4v12a1 1 0 01-1.707.707L4.586 13H2a1 1 0 01-1-1V8a1 1 0 011-1h2.586l3.707-3.707a1 1 0 011.09-.217zM12.293 7.293a1 1 0 011.414 0L15 8.586l1.293-1.293a1 1 0 111.414 1.414L16.414 10l1.293 1.293a1 1 0 01-1.414 1.414L15 11.414l-1.293 1.293a1 1 0 01-1.414-1.414L13.586 10l-1.293-1.293a1 1 0 010-1.414z" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
{/if}
|
||||
<span class="text-xs hidden sm:inline">{soundEnabled ? 'Sound ON' : 'Sound OFF'}</span>
|
||||
<span class="text-xs hidden lg:inline">{soundEnabled ? 'ON' : 'OFF'}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
on:click={() => dispatch('shutdown')}
|
||||
class="px-3 py-1.5 text-xs bg-red-600 hover:bg-red-700 rounded transition-colors flex items-center gap-1">
|
||||
class="px-2.5 py-1 text-xs bg-red-600 hover:bg-red-700 rounded transition-colors flex items-center gap-1">
|
||||
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
Shutdown
|
||||
<span class="hidden lg:inline">Shutdown</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,6 +1,10 @@
|
||||
<script>
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
export let logs = [];
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
let autoScroll = true;
|
||||
let container;
|
||||
let selectedLevels = {
|
||||
@@ -19,7 +23,7 @@
|
||||
// ✅ Auto-scroll UNIQUEMENT si activé
|
||||
$: if (autoScroll && container && filteredLogs.length > 0) {
|
||||
setTimeout(() => {
|
||||
if (autoScroll) { // ✅ Vérifier à nouveau car peut avoir changé
|
||||
if (autoScroll) {
|
||||
container.scrollTop = container.scrollHeight;
|
||||
}
|
||||
}, 10);
|
||||
@@ -47,8 +51,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ Dispatcher l'événement au parent
|
||||
function clearLogs() {
|
||||
logs = [];
|
||||
dispatch('clearLogs');
|
||||
}
|
||||
|
||||
function toggleLevel(level) {
|
||||
|
||||
@@ -12,15 +12,20 @@
|
||||
export let recentQSOs;
|
||||
export let logStats;
|
||||
export let dxccProgress;
|
||||
export let showOnlyActive = false; // ✅ Export pour persister l'état
|
||||
export let showOnlyActive = false;
|
||||
export let logs = [];
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
// ✅ Propagation des évènements vers le parent
|
||||
// ✅ Propagation des événements vers le parent
|
||||
function handleToast(event) {
|
||||
dispatch('toast', event.detail);
|
||||
}
|
||||
|
||||
// ✅ Propager clearLogs vers App.svelte
|
||||
function handleClearLogs() {
|
||||
dispatch('clearLogs');
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="bg-slate-800/50 backdrop-blur rounded-lg border border-slate-700/50 flex flex-col h-full" style="height: 100%; max-height: 100%;">
|
||||
@@ -83,7 +88,10 @@
|
||||
{dxccProgress}
|
||||
/>
|
||||
{:else if activeTab === 'logs'}
|
||||
<LogsTab {logs} />
|
||||
<LogsTab
|
||||
{logs}
|
||||
on:clearLogs={handleClearLogs}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
@@ -773,7 +773,6 @@ func (s *HTTPServer) getWatchlistSpotsWithStatus(w http.ResponseWriter, r *http.
|
||||
for _, pattern := range watchlistCallsigns {
|
||||
if spot.DX == pattern || strings.HasPrefix(spot.DX, pattern) {
|
||||
isInWatchlist = true
|
||||
Log.Debugf("✅ Watchlist match in API: %s matches pattern %s", spot.DX, pattern)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -783,8 +782,6 @@ func (s *HTTPServer) getWatchlistSpotsWithStatus(w http.ResponseWriter, r *http.
|
||||
}
|
||||
}
|
||||
|
||||
Log.Debugf("📊 Watchlist spots API returned %d spots", len(relevantSpots))
|
||||
|
||||
type BandModeKey struct {
|
||||
Band string
|
||||
Mode string
|
||||
|
||||
412
watchlist.json
412
watchlist.json
@@ -1,74 +1,34 @@
|
||||
[
|
||||
{
|
||||
"callsign": "PY0FB",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:24.3843986+02:00",
|
||||
"spotCount": 0,
|
||||
"callsign": "FW5K",
|
||||
"lastSeen": "2025-10-22T22:37:24.0393589+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:17:37.9061157+02:00",
|
||||
"spotCount": 140,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "D2A",
|
||||
"lastSeen": "2025-10-23T02:16:36.4176115+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-20T22:11:35.4767205+02:00",
|
||||
"spotCount": 180,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5H3MB",
|
||||
"lastSeen": "2025-10-20T22:27:00.0920217+02:00",
|
||||
"lastSeenStr": "20 hours ago",
|
||||
"lastSeen": "2025-10-22T21:21:06.1309604+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:18:42.8402097+02:00",
|
||||
"spotCount": 6,
|
||||
"spotCount": 20,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "C5R",
|
||||
"lastSeen": "2025-10-21T19:27:01.1572273+02:00",
|
||||
"lastSeen": "2025-10-23T02:17:36.6578871+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:18:04.5006892+02:00",
|
||||
"spotCount": 219,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "SU0ERA",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:45.8848244+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "XT2AW",
|
||||
"lastSeen": "2025-10-21T04:49:21.3973928+02:00",
|
||||
"lastSeenStr": "14 hours ago",
|
||||
"addedAt": "2025-10-18T17:17:27.3839089+02:00",
|
||||
"spotCount": 69,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "3B8M",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:32.6851135+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5K0UA",
|
||||
"lastSeen": "2025-10-21T19:26:43.7522993+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:17:53.7390559+02:00",
|
||||
"spotCount": 437,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "9L8MD",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:56.7896868+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "E6AD",
|
||||
"lastSeen": "2025-10-20T20:08:38.1641735+02:00",
|
||||
"lastSeenStr": "23 hours ago",
|
||||
"addedAt": "2025-10-18T17:17:40.8765179+02:00",
|
||||
"spotCount": 459,
|
||||
"spotCount": 307,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
@@ -80,26 +40,26 @@
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "4X6TT",
|
||||
"lastSeen": "2025-10-19T19:59:28.3446792+02:00",
|
||||
"lastSeenStr": "1 day ago",
|
||||
"addedAt": "2025-10-18T17:18:13.335878+02:00",
|
||||
"spotCount": 1,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "PJ6Y",
|
||||
"lastSeen": "2025-10-21T19:25:29.1180452+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:17:47.7237081+02:00",
|
||||
"spotCount": 664,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "YI1MB",
|
||||
"callsign": "9L8MD",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:18.825584+02:00",
|
||||
"addedAt": "2025-10-18T17:18:56.7896868+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "YJ0CA",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:33.3921665+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "SU0ERA",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:45.8848244+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
@@ -112,10 +72,26 @@
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "VP2M",
|
||||
"callsign": "DP0GVN",
|
||||
"lastSeen": "2025-10-23T02:03:51.5639848+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-20T07:00:51.7088369+02:00",
|
||||
"spotCount": 86,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5J0EA",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:57.308717+02:00",
|
||||
"addedAt": "2025-10-18T17:17:51.0758741+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5X2I",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:14.6598633+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
@@ -128,122 +104,10 @@
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5R8IC",
|
||||
"lastSeen": "2025-10-21T07:25:10.6322383+02:00",
|
||||
"lastSeenStr": "11 hours ago",
|
||||
"addedAt": "2025-10-19T18:18:58.8382325+02:00",
|
||||
"spotCount": 61,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "XV9",
|
||||
"callsign": "PY0FB",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:24.9155327+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5J0EA",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:51.0758741+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "VP8LP",
|
||||
"lastSeen": "2025-10-20T22:46:40.9079579+02:00",
|
||||
"lastSeenStr": "20 hours ago",
|
||||
"addedAt": "2025-10-18T17:18:49.0576187+02:00",
|
||||
"spotCount": 21,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "EL2BG",
|
||||
"lastSeen": "2025-10-21T05:41:57.870261+02:00",
|
||||
"lastSeenStr": "13 hours ago",
|
||||
"addedAt": "2025-10-18T17:18:10.2000017+02:00",
|
||||
"spotCount": 22,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "YJ0CA",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:33.3921665+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "TZ4AM",
|
||||
"lastSeen": "2025-10-21T01:27:17.0524499+02:00",
|
||||
"lastSeenStr": "17 hours ago",
|
||||
"addedAt": "2025-10-18T17:19:00.3154177+02:00",
|
||||
"spotCount": 46,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "H44MS",
|
||||
"lastSeen": "2025-10-20T19:29:23.5019952+02:00",
|
||||
"lastSeenStr": "23 hours ago",
|
||||
"addedAt": "2025-10-18T17:16:49.1572859+02:00",
|
||||
"spotCount": 1,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "TJ1GD",
|
||||
"lastSeen": "2025-10-21T07:18:19.1978587+02:00",
|
||||
"lastSeenStr": "12 hours ago",
|
||||
"addedAt": "2025-10-18T17:18:27.6004027+02:00",
|
||||
"spotCount": 41,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "C5LT",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:07.2442738+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "C8K",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:39.8627992+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "FW5K",
|
||||
"lastSeen": "2025-10-21T07:17:42.220076+02:00",
|
||||
"lastSeenStr": "12 hours ago",
|
||||
"addedAt": "2025-10-18T17:17:37.9061157+02:00",
|
||||
"spotCount": 111,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "Z66IPA",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:36.5251607+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "V85NPV",
|
||||
"lastSeen": "2025-10-19T15:42:31.3912491+02:00",
|
||||
"lastSeenStr": "2 days ago",
|
||||
"addedAt": "2025-10-18T17:18:15.8781583+02:00",
|
||||
"spotCount": 2,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5X2I",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:14.6598633+02:00",
|
||||
"addedAt": "2025-10-18T17:17:24.3843986+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
@@ -256,19 +120,163 @@
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "DP0GVN",
|
||||
"lastSeen": "2025-10-21T07:20:49.6910744+02:00",
|
||||
"lastSeenStr": "12 hours ago",
|
||||
"addedAt": "2025-10-20T07:00:51.7088369+02:00",
|
||||
"spotCount": 77,
|
||||
"callsign": "3B8M",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:32.6851135+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "D2A",
|
||||
"lastSeen": "2025-10-21T07:21:58.7128427+02:00",
|
||||
"lastSeenStr": "11 hours ago",
|
||||
"addedAt": "2025-10-20T22:11:35.4767205+02:00",
|
||||
"spotCount": 76,
|
||||
"callsign": "PJ6Y",
|
||||
"lastSeen": "2025-10-23T02:17:52.6776808+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:17:47.7237081+02:00",
|
||||
"spotCount": 864,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "YI1MB",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:18.825584+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "TJ1GD",
|
||||
"lastSeen": "2025-10-23T00:29:20.5443895+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:18:27.6004027+02:00",
|
||||
"spotCount": 62,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "EL2BG",
|
||||
"lastSeen": "2025-10-22T19:26:22.9261316+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:18:10.2000017+02:00",
|
||||
"spotCount": 24,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "6O3T",
|
||||
"lastSeen": "2025-10-23T02:14:10.5255505+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-22T19:31:13.1154881+02:00",
|
||||
"spotCount": 138,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "4X6TT",
|
||||
"lastSeen": "2025-10-21T19:54:01.9678474+02:00",
|
||||
"lastSeenStr": "23 hours ago",
|
||||
"addedAt": "2025-10-18T17:18:13.335878+02:00",
|
||||
"spotCount": 4,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "XT2AW",
|
||||
"lastSeen": "2025-10-23T00:20:38.5329853+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:17:27.3839089+02:00",
|
||||
"spotCount": 92,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "V85NPV",
|
||||
"lastSeen": "2025-10-19T15:42:31.3912491+02:00",
|
||||
"lastSeenStr": "3 days ago",
|
||||
"addedAt": "2025-10-18T17:18:15.8781583+02:00",
|
||||
"spotCount": 2,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "VP8LP",
|
||||
"lastSeen": "2025-10-20T22:46:40.9079579+02:00",
|
||||
"lastSeenStr": "1 day ago",
|
||||
"addedAt": "2025-10-18T17:18:49.0576187+02:00",
|
||||
"spotCount": 21,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "C5LT",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:07.2442738+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "Z66IPA",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:36.5251607+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "TZ4AM",
|
||||
"lastSeen": "2025-10-23T00:08:32.5194313+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:19:00.3154177+02:00",
|
||||
"spotCount": 54,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "E6AD",
|
||||
"lastSeen": "2025-10-20T20:08:38.1641735+02:00",
|
||||
"lastSeenStr": "1 day ago",
|
||||
"addedAt": "2025-10-18T17:17:40.8765179+02:00",
|
||||
"spotCount": 459,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "H44MS",
|
||||
"lastSeen": "2025-10-20T19:29:23.5019952+02:00",
|
||||
"lastSeenStr": "1 day ago",
|
||||
"addedAt": "2025-10-18T17:16:49.1572859+02:00",
|
||||
"spotCount": 1,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "C8K",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:39.8627992+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5K0UA",
|
||||
"lastSeen": "2025-10-23T02:07:24.3949315+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:17:53.7390559+02:00",
|
||||
"spotCount": 637,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "XV9",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:24.9155327+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "VP2M",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:57.308717+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5R8IC",
|
||||
"lastSeen": "2025-10-21T07:25:10.6322383+02:00",
|
||||
"lastSeenStr": "1 day ago",
|
||||
"addedAt": "2025-10-19T18:18:58.8382325+02:00",
|
||||
"spotCount": 61,
|
||||
"playSound": true
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user