up
This commit is contained in:
@@ -134,8 +134,6 @@ func (c *TCPClient) connect() error {
|
||||
c.LoggedIn = false
|
||||
c.reconnectAttempts = 0 // Reset sur connexion réussie
|
||||
|
||||
Log.Infof("Successfully connected to %s", addr)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
let newCallsign = '';
|
||||
let watchlistSpots = [];
|
||||
let refreshInterval;
|
||||
let editingNotes = {};
|
||||
let tempNotes = {};
|
||||
|
||||
$: matchingSpots = countWatchlistSpots(spots, watchlist);
|
||||
$: displayList = getDisplayList(watchlist, watchlistSpots, showOnlyActive);
|
||||
@@ -32,7 +30,6 @@
|
||||
}
|
||||
}, 10000);
|
||||
|
||||
// Listen for watchlist alerts
|
||||
window.addEventListener('watchlistAlert', handleWatchlistAlert);
|
||||
});
|
||||
|
||||
@@ -50,7 +47,6 @@
|
||||
soundManager.playWatchlistAlert('medium');
|
||||
}
|
||||
|
||||
// Show toast notification
|
||||
dispatch('toast', {
|
||||
message: `🎯 ${callsign} spotted!`,
|
||||
type: 'success'
|
||||
@@ -67,7 +63,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
// Sort alphabetically
|
||||
return [...list].sort((a, b) => a.callsign.localeCompare(b.callsign, 'en', { numeric: true }));
|
||||
}
|
||||
|
||||
@@ -173,34 +168,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function startEditNotes(callsign, currentNotes) {
|
||||
editingNotes[callsign] = true;
|
||||
tempNotes[callsign] = currentNotes || '';
|
||||
}
|
||||
|
||||
async function saveNotes(callsign) {
|
||||
try {
|
||||
const response = await fetch('/api/watchlist/update-notes', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ callsign, notes: tempNotes[callsign] || '' })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
if (data.success) {
|
||||
editingNotes[callsign] = false;
|
||||
dispatch('toast', { message: 'Notes saved', type: 'success' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error saving notes:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function cancelEditNotes(callsign) {
|
||||
editingNotes[callsign] = false;
|
||||
delete tempNotes[callsign];
|
||||
}
|
||||
|
||||
function handleKeyPress(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
@@ -294,7 +261,11 @@
|
||||
{/if}
|
||||
|
||||
{#if entry.lastSeenStr && entry.lastSeenStr !== 'Never'}
|
||||
<span class="text-xs text-slate-500">Last seen: {entry.lastSeenStr}</span>
|
||||
<span class="text-xs text-slate-500">• {entry.lastSeenStr}</span>
|
||||
{/if}
|
||||
|
||||
{#if entry.spotCount > 0}
|
||||
<span class="text-xs text-slate-600">• {entry.spotCount} total spot{entry.spotCount !== 1 ? 's' : ''}</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
@@ -316,40 +287,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notes section -->
|
||||
<div class="mt-2 mb-2">
|
||||
{#if editingNotes[entry.callsign]}
|
||||
<div class="flex gap-2">
|
||||
<input
|
||||
type="text"
|
||||
bind:value={tempNotes[entry.callsign]}
|
||||
placeholder="Add notes..."
|
||||
class="flex-1 px-2 py-1 bg-slate-700/50 border border-slate-600 rounded text-xs text-white focus:outline-none focus:border-blue-500"
|
||||
/>
|
||||
<button
|
||||
on:click={() => saveNotes(entry.callsign)}
|
||||
class="px-2 py-1 text-xs bg-green-600 hover:bg-green-700 rounded">
|
||||
Save
|
||||
</button>
|
||||
<button
|
||||
on:click={() => cancelEditNotes(entry.callsign)}
|
||||
class="px-2 py-1 text-xs bg-slate-600 hover:bg-slate-700 rounded">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
{:else}
|
||||
<button
|
||||
on:click={() => startEditNotes(entry.callsign, entry.notes)}
|
||||
class="w-full text-left px-2 py-1 bg-slate-800/30 rounded text-xs text-slate-400 hover:bg-slate-700/30 hover:text-slate-300 transition-colors">
|
||||
{#if entry.notes}
|
||||
📝 {entry.notes}
|
||||
{:else}
|
||||
+ Add notes...
|
||||
{/if}
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if count > 0}
|
||||
<div class="mt-2 space-y-1 max-h-48 overflow-y-auto" style="overflow-y: auto;">
|
||||
{#each matchingSpots.slice(0, 10) as spot}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class SoundManager {
|
||||
constructor() {
|
||||
this.enabled = true;
|
||||
this.enabled = false;
|
||||
this.audioContext = null;
|
||||
this.sounds = {};
|
||||
this.init();
|
||||
|
||||
@@ -167,7 +167,6 @@ func (s *HTTPServer) setupRoutes() {
|
||||
api.HandleFunc("/watchlist/spots", s.getWatchlistSpotsWithStatus).Methods("GET", "OPTIONS")
|
||||
api.HandleFunc("/watchlist/add", s.addToWatchlist).Methods("POST", "OPTIONS")
|
||||
api.HandleFunc("/watchlist/remove", s.removeFromWatchlist).Methods("DELETE", "OPTIONS")
|
||||
api.HandleFunc("/watchlist/update-notes", s.updateWatchlistNotes).Methods("POST", "OPTIONS")
|
||||
api.HandleFunc("/watchlist/update-sound", s.updateWatchlistSound).Methods("POST", "OPTIONS")
|
||||
api.HandleFunc("/stats/spots", s.getSpotProcessingStats).Methods("GET", "OPTIONS")
|
||||
api.HandleFunc("/logs", s.getLogs).Methods("GET", "OPTIONS")
|
||||
@@ -715,11 +714,6 @@ func (s *HTTPServer) updateWatchlistNotes(w http.ResponseWriter, r *http.Request
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.Watchlist.UpdateNotes(req.Callsign, req.Notes); err != nil {
|
||||
s.sendJSON(w, APIResponse{Success: false, Error: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
s.Log.Debugf("Updated notes for %s", req.Callsign)
|
||||
|
||||
// Broadcast updated watchlist to all clients
|
||||
|
||||
39
watchlist.go
39
watchlist.go
@@ -10,8 +10,8 @@ import (
|
||||
)
|
||||
|
||||
type WatchlistEntry struct {
|
||||
Callsign string `json:"callsign"`
|
||||
Notes string `json:"notes"`
|
||||
Callsign string `json:"callsign"`
|
||||
// ✅ NOTES SUPPRIMÉES
|
||||
LastSeen time.Time `json:"lastSeen"`
|
||||
LastSeenStr string `json:"lastSeenStr"`
|
||||
AddedAt time.Time `json:"addedAt"`
|
||||
@@ -67,7 +67,6 @@ func (w *Watchlist) load() {
|
||||
Log.Infof("Loaded %d entries from watchlist", len(w.entries))
|
||||
}
|
||||
|
||||
// saveUnsafe fait la sauvegarde SANS prendre de lock (à utiliser quand on a déjà un lock)
|
||||
func (w *Watchlist) saveUnsafe() error {
|
||||
entries := make([]WatchlistEntry, 0, len(w.entries))
|
||||
for _, entry := range w.entries {
|
||||
@@ -89,7 +88,6 @@ func (w *Watchlist) saveUnsafe() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// save est la version publique avec lock (pour les appels périodiques depuis httpserver)
|
||||
func (w *Watchlist) save() error {
|
||||
w.mutex.RLock()
|
||||
defer w.mutex.RUnlock()
|
||||
@@ -115,8 +113,8 @@ func (w *Watchlist) Add(callsign string) error {
|
||||
}
|
||||
|
||||
w.entries[callsign] = &WatchlistEntry{
|
||||
Callsign: callsign,
|
||||
Notes: "",
|
||||
Callsign: callsign,
|
||||
// ✅ PAS DE NOTES
|
||||
AddedAt: time.Now(),
|
||||
LastSeen: time.Time{},
|
||||
LastSeenStr: "Never",
|
||||
@@ -157,28 +155,8 @@ func (w *Watchlist) Remove(callsign string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *Watchlist) UpdateNotes(callsign, notes string) error {
|
||||
w.mutex.Lock()
|
||||
defer w.mutex.Unlock()
|
||||
|
||||
callsign = strings.ToUpper(strings.TrimSpace(callsign))
|
||||
|
||||
entry, exists := w.entries[callsign]
|
||||
if !exists {
|
||||
Log.Warnf("Attempted to update notes for non-existent callsign: %s", callsign)
|
||||
return fmt.Errorf("callsign not in watchlist")
|
||||
}
|
||||
|
||||
entry.Notes = notes
|
||||
Log.Debugf("Updated notes for %s", callsign)
|
||||
|
||||
if err := w.saveUnsafe(); err != nil {
|
||||
Log.Errorf("Failed to save watchlist after updating notes for %s: %v", callsign, err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
// ✅ FONCTION SUPPRIMÉE
|
||||
// func (w *Watchlist) UpdateNotes(callsign, notes string) error { ... }
|
||||
|
||||
func (w *Watchlist) UpdateSound(callsign string, playSound bool) error {
|
||||
w.mutex.Lock()
|
||||
@@ -219,9 +197,6 @@ func (w *Watchlist) MarkSeen(callsign string) {
|
||||
entry.SpotCount++
|
||||
|
||||
Log.Debugf("Marked %s as seen (count: %d)", callsign, entry.SpotCount)
|
||||
|
||||
// Ne PAS sauvegarder à chaque spot - trop lent !
|
||||
// La sauvegarde sera faite périodiquement par le ticker
|
||||
}
|
||||
|
||||
func (w *Watchlist) Matches(callsign string) bool {
|
||||
@@ -247,7 +222,6 @@ func (w *Watchlist) GetEntry(callsign string) *WatchlistEntry {
|
||||
|
||||
for pattern, entry := range w.entries {
|
||||
if callsign == pattern || strings.HasPrefix(callsign, pattern) {
|
||||
// Retourner une copie pour éviter les race conditions
|
||||
entryCopy := *entry
|
||||
return &entryCopy
|
||||
}
|
||||
@@ -262,7 +236,6 @@ func (w *Watchlist) GetAll() []WatchlistEntry {
|
||||
|
||||
entries := make([]WatchlistEntry, 0, len(w.entries))
|
||||
for _, entry := range w.entries {
|
||||
// Mettre à jour LastSeenStr avant de retourner
|
||||
entryCopy := *entry
|
||||
if !entryCopy.LastSeen.IsZero() {
|
||||
entryCopy.LastSeenStr = formatLastSeen(entryCopy.LastSeen)
|
||||
|
||||
420
watchlist.json
420
watchlist.json
@@ -1,16 +1,166 @@
|
||||
[
|
||||
{
|
||||
"callsign": "9L9L",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:53.3401773+02:00",
|
||||
"spotCount": 0,
|
||||
"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": "PJ6Y",
|
||||
"lastSeen": "2025-10-19T18:26:10.9139291+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:17:47.7237081+02:00",
|
||||
"spotCount": 319,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5X1XA",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:01.2081871+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "XT2AW",
|
||||
"lastSeen": "2025-10-19T17:43:24.3788757+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:17:27.3839089+02:00",
|
||||
"spotCount": 22,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "PY0FB",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:24.3843986+02:00",
|
||||
"spotCount": 0,
|
||||
"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": "EL2BG",
|
||||
"lastSeen": "2025-10-19T18:20:24.2625789+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:18:10.2000017+02:00",
|
||||
"spotCount": 19,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5R8IC",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-19T18:18:58.8382325+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "TJ1GD",
|
||||
"lastSeen": "2025-10-19T17:30:20.2860148+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:18:27.6004027+02:00",
|
||||
"spotCount": 11,
|
||||
"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": "C8K",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:39.8627992+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "E51MWA",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:43.6895454+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "4X6TT",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:13.335878+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "VP8LP",
|
||||
"lastSeen": "2025-10-19T18:19:58.5335162+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:18:49.0576187+02:00",
|
||||
"spotCount": 17,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5X2I",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:14.6598633+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
|
||||
},
|
||||
{
|
||||
"callsign": "C5R",
|
||||
"lastSeen": "2025-10-19T18:19:31.7179248+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:18:04.5006892+02:00",
|
||||
"spotCount": 99,
|
||||
"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": "FW5K",
|
||||
"lastSeen": "2025-10-19T17:35:31.6022206+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:17:37.9061157+02:00",
|
||||
"spotCount": 75,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "XV9",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:24.9155327+02:00",
|
||||
@@ -19,7 +169,6 @@
|
||||
},
|
||||
{
|
||||
"callsign": "3B8M",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:32.6851135+02:00",
|
||||
@@ -27,264 +176,83 @@
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "PY0FB",
|
||||
"notes": "",
|
||||
"callsign": "YJ0CA",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:24.3843986+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5X1XA",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:01.2081871+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "4X6TT",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:13.335878+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5J0EA",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:51.0758741+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "Z66IPA",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:36.5251607+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "E51MWA",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:43.6895454+02:00",
|
||||
"addedAt": "2025-10-18T17:17:33.3921665+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "C5LT",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:07.2442738+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "TZ4AM",
|
||||
"lastSeen": "2025-10-19T13:54:22.6033432+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:19:00.3154177+02:00",
|
||||
"spotCount": 27,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "H44MS",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:16:49.1572859+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "C21TS",
|
||||
"notes": "",
|
||||
"lastSeen": "2025-10-18T18:50:28.7708075+02:00",
|
||||
"lastSeenStr": "15 hours ago",
|
||||
"addedAt": "2025-10-18T17:18:21.7895474+02:00",
|
||||
"spotCount": 9,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "XT2AW",
|
||||
"notes": "",
|
||||
"lastSeen": "2025-10-19T10:00:12.7622002+02:00",
|
||||
"lastSeenStr": "40 minutes ago",
|
||||
"addedAt": "2025-10-18T17:17:27.3839089+02:00",
|
||||
"spotCount": 3,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5H3MB",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:42.8402097+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "V85NPV",
|
||||
"lastSeen": "2025-10-19T15:42:31.3912491+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:18:15.8781583+02:00",
|
||||
"spotCount": 2,
|
||||
"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": "5K0UA",
|
||||
"lastSeen": "2025-10-19T18:24:42.7186896+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:17:53.7390559+02:00",
|
||||
"spotCount": 116,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "E6AD",
|
||||
"lastSeen": "2025-10-19T18:25:32.690685+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:17:40.8765179+02:00",
|
||||
"spotCount": 385,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "ZL7IO",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:30.7153757+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "PJ6Y",
|
||||
"notes": "",
|
||||
"lastSeen": "2025-10-19T10:52:44.506525+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:17:47.7237081+02:00",
|
||||
"spotCount": 226,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "EL2BG",
|
||||
"notes": "",
|
||||
"lastSeen": "2025-10-19T10:03:29.0397937+02:00",
|
||||
"lastSeenStr": "36 minutes ago",
|
||||
"addedAt": "2025-10-18T17:18:10.2000017+02:00",
|
||||
"spotCount": 8,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "5K0UA",
|
||||
"notes": "",
|
||||
"lastSeen": "2025-10-19T10:39:23.7846359+02:00",
|
||||
"lastSeenStr": "1 minute ago",
|
||||
"addedAt": "2025-10-18T17:17:53.7390559+02:00",
|
||||
"spotCount": 53,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "V85NPV",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:15.8781583+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "C8K",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:39.8627992+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "TJ1GD",
|
||||
"notes": "",
|
||||
"lastSeen": "2025-10-18T18:45:59.6232796+02:00",
|
||||
"lastSeenStr": "15 hours ago",
|
||||
"addedAt": "2025-10-18T17:18:27.6004027+02:00",
|
||||
"spotCount": 10,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "9L8MD",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:56.7896868+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "YI1MB",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:18.825584+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "VP2M",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:57.308717+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "C5R",
|
||||
"notes": "",
|
||||
"lastSeen": "2025-10-19T10:42:39.5198229+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:18:04.5006892+02:00",
|
||||
"spotCount": 63,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "FW5K",
|
||||
"notes": "",
|
||||
"lastSeen": "2025-10-19T10:39:01.1319995+02:00",
|
||||
"lastSeenStr": "1 minute ago",
|
||||
"addedAt": "2025-10-18T17:17:37.9061157+02:00",
|
||||
"spotCount": 54,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "9L9L",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:53.3401773+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "VP8LP",
|
||||
"notes": "",
|
||||
"lastSeen": "2025-10-19T02:44:48.7228962+02:00",
|
||||
"lastSeenStr": "7 hours ago",
|
||||
"addedAt": "2025-10-18T17:18:49.0576187+02:00",
|
||||
"spotCount": 4,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "TZ4AM",
|
||||
"notes": "",
|
||||
"lastSeen": "2025-10-18T23:16:45.8032011+02:00",
|
||||
"lastSeenStr": "11 hours ago",
|
||||
"addedAt": "2025-10-18T17:19:00.3154177+02:00",
|
||||
"spotCount": 22,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "SU0ERA",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:18:45.8848244+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "E6AD",
|
||||
"notes": "",
|
||||
"lastSeen": "2025-10-19T10:52:30.5135569+02:00",
|
||||
"lastSeenStr": "Just now",
|
||||
"addedAt": "2025-10-18T17:17:40.8765179+02:00",
|
||||
"spotCount": 222,
|
||||
"playSound": true
|
||||
},
|
||||
{
|
||||
"callsign": "YJ0CA",
|
||||
"notes": "",
|
||||
"lastSeen": "0001-01-01T00:00:00Z",
|
||||
"lastSeenStr": "Never",
|
||||
"addedAt": "2025-10-18T17:17:33.3921665+02:00",
|
||||
"spotCount": 0,
|
||||
"playSound": true
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user