diff --git a/htdocs/lib/MessagePanel.js b/htdocs/lib/MessagePanel.js
index 1e7a75b..80afc25 100644
--- a/htdocs/lib/MessagePanel.js
+++ b/htdocs/lib/MessagePanel.js
@@ -157,13 +157,17 @@ PacketMessagePanel.prototype.pushMessage = function(msg) {
if (msg.type && msg.type === 'thirdparty' && msg.data) {
msg = msg.data;
}
+
var source = msg.source;
- if (msg.type) {
- if (msg.type === 'item') {
- source = msg.item;
- }
- if (msg.type === 'object') {
- source = msg.object;
+ var callsign;
+ if ('object' in source) {
+ callsign = source.object;
+ } else if ('item' in source) {
+ callsign = source.item;
+ } else {
+ callsign = source.callsign;
+ if ('ssid' in source) {
+ callsign += '-' + source.ssid;
}
}
@@ -202,7 +206,7 @@ PacketMessagePanel.prototype.pushMessage = function(msg) {
'style="' + stylesToString(styles) + '"'
].join(' ');
if (msg.lat && msg.lon) {
- link = '' + overlay + '';
+ link = '' + overlay + '';
} else {
link = '
' + overlay + '
'
}
@@ -210,7 +214,7 @@ PacketMessagePanel.prototype.pushMessage = function(msg) {
$b.append($(
'' +
'' + timestamp + ' | ' +
- '' + source + ' | ' +
+ '' + callsign + ' | ' +
'' + link + ' | ' +
'' + (msg.comment || msg.message || '') + ' | ' +
'
'
diff --git a/htdocs/map.js b/htdocs/map.js
index 3a0c0a8..089cc5b 100644
--- a/htdocs/map.js
+++ b/htdocs/map.js
@@ -1,17 +1,12 @@
$(function(){
- var query = window.location.search.replace(/^\?/, '').split('&').map(function(v){
- var s = v.split('=');
- var r = {};
- r[s[0]] = s.slice(1).join('=');
- return r;
- }).reduce(function(a, b){
- return a.assign(b);
- });
+ var query = new URLSearchParams(window.location.search);
var expectedCallsign;
- if (query.callsign) expectedCallsign = decodeURIComponent(query.callsign);
+ if (query.has('callsign')) {
+ expectedCallsign = Object.fromEntries(query.entries());
+ }
var expectedLocator;
- if (query.locator) expectedLocator = query.locator;
+ if (query.has('locator')) expectedLocator = query.get('locator');
var protocol = window.location.protocol.match(/https/) ? 'wss' : 'ws';
@@ -102,6 +97,11 @@ $(function(){
return '' + key + '';
});
$(".openwebrx-map-legend .content").html('');
+ };
+
+ var shallowEquals = function(obj1, obj2) {
+ // basic shallow object comparison
+ return Object.entries(obj1).sort().toString() === Object.entries(obj2).sort().toString();
}
var processUpdates = function(updates) {
@@ -110,6 +110,7 @@ $(function(){
return;
}
updates.forEach(function(update){
+ var key = sourceToKey(update.source);
switch (update.location.type) {
case 'latlon':
@@ -123,33 +124,33 @@ $(function(){
aprsOptions.course = update.location.course;
aprsOptions.speed = update.location.speed;
}
- if (markers[update.callsign]) {
- marker = markers[update.callsign];
+ if (markers[key]) {
+ marker = markers[key];
} else {
marker = new markerClass();
marker.addListener('click', function(){
- showMarkerInfoWindow(update.callsign, pos);
+ showMarkerInfoWindow(update.source, pos);
});
- markers[update.callsign] = marker;
+ markers[key] = marker;
}
marker.setOptions($.extend({
position: pos,
map: map,
- title: update.callsign
+ title: sourceToString(update.source)
}, aprsOptions, getMarkerOpacityOptions(update.lastseen) ));
marker.lastseen = update.lastseen;
marker.mode = update.mode;
marker.band = update.band;
marker.comment = update.location.comment;
- if (expectedCallsign && expectedCallsign == update.callsign) {
+ if (expectedCallsign && shallowEquals(expectedCallsign, update.source)) {
map.panTo(pos);
- showMarkerInfoWindow(update.callsign, pos);
+ showMarkerInfoWindow(update.source, pos);
expectedCallsign = false;
}
- if (infowindow && infowindow.callsign && infowindow.callsign == update.callsign) {
- showMarkerInfoWindow(infowindow.callsign, pos);
+ if (infowindow && infowindow.source && shallowEquals(infowindow.source, update.source)) {
+ showMarkerInfoWindow(infowindow.source, pos);
}
break;
case 'locator':
@@ -160,15 +161,16 @@ $(function(){
var rectangle;
// the accessor is designed to work on the rectangle... but it should work on the update object, too
var color = getColor(colorAccessor(update));
- if (rectangles[update.callsign]) {
- rectangle = rectangles[update.callsign];
+ if (rectangles[key]) {
+ rectangle = rectangles[key];
} else {
rectangle = new google.maps.Rectangle();
rectangle.addListener('click', function(){
showLocatorInfoWindow(this.locator, this.center);
});
- rectangles[update.callsign] = rectangle;
+ rectangles[key] = rectangle;
}
+ rectangle.source = update.source;
rectangle.lastseen = update.lastseen;
rectangle.locator = update.location.locator;
rectangle.mode = update.mode;
@@ -188,13 +190,13 @@ $(function(){
}
}, getRectangleOpacityOptions(update.lastseen) ));
- if (expectedLocator && expectedLocator == update.location.locator) {
+ if (expectedLocator && expectedLocator === update.location.locator) {
map.panTo(center);
showLocatorInfoWindow(expectedLocator, center);
expectedLocator = false;
}
- if (infowindow && infowindow.locator && infowindow.locator == update.location.locator) {
+ if (infowindow && infowindow.locator && infowindow.locator === update.location.locator) {
showLocatorInfoWindow(infowindow.locator, center);
}
break;
@@ -203,7 +205,7 @@ $(function(){
};
var clearMap = function(){
- var reset = function(callsign, item) { item.setMap(); };
+ var reset = function(_, item) { item.setMap(); };
$.each(markers, reset);
$.each(rectangles, reset);
receiverMarker.setMap();
@@ -336,21 +338,35 @@ $(function(){
infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(infowindow, 'closeclick', function() {
delete infowindow.locator;
- delete infowindow.callsign;
+ delete infowindow.source;
});
}
delete infowindow.locator;
- delete infowindow.callsign;
+ delete infowindow.source;
return infowindow;
};
- var linkifyCallsign = function(callsign) {
- if ((callsign_url == null) || (callsign_url == ''))
- return callsign;
+ var sourceToKey = function(source) {
+ // special treatment for special entities
+ // not just for display but also in key treatment in order not to overlap with other locations sent by the same callsign
+ if ('item' in source) return source['item'];
+ if ('object' in source) return source['object'];
+ var key = source.callsign;
+ if ('ssid' in source) key += '-' + source.ssid;
+ return key;
+ };
+
+ // we can reuse the same logic for displaying and indexing
+ var sourceToString = sourceToKey;
+
+ var linkifySource = function(source) {
+ var callsignString = sourceToString(source);
+ if (callsign_url == null || callsign_url === '')
+ return callsignString;
else
return '' + callsign + '';
+ callsign_url.replaceAll('{}', source.callsign) +
+ '">' + callsignString + '';
};
var distanceKm = function(p1, p2) {
@@ -374,10 +390,8 @@ $(function(){
var showLocatorInfoWindow = function(locator, pos) {
var infowindow = getInfoWindow();
infowindow.locator = locator;
- var inLocator = $.map(rectangles, function(r, callsign) {
- return {callsign: callsign, locator: r.locator, lastseen: r.lastseen, mode: r.mode, band: r.band}
- }).filter(rectangleFilter).filter(function(d) {
- return d.locator == locator;
+ var inLocator = Object.values(rectangles).filter(rectangleFilter).filter(function(d) {
+ return d.locator === locator;
}).sort(function(a, b){
return b.lastseen - a.lastseen;
});
@@ -389,7 +403,7 @@ $(function(){
'