diff --git a/src/c3nav/mapdata/quests/positioning.py b/src/c3nav/mapdata/quests/positioning.py index 92bb0956..f511fcf0 100644 --- a/src/c3nav/mapdata/quests/positioning.py +++ b/src/c3nav/mapdata/quests/positioning.py @@ -109,6 +109,7 @@ class RangingBeaconBSSIDsQuest(Quest): class BeaconMeasurementQuestForm(ChangeSetModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self.fields["beacon_measurement_quest"] = CharField(disabled=True, initial='', widget=HiddenInput(), required=False) self.fields["data"].widget = HiddenInput() def clean_data(self): diff --git a/src/c3nav/site/static/site/css/c3nav.scss b/src/c3nav/site/static/site/css/c3nav.scss index 050f79f6..8733d72d 100644 --- a/src/c3nav/site/static/site/css/c3nav.scss +++ b/src/c3nav/site/static/site/css/c3nav.scss @@ -2000,12 +2000,18 @@ blink { } } +.beacon-quest-scanner { + margin-bottom: 1rem; +} -.ap-name-bssid-result { +.ap-name-bssid-result, .beacon-quest-scanner > table { + display: block; + max-height: 30vh; + overflow: scroll; border-radius: 4px; border: 1px solid gray; padding: 4px 0; - box-shadow: inset 0px 0px 1px gray; + box-shadow: inset 0 0 1px gray; thead { border-bottom: 1px solid gray; diff --git a/src/c3nav/site/static/site/js/c3nav.js b/src/c3nav/site/static/site/js/c3nav.js index c150f50b..0a59c6bd 100644 --- a/src/c3nav/site/static/site/js/c3nav.js +++ b/src/c3nav/site/static/site/js/c3nav.js @@ -1471,17 +1471,112 @@ c3nav = { }, _set_modal_content: function (content, no_close) { const $modal = $('#modal'); + const $content = $modal.find('#modal-content'); $modal.toggleClass('loading', !content) - .find('#modal-content') - .html((!no_close) ? '' : '') + $content.html((!no_close) ? '' : '') .append(content || '
'); - if ($modal.find('[name=look_for_ap]').length) { + if ($content.find('[name=look_for_ap]').length) { + $content.find('button[type=submit]').hide(); if (!window.mobileclient) { - alert('need app!') + $content.find('p, form').remove(); + $content.append('This quest is only available in the android app.
'); // TODO translate + } else { + c3nav._ap_name_scan_result_update(); + } + } else if ($content.find('[name=beacon_measurement_quest]').length) { + $content.find('button[type=submit]').hide(); + if (!window.mobileclient) { + $content.find('p, form').remove(); + $content.append('This quest is only available in the android app.
'); // TODO translate + } else { + const $scanner = $(''); + const $button = $('') + .click(() => { + $button.remove(); + $scanner.append('Scanning… Please do not close this popup and do not move.
'); + c3nav._quest_wifi_scans = []; + c3nav._beacon_quest_scanning = true; + }) + $scanner.append($button); + $content.find('form').prev().after($scanner) } - $modal.find('button').hide(); } }, + _quest_wifi_scans: [], + _quest_ibeacon_scans: [], + _wifi_measurement_scan_update: function () { + + const wifi_display_results = []; + const bluetooth_display_results = []; + for (const scan of c3nav._quest_wifi_scans) { + for (const peer of scan) { + let found = false; + for (const existing_peer of wifi_display_results) { + if (peer.bssid === existing_peer.bssid && peer.ssid === existing_peer.ssid) { + existing_peer.rssi = peer.rssi; + found = true; + break; + } + } + if (!found) { + wifi_display_results.push(peer); + } + } + } + for (const scan of c3nav._quest_ibeacon_scans) { + for (const peer of scan) { + let found = false; + for (const existing_peer of bluetooth_display_results) { + if (peer.uuid === existing_peer.uuid && peer.major === existing_peer.major && peer.minor === existing_peer.minor) { + existing_peer.distance = peer.distance; + found = true; + break; + } + } + if (!found) { + bluetooth_display_results.push(peer); + } + } + } + + const $scanner = $('#modal .beacon-quest-scanner'); + + const $wifi_table = $(`${c3nav._quest_wifi_scans.length} wifi scans | ||
BSSID | SSID | RSSI |
---|
${c3nav._quest_ibeacon_scans.length} wifi scans | ||
ID | Distance |
---|
Scanning… Please do not close this popup and do not move.
'); + } else { + if (c3nav._quest_wifi_scans.length > 2) { + $('#modal input[name=data]').val(JSON.stringify({ + wifi: c3nav._quest_wifi_scans, + ibeacon: c3nav._quest_ibeacon_scans, + })) + $('#modal button[type=submit]').show(); + } + } + + if (wifi_display_results.length > 0) { + $scanner.append($wifi_table); + } + if (bluetooth_display_results.length > 0) { + $scanner.append($bluetooth_table); + } + + }, + _ap_name_scan_result_update: function () { const $modal = $('#modal'); const $match_ap = $modal.find('[name=look_for_ap]'); @@ -2178,6 +2273,7 @@ c3nav = { _last_ibeacon_peers: [], _no_scan_count: 0, _ap_name_mappings: {}, + _beacon_quest_scan_results: {}, _enable_scan_debugging: false, _scan_debugging_results: [], _wifi_scan_results: function (peers) { @@ -2221,12 +2317,23 @@ c3nav = { c3nav._ap_name_scan_result_update(); + if (c3nav._beacon_quest_scanning) { + c3nav._quest_wifi_scans.push(peers); + c3nav._wifi_measurement_scan_update(); + } + c3nav._last_wifi_peers = peers; c3nav._after_scan_results(); }, _ibeacon_scan_results: function (peers) { peers = JSON.parse(peers); c3nav._last_ibeacon_peers = peers; + + if (c3nav._beacon_quest_scanning) { + c3nav._quest_ibeacon_scans.push(peers); + c3nav._wifi_measurement_scan_update(); + } + c3nav._after_scan_results(); }, _after_scan_results: function () {