kopia lustrzana https://gitlab.com/gridtracker.org/gridtracker
Merge branch 'call-roster-refactor' into 'master'
big roster refactor - starting Closes #107, #91, and #76 See merge request gridtracker.org/gridtracker!139merge-requests/151/head test_1.21.1212_RollNWJS49
commit
537cd24e0f
|
@ -10,4 +10,4 @@ debian/tmp
|
|||
.DS_Store
|
||||
node_modules
|
||||
package-lock.json
|
||||
.vscode
|
||||
.vscode
|
3
LICENSE
3
LICENSE
|
@ -1,6 +1,7 @@
|
|||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2018-2020 GridTricker.org
|
||||
Copyright (c) 2018-2020 Stephen Tag Loomis
|
||||
Copyright (c) 2018-2022 GridTricker.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,6 +1,24 @@
|
|||
gridtracker (1.21.1212) unstable; urgency=low
|
||||
Release build with the call roster refactor code that's been in the works for some time.
|
||||
[Bug Fixes]
|
||||
- Fix #76, unfinished ignore CQ and ITU zones.
|
||||
- Improved handling of stations that are not in a valid DXCC (ie; /MM stations)
|
||||
- Improved handling of free text decodes that don't contain valid callsigns (ie "HI BOB" and "MERRY XMAS")
|
||||
- Fix how the Call Roster title bar counts are calculated.
|
||||
[Enhancements]
|
||||
- More clarity when a ULS Zip code falls in more then one county, replacing ~ with ? symbols and
|
||||
better tool tip message.
|
||||
- Fix #107, where the call roster timeout was longer then a single FT4 cycle.
|
||||
- Fix #91, CQ is always highlighted, no matter status of CQ Only.
|
||||
- Performance improvement by changing how call roster vars are handled ('let' vs 'var')
|
||||
- Build system improved to push to Arch AUR, building of Debian (.deb) packages and triggering
|
||||
of COPR RPM builds for Fedora/Cent/RHEL and their cousins.
|
||||
|
||||
-- Matthew Chambers <nr0q@gridtracker.org> Thu, 12 Dec 2021 15:10:00 -0000
|
||||
|
||||
gridtracker (1.21.0928) unstable; urgency=medium
|
||||
[Bug Fixes]
|
||||
- Treat ADIF record values as byte length vs string length (to better handle UTF-8 data).
|
||||
- Treat ADIF record values as byte length vs string length (to better handle UTSF-8 data).
|
||||
- Remove looking at fetched records for last date for LoTW fetches, Use only headers (More reliable LoTW fetches).
|
||||
[Enhancements]
|
||||
- ARM builds now with NWJS 0.54.2 and 64 bit ARM binaries.
|
||||
|
|
|
@ -4,9 +4,9 @@ Upstream-Contact: GridTracker Team <contact@gridtracker.org>
|
|||
Source: https://gitlab.com/gridtracker.org/gridtracker
|
||||
|
||||
Files: *
|
||||
Copyright: Copyright (c) 2018-2020 by Tag Loomis, 2020 by GridTracker.org
|
||||
Copyright: Copyright (c) 2018-2020 by Tag Loomis, 2020-2022 by GridTracker.org
|
||||
License: BSD-3-clause
|
||||
Copyright (c) 2018-2020 GridTricker.org
|
||||
Copyright (c) 2018-2022 GridTricker.org
|
||||
All rights reserved.
|
||||
.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -43,7 +43,7 @@ Run gridtracker, no arguments needed.
|
|||
.SH COPYRIGHT
|
||||
.PP
|
||||
Copyright (c) 2018-2020 Stephen Tag Loomis. All rights reserved.
|
||||
Copyright (c) 2020 GridTracker.org. All rights reserved.
|
||||
Copyright (c) 2020-2022 GridTracker.org. All rights reserved.
|
||||
Released under BSD 3-Clause License
|
||||
https://gridtracker.org
|
||||
|
||||
|
|
|
@ -40,7 +40,19 @@ DESTDIR=${RPM_BUILD_ROOT} make clean
|
|||
%license %{_docdir}/%{name}/
|
||||
|
||||
%changelog
|
||||
* Sun Dec 13 2021 Matthew Chambers <nr0q@gridtracker.org> - 1.21.1212-1
|
||||
- Release with refactored Call Roster code and minor improvements.
|
||||
* Sun Dec 12 2021 Matthew Chambers <nr0q@gridtracker.org> - 1.21.1212-1
|
||||
- Release build with the call roster refactor code that's been in the works for some time.
|
||||
- [Bug Fixes]
|
||||
- Fix #76, unfinished ignore CQ and ITU zones.
|
||||
- Improved handling of stations that are not in a valid DXCC (ie; /MM stations)
|
||||
- Improved handling of free text decodes that don't contain valid callsigns (ie "HI BOB" and "MERRY XMAS")
|
||||
- Fix how the Call Roster title bar counts are calculated.
|
||||
- [Enhancements]
|
||||
- More clarity when a ULS Zip code falls in more then one county, replacing ~ with ? symbols and better tool tip message.
|
||||
- Fix #107, where the call roster timeout was longer then a single FT4 cycle.
|
||||
- Fix #91, CQ is always highlighted, no matter status of CQ Only.
|
||||
- Performance improvement by changing how call roster vars are handled ('let' vs 'var')
|
||||
- Build system improved to push to Arch AUR, building of Debian (.deb) packages and triggering
|
||||
of COPR RPM builds for Fedora/Cent/RHEL and their cousins.
|
||||
* Thu Sep 30 2021 Matthew Chambers <nr0q@gridtracker.org> - 1.21.0928-1
|
||||
- First attempt at repo grade RPM builds
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
GridTracker Copyright © 2018-2021 GridTracker.org
|
||||
GridTracker Copyright © 2018-2022 GridTracker.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
@ -2893,7 +2893,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
<td colspan="2">
|
||||
<input
|
||||
type="range"
|
||||
min="15"
|
||||
min="5"
|
||||
max="300"
|
||||
value="120"
|
||||
step="15"
|
||||
|
@ -2905,6 +2905,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mapItem">
|
||||
<table align="center">
|
||||
<tr align="center">
|
||||
<td align="center">Clear Call Roster on Band change</td>
|
||||
</tr>
|
||||
<tr align="center">
|
||||
<td colspan="2">
|
||||
<input type="checkbox" id="clearRosterOnBandChange" onchange="clearRosterOnBandChangeValueChanged(this);" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<br />
|
||||
<div class="mapItem" id="haltTXDiv" style="display: none">
|
||||
<table align="center">
|
||||
|
@ -3526,7 +3538,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
>GridTracker.org!</a
|
||||
>
|
||||
</p>
|
||||
<p>Copyright © 2021 GridTracker.org</p>
|
||||
<p>Copyright © 2022 GridTracker.org</p>
|
||||
<img src="./gridview.png" /> <br />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -43923,6 +43923,31 @@
|
|||
"worked_modes": {},
|
||||
"confirmed_modes": {}
|
||||
},
|
||||
"390": {
|
||||
"dxcc": "0",
|
||||
"cc": "-",
|
||||
"ccc": "-",
|
||||
"name": "None",
|
||||
"continent": "-",
|
||||
"ituzone": ["-"],
|
||||
"cqzone": ["-"],
|
||||
"timezone": "1",
|
||||
"ccode": "-",
|
||||
"aname": "None",
|
||||
"mh": [],
|
||||
"prefix": [],
|
||||
"worked": false,
|
||||
"confirmed": false,
|
||||
"flag": "un.png",
|
||||
"pp": "-",
|
||||
"lat": 0.0,
|
||||
"lon": 0.0,
|
||||
"geo": "deleted",
|
||||
"worked_bands": {},
|
||||
"confirmed_bands": {},
|
||||
"worked_modes": {},
|
||||
"confirmed_modes": {}
|
||||
},
|
||||
"-1": {
|
||||
"dxcc": "-1",
|
||||
"cc": "-",
|
||||
|
|
|
@ -22,6 +22,13 @@
|
|||
<script src="./lib/protos.js" type="text/javascript"></script>
|
||||
<script src="./lib/third-party.js" type="text/javascript"></script>
|
||||
<script src="./lib/roster.js" type="text/javascript"></script>
|
||||
<script src="./lib/roster/prepareRosterSettings.js" type="text/javascript"></script>
|
||||
<script src="./lib/roster/processRosterFiltering.js" type="text/javascript"></script>
|
||||
<script src="./lib/roster/processRosterHunting.js" type="text/javascript"></script>
|
||||
<script src="./lib/roster/renderCompactRoster.js" type="text/javascript"></script>
|
||||
<script src="./lib/roster/renderNormalRoster.js" type="text/javascript"></script>
|
||||
<script src="./lib/roster/renderRoster.js" type="text/javascript"></script>
|
||||
<script src="./lib/roster/sendAlerts.js" type="text/javascript"></script>
|
||||
<script src="./lib/screens.js"></script>
|
||||
</head>
|
||||
<body onload="init()" class="roster" oncontextmenu="return handleContextMenu(event);">
|
||||
|
|
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
|
@ -1,4 +1,4 @@
|
|||
// GridTracker Copyright © 2021 GridTracker.org
|
||||
// GridTracker Copyright © 2022 GridTracker.org
|
||||
// All rights reserved.
|
||||
// See LICENSE for more information.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// GridTracker Copyright © 2021 GridTracker.org
|
||||
// GridTracker Copyright © 2022 GridTracker.org
|
||||
// All rights reserved.
|
||||
// See LICENSE for more information.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// GridTracker Copyright © 2021 GridTracker.org
|
||||
// GridTracker Copyright © 2022 GridTracker.org
|
||||
// All rights reserved.
|
||||
// See LICENSE for more information.
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ var def_appSettings = {
|
|||
lookupPasswordQth: "",
|
||||
lookupService: "CALLOOK",
|
||||
lookupCallookPreferred: false,
|
||||
clearRosterOnBandChange: false,
|
||||
moonPath: 0,
|
||||
moonTrack: 0,
|
||||
mouseTrack: 0,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// GridTracker Copyright © 2021 GridTracker.org
|
||||
// GridTracker Copyright © 2022 GridTracker.org
|
||||
// All rights reserved.
|
||||
// See LICENSE for more information.
|
||||
const pjson = require("./package.json");
|
||||
|
@ -12138,7 +12138,7 @@ function callsignToDxcc(insign)
|
|||
{
|
||||
if (parts[end].toUpperCase() == "MM")
|
||||
{
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
parts.pop();
|
||||
end = parts.length - 1;
|
||||
|
@ -12962,6 +12962,7 @@ function loadMapSettings()
|
|||
focusRigValue.checked = g_mapSettings.focusRig;
|
||||
haltAllOnTxValue.checked = g_mapSettings.haltAllOnTx;
|
||||
strikesAlert.value = g_mapSettings.strikesAlert;
|
||||
clearRosterOnBandChange.checked = g_appSettings.clearRosterOnBandChange;
|
||||
|
||||
setStrikesButton();
|
||||
|
||||
|
@ -14393,6 +14394,11 @@ function loadLookupDetails()
|
|||
else lookupCredentials.style.display = "block";
|
||||
}
|
||||
|
||||
function clearRosterOnBandChangeValueChanged(what)
|
||||
{
|
||||
g_appSettings.clearRosterOnBandChange = clearRosterOnBandChange.checked;
|
||||
}
|
||||
|
||||
function lookupValueChanged(what)
|
||||
{
|
||||
if (g_appSettings.lookupService != lookupService.value)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// GridTracker Copyright © 2021 GridTracker.org
|
||||
// GridTracker Copyright © 2022 GridTracker.org
|
||||
// All rights reserved.
|
||||
// See LICENSE for more information.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// GridTracker Copyright © 2021 GridTracker.org
|
||||
// GridTracker Copyright © 2022 GridTracker.org
|
||||
// All rights reserved.
|
||||
// See LICENSE for more information.
|
||||
|
||||
|
@ -141,7 +141,7 @@ Number.prototype.toDHM = function ()
|
|||
|
||||
days = days ? days + "d " : "";
|
||||
hrs = hrs ? hrs + "h " : "";
|
||||
mnts = mnts ? mnts + "m " : "";
|
||||
mnts = mnts || seconds ? mnts + "m " : "";
|
||||
val = days + hrs + mnts;
|
||||
return val;
|
||||
};
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,83 @@
|
|||
function prepareRosterSettings()
|
||||
{
|
||||
let rosterSettings = {
|
||||
bands: {},
|
||||
modes: {},
|
||||
callMode: g_rosterSettings.callsign,
|
||||
onlyHits: false,
|
||||
isAwardTracker: false,
|
||||
now: timeNowSec()
|
||||
}
|
||||
|
||||
if (rosterSettings.callMode == "hits")
|
||||
{
|
||||
rosterSettings.callMode = "all"
|
||||
rosterSettings.onlyHits = true;
|
||||
}
|
||||
if (referenceNeed.value == LOGBOOK_AWARD_TRACKER)
|
||||
{
|
||||
rosterSettings.callMode = "all";
|
||||
rosterSettings.onlyHits = false;
|
||||
rosterSettings.isAwardTracker = true;
|
||||
g_rosterSettings.huntNeed = "confirmed";
|
||||
}
|
||||
// this appears to be determine if we should show the OAMS column
|
||||
// if the user is not in offline mode and has OAMS enabled, this could
|
||||
// be it's own function maybe?
|
||||
rosterSettings.canMsg =
|
||||
window.opener.g_mapSettings.offlineMode == false &&
|
||||
window.opener.g_appSettings.gtShareEnable == "true" &&
|
||||
window.opener.g_appSettings.gtMsgEnable == "true";
|
||||
|
||||
// The following 3 sections deal with QSLing, do we break them out
|
||||
// individually or lump them into a qslUser function that sets
|
||||
// all three at the same time?
|
||||
// this section is for LoTW users, can be a function
|
||||
if (window.opener.g_callsignLookups.lotwUseEnable == true)
|
||||
{
|
||||
usesLoTWDiv.style.display = "";
|
||||
if (g_rosterSettings.usesLoTW == true)
|
||||
{
|
||||
maxLoTW.style.display = "";
|
||||
maxLoTWView.style.display = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
maxLoTW.style.display = "none";
|
||||
maxLoTWView.style.display = "none";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
usesLoTWDiv.style.display = "none";
|
||||
maxLoTW.style.display = "none";
|
||||
maxLoTWView.style.display = "none";
|
||||
}
|
||||
|
||||
if (g_rosterSettings.huntNeed == "mixed")
|
||||
{
|
||||
rosterSettings.huntIndex = g_confirmed;
|
||||
rosterSettings.workedIndex = g_worked;
|
||||
rosterSettings.layeredMode = LAYERED_MODE_FOR[String(g_rosterSettings.reference)];
|
||||
}
|
||||
else if (g_rosterSettings.huntNeed == "worked")
|
||||
{
|
||||
rosterSettings.huntIndex = g_worked;
|
||||
rosterSettings.workedIndex = false;
|
||||
rosterSettings.layeredMode = false;
|
||||
}
|
||||
else if (g_rosterSettings.huntNeed == "confirmed")
|
||||
{
|
||||
rosterSettings.huntIndex = g_confirmed;
|
||||
rosterSettings.workedIndex = g_worked;
|
||||
rosterSettings.layeredMode = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rosterSettings.huntIndex = false;
|
||||
rosterSettings.workedIndex = false;
|
||||
rosterSettings.layeredMode = false;
|
||||
}
|
||||
|
||||
return rosterSettings
|
||||
}
|
|
@ -0,0 +1,384 @@
|
|||
function processRosterFiltering(callRoster, rosterSettings)
|
||||
{
|
||||
// First loop, exclude calls, mostly based on "Exceptions" settings
|
||||
// this whole section is full of individual if's that could be broken out
|
||||
for (let callHash in callRoster)
|
||||
{
|
||||
let entry = callRoster[callHash];
|
||||
let callObj = entry.callObj;
|
||||
|
||||
let call = entry.DEcall;
|
||||
|
||||
entry.tx = true;
|
||||
callObj.shouldAlert = false;
|
||||
callObj.reason = Array();
|
||||
callObj.awardReason = "Callsign";
|
||||
|
||||
if (rosterSettings.now - callObj.age > window.opener.g_mapSettings.rosterTime)
|
||||
{
|
||||
entry.tx = false;
|
||||
entry.alerted = false;
|
||||
callObj.qrz = false;
|
||||
callObj.reset = true;
|
||||
continue;
|
||||
}
|
||||
if (!callObj.dxcc || callObj.dxcc == -1)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (window.opener.g_instances[callObj.instance].crEnable == false)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (call in g_blockedCalls)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
entry.DXcall + " from All" in g_blockedCQ ||
|
||||
entry.DXcall + " from " + window.opener.g_dxccToAltName[callObj.dxcc] in g_blockedCQ
|
||||
)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (callObj.ituza in g_blockedITUz)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (callObj.cqza in g_blockedCQz)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (callObj.dxcc in g_blockedDxcc)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (g_rosterSettings.cqOnly == true && callObj.CQ == false)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (g_rosterSettings.useRegex && g_rosterSettings.callsignRegex.length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!call.match(g_rosterSettings.callsignRegex))
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (e) {}
|
||||
}
|
||||
if (g_rosterSettings.requireGrid == true && callObj.grid.length != 4)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (g_rosterSettings.wantMinDB == true && entry.message.SR < g_rosterSettings.minDb)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (g_rosterSettings.wantMaxDT == true && Math.abs(entry.message.DT) > g_rosterSettings.maxDT)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (g_rosterSettings.wantMinFreq == true && entry.message.DF < g_rosterSettings.minFreq)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (g_rosterSettings.wantMaxFreq == true && entry.message.DF > g_rosterSettings.maxFreq)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_rosterSettings.noMsg == true)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (callObj.msg.match(g_rosterSettings.noMsgValue))
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (e) {}
|
||||
}
|
||||
if (g_rosterSettings.onlyMsg == true)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!callObj.msg.match(g_rosterSettings.onlyMsgValue))
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (e) {}
|
||||
}
|
||||
|
||||
if (callObj.dxcc == window.opener.g_myDXCC)
|
||||
{
|
||||
if (g_rosterSettings.noMyDxcc == true)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_rosterSettings.onlyMyDxcc == true)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (window.opener.g_callsignLookups.lotwUseEnable == true && g_rosterSettings.usesLoTW == true)
|
||||
{
|
||||
if (!(call in window.opener.g_lotwCallsigns))
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (g_rosterSettings.maxLoTW < 27)
|
||||
{
|
||||
let months = (g_day - window.opener.g_lotwCallsigns[call]) / 30;
|
||||
if (months > g_rosterSettings.maxLoTW)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (window.opener.g_callsignLookups.eqslUseEnable == true && g_rosterSettings.useseQSL == true)
|
||||
{
|
||||
if (!(call in window.opener.g_eqslCallsigns))
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (window.opener.g_callsignLookups.oqrsUseEnable == true && g_rosterSettings.usesOQRS == true)
|
||||
{
|
||||
if (!(call in window.opener.g_oqrsCallsigns))
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (rosterSettings.callMode != "all")
|
||||
{
|
||||
if (entry.DXcall == "CQ DX" && callObj.dxcc == window.opener.g_myDXCC)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
let hash = hashMaker(call, callObj, g_rosterSettings.reference);
|
||||
if (rosterSettings.callMode == "worked" && hash in g_worked.call)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (rosterSettings.callMode == "confirmed" && hash in g_confirmed.call)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_rosterSettings.hunting == "grid")
|
||||
{
|
||||
let hash = hashMaker(callObj.grid.substr(0, 4),
|
||||
callObj, g_rosterSettings.reference);
|
||||
if (rosterSettings.huntIndex && hash in rosterSettings.huntIndex.grid)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
if (callObj.grid.length == 0)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (g_rosterSettings.hunting == "dxcc")
|
||||
{
|
||||
let hash = hashMaker(String(callObj.dxcc),
|
||||
callObj, g_rosterSettings.reference);
|
||||
|
||||
if (rosterSettings.huntIndex && (hash in rosterSettings.huntIndex.dxcc))
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (callObj.dxcc === -1)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_rosterSettings.hunting == "dxccs" && r_currentDXCCs != -1)
|
||||
{
|
||||
if (callObj.dxcc != r_currentDXCCs)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_rosterSettings.hunting == "wpx")
|
||||
{
|
||||
if (String(callObj.px) == null)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
let hash = hashMaker(String(callObj.px),
|
||||
callObj, g_rosterSettings.reference);
|
||||
|
||||
if (rosterSettings.huntIndex && (hash in rosterSettings.huntIndex.px))
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_rosterSettings.hunting == "cq")
|
||||
{
|
||||
let huntTotal = callObj.cqza.length;
|
||||
if (huntTotal == 0 || !rosterSettings.huntIndex)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
let huntFound = 0;
|
||||
for (index in callObj.cqza)
|
||||
{
|
||||
let hash = hashMaker(callObj.cqza[index], callObj, g_rosterSettings.reference);
|
||||
|
||||
if (hash in rosterSettings.huntIndex.cqz) huntFound++;
|
||||
}
|
||||
if (huntFound == huntTotal)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_rosterSettings.hunting == "itu")
|
||||
{
|
||||
let huntTotal = callObj.ituza.length;
|
||||
if (huntTotal == 0 || !rosterSettings.huntIndex)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
let huntFound = 0;
|
||||
for (index in callObj.ituza)
|
||||
{
|
||||
let hash = hashMaker(callObj.ituza[index], callObj, g_rosterSettings.reference);
|
||||
|
||||
if (hash in rosterSettings.huntIndex.ituz) huntFound++;
|
||||
}
|
||||
if (huntFound == huntTotal)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (callObj.grid.length == 0)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_rosterSettings.hunting == "usstates" && window.opener.g_callsignLookups.ulsUseEnable == true)
|
||||
{
|
||||
let state = callObj.state;
|
||||
let finalDxcc = callObj.dxcc;
|
||||
if (finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6)
|
||||
{
|
||||
if (state in window.opener.g_StateData)
|
||||
{
|
||||
let hash = hashMaker(state, callObj, g_rosterSettings.reference);
|
||||
|
||||
if (rosterSettings.huntIndex && hash in rosterSettings.huntIndex.state)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else entry.tx = false;
|
||||
}
|
||||
else entry.tx = false;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_rosterSettings.hunting == "usstate" && g_currentUSCallsigns)
|
||||
{
|
||||
if (call in g_currentUSCallsigns)
|
||||
{
|
||||
// Do Nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (rosterSettings.isAwardTracker)
|
||||
{
|
||||
let tx = false;
|
||||
let baseHash = hashMaker("", callObj, g_rosterSettings.reference);
|
||||
|
||||
for (let award in g_awardTracker)
|
||||
{
|
||||
if (g_awardTracker[award].enable)
|
||||
{
|
||||
tx = testAward(award, callObj, baseHash);
|
||||
if (tx)
|
||||
{
|
||||
let x = g_awardTracker[award];
|
||||
|
||||
// TODO: Move award reason out of exclusions code?
|
||||
callObj.awardReason =
|
||||
g_awards[x.sponsor].awards[x.name].tooltip +
|
||||
" (" +
|
||||
g_awards[x.sponsor].sponsor +
|
||||
")";
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
entry.tx = tx;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,700 @@
|
|||
function processRosterHunting(callRoster, rosterSettings)
|
||||
{
|
||||
// these lets, do they rely on anything between the top and here?
|
||||
// if not could they be put in the let list at the beginning?
|
||||
let hasGtPin = false;
|
||||
|
||||
let inversionAlpha = "DD";
|
||||
let row = "#000000";
|
||||
let bold = "#000000;font-weight: bold;";
|
||||
let unconf = "background-clip:padding-box;box-shadow: 0 0 7px 3px inset ";
|
||||
let layeredAlpha = "77";
|
||||
let layeredInversionAlpha = "66";
|
||||
let layeredUnconf = "background-clip:padding-box;box-shadow: 0 0 4px 2px inset ";
|
||||
let layeredUnconfAlpha = "AA";
|
||||
|
||||
// TODO: Hunting results might be used to filter, based on the "Callsigns: Only Wanted" option,
|
||||
// so maybe we can move this loop first, and add a check to the filtering loop?
|
||||
|
||||
// Second loop, hunting and highlighting
|
||||
for (let callHash in callRoster)
|
||||
{
|
||||
let entry = callRoster[callHash];
|
||||
let callObj = entry.callObj;
|
||||
|
||||
// Special case check for called station
|
||||
if (callObj.qrz == true && entry.tx == false)
|
||||
{
|
||||
// The instance has to be enabled
|
||||
if (window.opener.g_instances[callObj.instance].crEnable == true)
|
||||
{
|
||||
// Calling us, but we wouldn't normally display
|
||||
// If they are not ignored or we're in a QSO with them, let it through
|
||||
|
||||
// TODO: This is here because it's after the filtering stage
|
||||
if ((!(entry.DEcall in g_blockedCalls) && !(callObj.dxcc in g_blockedDxcc)) ||
|
||||
window.opener.g_instances[callObj.instance].status.DXcall == entry.DEcall)
|
||||
{
|
||||
entry.tx = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only render entries with `tx == true`, ignore the rest
|
||||
if (callObj.dxcc != -1 && entry.tx == true)
|
||||
{
|
||||
// In layered mode ("Hunting: mixed") the workHashSuffix becomes a more stricter 'live band',
|
||||
// while the layered suffix is a broader 'mixed band'
|
||||
let workHashSuffix, layeredHashSuffix;
|
||||
if (rosterSettings.layeredMode)
|
||||
{
|
||||
workHashSuffix = hashMaker("", callObj, rosterSettings.layeredMode);
|
||||
layeredHashSuffix = hashMaker("", callObj, g_rosterSettings.reference);
|
||||
}
|
||||
else
|
||||
{
|
||||
workHashSuffix = hashMaker("", callObj, g_rosterSettings.reference);
|
||||
layeredHashSuffix = false
|
||||
}
|
||||
let workHash = workHashSuffix; // TODO: Remove after replacing all occurrences with Suffix
|
||||
|
||||
let callsign = entry.DEcall;
|
||||
|
||||
callObj.hunting = {}
|
||||
callObj.callFlags = {}
|
||||
|
||||
let colorObject = Object();
|
||||
|
||||
let callPointer = callObj.CQ == true ? "cursor:pointer" : "";
|
||||
|
||||
let didWork = false;
|
||||
|
||||
let call = "#FFFF00";
|
||||
let grid = "#00FFFF";
|
||||
let calling = "#90EE90";
|
||||
let dxcc = "#FFA500";
|
||||
let state = "#90EE90";
|
||||
let cnty = "#CCDD00";
|
||||
let cont = "#00DDDD";
|
||||
let cqz = "#DDDDDD";
|
||||
let ituz = "#DDDDDD";
|
||||
let wpx = "#FFFF00";
|
||||
|
||||
hasGtPin = false;
|
||||
let shouldAlert = false;
|
||||
let callBg, gridBg, callingBg, dxccBg, stateBg, cntyBg, contBg, cqzBg, ituzBg, wpxBg, gtBg;
|
||||
let callConf, gridConf, callingConf, dxccConf, stateConf, cntyConf, contConf, cqzConf, ituzConf, wpxConf;
|
||||
|
||||
callBg = gridBg = callingBg = dxccBg = stateBg = cntyBg = contBg = cqzBg = ituzBg = wpxBg = gtBg = row;
|
||||
|
||||
callConf = gridConf = callingConf = dxccConf = stateConf = cntyConf = contConf = cqzConf = ituzConf = wpxConf =
|
||||
"";
|
||||
|
||||
let hash = callsign + workHashSuffix;
|
||||
let layeredHash = layeredHashSuffix && (callsign + layeredHashSuffix)
|
||||
|
||||
// Call worked in current logbook settings, regardless of hunting mode
|
||||
if (hash in g_worked.call)
|
||||
{
|
||||
callObj.callFlags.worked = true;
|
||||
didWork = true;
|
||||
callConf = `${unconf}${call}${inversionAlpha};`;
|
||||
|
||||
if (hash in g_confirmed.call)
|
||||
{
|
||||
callObj.callFlags.confirmed = true;
|
||||
callPointer = "text-decoration: line-through; ";
|
||||
callConf = "";
|
||||
}
|
||||
}
|
||||
|
||||
// Calls that have OAMS chat support
|
||||
if (
|
||||
callsign in window.opener.g_gtCallsigns &&
|
||||
window.opener.g_gtCallsigns[callsign] in window.opener.g_gtFlagPins &&
|
||||
window.opener.g_gtFlagPins[window.opener.g_gtCallsigns[callsign]].canmsg == true
|
||||
)
|
||||
{
|
||||
callObj.callFlags.oams = true;
|
||||
// grab the CID
|
||||
colorObject.gt = window.opener.g_gtCallsigns[callsign];
|
||||
hasGtPin = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
colorObject.gt = 0;
|
||||
}
|
||||
|
||||
// We only do hunt highlighting when showing all entries
|
||||
// This means "Callsigns: All Traffic", "Callsigns: All Traffic/Only Wanted" and "Logbook: Award Tracker"
|
||||
// There is no highlighting in other modes
|
||||
if (rosterSettings.callMode == "all")
|
||||
{
|
||||
// Skip when "only new calls"
|
||||
// Questions: Move to the first loop? Why only skip new calls in "all traffic" and not other modes?
|
||||
if (allOnlyNew.checked == true && didWork && callObj.qrz == false)
|
||||
{
|
||||
entry.tx = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Hunting for callsigns
|
||||
if (huntCallsign.checked == true)
|
||||
{
|
||||
let hash = callsign + workHashSuffix;
|
||||
let layeredHash = rosterSettings.layeredMode && (callsign + layeredHashSuffix)
|
||||
|
||||
if (rosterSettings.huntIndex && !(hash in rosterSettings.huntIndex.call))
|
||||
{
|
||||
shouldAlert = true;
|
||||
|
||||
callObj.reason.push("call");
|
||||
|
||||
if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.call)
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.call)
|
||||
{
|
||||
callObj.hunting.call = "worked-and-mixed";
|
||||
callConf = `${layeredUnconf}${call}${layeredUnconfAlpha};`;
|
||||
callBg = `${call}${layeredInversionAlpha}`;
|
||||
call = bold;
|
||||
}
|
||||
// /* Currently we don't have a way to figure out
|
||||
// * if the call is worked only in this band or also others,
|
||||
// * so we cannot cover this particular combination
|
||||
// * and have to default to just showing it as plain "worked"
|
||||
// */
|
||||
// else if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.call)
|
||||
// {
|
||||
// callObj.hunting.call = "worked-and-mixed-worked";
|
||||
// callConf = `${layeredUnconf}${call}${layeredAlpha};`;
|
||||
// }
|
||||
else
|
||||
{
|
||||
callObj.hunting.call = "worked";
|
||||
callConf = `${unconf}${call}${inversionAlpha};`;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.call)
|
||||
{
|
||||
callObj.hunting.call = "mixed";
|
||||
callBg = `${call}${layeredAlpha};`;
|
||||
call = bold;
|
||||
}
|
||||
else if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.call)
|
||||
{
|
||||
callObj.hunting.call = "mixed-worked";
|
||||
callConf = `${unconf}${call}${layeredAlpha};`;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.call = "hunted";
|
||||
callBg = `${call}${inversionAlpha};`;
|
||||
call = bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hunting for "stations calling you"
|
||||
if (huntQRZ.checked == true && callObj.qrz == true)
|
||||
{
|
||||
callObj.callFlags.calling = true
|
||||
shouldAlert = true;
|
||||
callObj.reason.push("qrz");
|
||||
}
|
||||
|
||||
// Hunting for stations with OAMS
|
||||
if (huntOAMS.checked == true && hasGtPin == true)
|
||||
{
|
||||
callObj.hunting.oams = "hunted";
|
||||
shouldAlert = true;
|
||||
callObj.reason.push("oams");
|
||||
}
|
||||
|
||||
// Hunting for grids
|
||||
if (huntGrid.checked == true && callObj.grid.length > 1)
|
||||
{
|
||||
let hash = callObj.grid.substr(0, 4) + workHashSuffix;
|
||||
let layeredHash = rosterSettings.layeredMode && (callObj.grid.substr(0, 4) + layeredHashSuffix)
|
||||
|
||||
if (rosterSettings.huntIndex && !(hash in rosterSettings.huntIndex.grid))
|
||||
{
|
||||
shouldAlert = true;
|
||||
|
||||
callObj.reason.push("grid");
|
||||
|
||||
if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.grid)
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.grid)
|
||||
{
|
||||
callObj.hunting.grid = "worked-and-mixed";
|
||||
gridConf = `${layeredUnconf}${grid}${layeredUnconfAlpha};`;
|
||||
gridBg = `${grid}${layeredInversionAlpha}`;
|
||||
grid = bold;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.grid = "worked";
|
||||
gridConf = `${unconf}${grid}${inversionAlpha};`;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.grid)
|
||||
{
|
||||
callObj.hunting.grid = "mixed";
|
||||
gridBg = `${grid}${layeredAlpha};`;
|
||||
grid = bold;
|
||||
}
|
||||
else if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.grid)
|
||||
{
|
||||
callObj.hunting.grid = "mixed-worked";
|
||||
gridConf = `${unconf}${grid}${layeredAlpha};`;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.grid = "hunted";
|
||||
gridBg = `${grid}${inversionAlpha};`;
|
||||
grid = bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hunting for DXCC
|
||||
if (huntDXCC.checked == true)
|
||||
{
|
||||
let hash = String(callObj.dxcc) + workHashSuffix;
|
||||
let layeredHash = rosterSettings.layeredMode && (String(callObj.dxcc) + layeredHashSuffix)
|
||||
|
||||
if (rosterSettings.huntIndex && !(hash in rosterSettings.huntIndex.dxcc))
|
||||
{
|
||||
shouldAlert = true;
|
||||
|
||||
callObj.reason.push("dxcc");
|
||||
|
||||
if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.dxcc)
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.dxcc)
|
||||
{
|
||||
callObj.hunting.dxcc = "worked-and-mixed";
|
||||
dxccConf = `${layeredUnconf}${dxcc}${layeredUnconfAlpha};`;
|
||||
dxccBg = `${dxcc}${layeredInversionAlpha}`;
|
||||
dxcc = bold;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.dxcc = "worked";
|
||||
dxccConf = `${unconf}${dxcc}${inversionAlpha};`;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.dxcc)
|
||||
{
|
||||
callObj.hunting.dxcc = "mixed";
|
||||
dxccBg = `${dxcc}${layeredAlpha};`;
|
||||
dxcc = bold;
|
||||
}
|
||||
else if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.dxcc)
|
||||
{
|
||||
callObj.hunting.dxcc = "mixed-worked";
|
||||
dxccConf = `${unconf}${dxcc}${layeredAlpha};`;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.dxcc = "hunted";
|
||||
dxccBg = `${dxcc}${inversionAlpha};`;
|
||||
dxcc = bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hunting for US States
|
||||
if (huntState.checked == true && window.opener.g_callsignLookups.ulsUseEnable == true)
|
||||
{
|
||||
let stateSearch = callObj.state;
|
||||
let finalDxcc = callObj.dxcc;
|
||||
if (finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6)
|
||||
{
|
||||
if (stateSearch in window.opener.g_StateData)
|
||||
{
|
||||
let hash = stateSearch + workHashSuffix;
|
||||
let layeredHash = rosterSettings.layeredMode && (stateSearch + layeredHashSuffix)
|
||||
|
||||
if (rosterSettings.huntIndex && !(hash in rosterSettings.huntIndex.state))
|
||||
{
|
||||
shouldAlert = true;
|
||||
|
||||
callObj.reason.push("state");
|
||||
|
||||
if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.state)
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.state)
|
||||
{
|
||||
callObj.hunting.state = "worked-and-mixed";
|
||||
stateConf = `${layeredUnconf}${state}${layeredUnconfAlpha};`;
|
||||
stateBg = `${state}${layeredInversionAlpha}`;
|
||||
state = bold;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.state = "worked";
|
||||
stateConf = `${unconf}${state}${inversionAlpha};`;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.state)
|
||||
{
|
||||
callObj.hunting.state = "mixed";
|
||||
stateBg = `${state}${layeredAlpha};`;
|
||||
state = bold;
|
||||
}
|
||||
else if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.state)
|
||||
{
|
||||
callObj.hunting.state = "mixed-worked";
|
||||
stateConf = `${unconf}${state}${layeredAlpha};`;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.state = "hunted";
|
||||
stateBg = `${state}${inversionAlpha};`;
|
||||
state = bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hunting for US Counties
|
||||
if (huntCounty.checked == true && window.opener.g_callsignLookups.ulsUseEnable == true)
|
||||
{
|
||||
let finalDxcc = callObj.dxcc;
|
||||
if (
|
||||
callObj.cnty &&
|
||||
(finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6 || finalDxcc == 202) &&
|
||||
callObj.cnty.length > 0
|
||||
)
|
||||
{
|
||||
let hash = callObj.cnty + (rosterSettings.layeredMode ? layeredHashSuffix : workHashSuffix);
|
||||
|
||||
if ((rosterSettings.huntIndex && !(hash in rosterSettings.huntIndex.cnty)) || callObj.qual == false)
|
||||
{
|
||||
if (callObj.qual == false)
|
||||
{
|
||||
let counties = window.opener.g_zipToCounty[callObj.zipcode];
|
||||
let foundHit = false;
|
||||
for (let cnt in counties)
|
||||
{
|
||||
let hh = counties[cnt] + workHash;
|
||||
callObj.cnty = counties[cnt];
|
||||
if (rosterSettings.huntIndex && !(hh in rosterSettings.huntIndex.cnty))
|
||||
{
|
||||
foundHit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundHit) shouldAlert = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
shouldAlert = true;
|
||||
}
|
||||
|
||||
if (shouldAlert)
|
||||
{
|
||||
callObj.reason.push("cnty");
|
||||
|
||||
if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.cnty)
|
||||
{
|
||||
callObj.hunting.cnty = "worked";
|
||||
cntyConf = `${unconf}${cnty}${inversionAlpha};`;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.cnty = "hunted";
|
||||
cntyBg = `${cnty}${inversionAlpha}`;
|
||||
cnty = bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hunting for CQ Zones
|
||||
if (huntCQz.checked == true)
|
||||
{
|
||||
let huntTotal = callObj.cqza.length;
|
||||
let huntFound = 0, layeredFound = 0, workedFound = 0, layeredWorkedFound = 0;
|
||||
|
||||
for (index in callObj.cqza)
|
||||
{
|
||||
let hash = callObj.cqza[index] + workHashSuffix;
|
||||
let layeredHash = rosterSettings.layeredMode && (callObj.cqza[index] + layeredHashSuffix)
|
||||
|
||||
if (rosterSettings.huntIndex && hash in rosterSettings.huntIndex.cqz) huntFound++;
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.cqz) layeredFound++;
|
||||
if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.cqz) workedFound++;
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.cqz) layeredWorkedFound++;
|
||||
}
|
||||
if (huntFound != huntTotal)
|
||||
{
|
||||
shouldAlert = true;
|
||||
callObj.reason.push("cqz");
|
||||
|
||||
if (rosterSettings.workedIndex && workedFound == huntTotal)
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredFound == huntTotal)
|
||||
{
|
||||
callObj.hunting.cqz = "worked-and-mixed";
|
||||
cqzConf = `${layeredUnconf}${cqz}${layeredUnconfAlpha};`;
|
||||
cqzBg = `${cqz}${layeredInversionAlpha}`;
|
||||
cqz = bold;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.cqz = "worked";
|
||||
cqzConf = `${unconf}${cqz}${inversionAlpha};`;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredFound == huntTotal)
|
||||
{
|
||||
callObj.hunting.cqz = "mixed";
|
||||
cqzBg = `${cqz}${layeredAlpha};`;
|
||||
cqz = bold;
|
||||
}
|
||||
else if (rosterSettings.layeredMode && layeredWorkedFound == huntTotal)
|
||||
{
|
||||
callObj.hunting.cqz = "mixed-worked";
|
||||
cqzConf = `${unconf}${cqz}${layeredAlpha};`;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.cqz = "hunted";
|
||||
cqzBg = `${cqz}${inversionAlpha};`;
|
||||
cqz = bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hunting for ITU Zones
|
||||
if (huntITUz.checked == true)
|
||||
{
|
||||
let huntTotal = callObj.ituza.length;
|
||||
let huntFound = 0, layeredFound = 0, workedFound = 0, layeredWorkedFound = 0;
|
||||
|
||||
for (index in callObj.ituza)
|
||||
{
|
||||
let hash = callObj.ituza[index] + workHashSuffix;
|
||||
let layeredHash = rosterSettings.layeredMode && (callObj.ituza[index] + layeredHashSuffix)
|
||||
|
||||
if (rosterSettings.huntIndex && hash in rosterSettings.huntIndex.ituz) huntFound++;
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.ituz) layeredFound++;
|
||||
if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.ituz) workedFound++;
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.ituz) layeredWorkedFound++;
|
||||
}
|
||||
if (huntFound != huntTotal)
|
||||
{
|
||||
shouldAlert = true;
|
||||
callObj.reason.push("ituz");
|
||||
|
||||
if (rosterSettings.workedIndex && workedFound == huntTotal)
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredFound == huntTotal)
|
||||
{
|
||||
callObj.hunting.ituz = "worked-and-mixed";
|
||||
ituzConf = `${layeredUnconf}${ituz}${layeredUnconfAlpha};`;
|
||||
ituzBg = `${ituz}${layeredInversionAlpha}`;
|
||||
ituz = bold;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.ituz = "worked";
|
||||
ituzConf = `${unconf}${ituz}${inversionAlpha};`;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredFound == huntTotal)
|
||||
{
|
||||
callObj.hunting.ituz = "mixed";
|
||||
ituzBg = `${ituz}${layeredAlpha};`;
|
||||
ituz = bold;
|
||||
}
|
||||
else if (rosterSettings.layeredMode && layeredWorkedFound == huntTotal)
|
||||
{
|
||||
callObj.hunting.ituz = "mixed-worked";
|
||||
ituzConf = `${unconf}${ituz}${layeredAlpha};`;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.ituz = "hunted";
|
||||
ituzBg = `${ituz}${inversionAlpha};`;
|
||||
ituz = bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hunting for WPX (Prefixes)
|
||||
if (huntPX.checked == true && callObj.px)
|
||||
{
|
||||
let hash = String(callObj.px) + workHashSuffix;
|
||||
let layeredHash = rosterSettings.layeredMode && (String(callObj.px) + layeredHashSuffix)
|
||||
|
||||
if (rosterSettings.huntIndex && !(hash in rosterSettings.huntIndex.px))
|
||||
{
|
||||
shouldAlert = true;
|
||||
|
||||
callObj.reason.push("wpx");
|
||||
|
||||
if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.px)
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.px)
|
||||
{
|
||||
callObj.hunting.wpx = "worked-and-mixed";
|
||||
wpxConf = `${layeredUnconf}${wpx}${layeredUnconfAlpha};`;
|
||||
wpxBg = `${wpx}${layeredInversionAlpha}`;
|
||||
wpx = bold;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.wpx = "worked";
|
||||
wpxConf = `${unconf}${wpx}${inversionAlpha};`;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.px)
|
||||
{
|
||||
callObj.hunting.wpx = "mixed";
|
||||
wpxBg = `${wpx}${layeredAlpha};`;
|
||||
wpx = bold;
|
||||
}
|
||||
else if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.px)
|
||||
{
|
||||
callObj.hunting.wpx = "mixed-worked";
|
||||
wpxConf = `${unconf}${wpx}${layeredAlpha};`;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.wpx = "hunted";
|
||||
wpxBg = `${wpx}${inversionAlpha};`;
|
||||
wpx = bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hunting for Continents
|
||||
if (huntCont.checked == true && callObj.cont)
|
||||
{
|
||||
let hash = String(callObj.cont) + workHashSuffix;
|
||||
let layeredHash = rosterSettings.layeredMode && (String(callObj.cont) + layeredHashSuffix)
|
||||
|
||||
if (rosterSettings.huntIndex && !(hash in rosterSettings.huntIndex.cont))
|
||||
{
|
||||
shouldAlert = true;
|
||||
|
||||
callObj.reason.push("cont");
|
||||
|
||||
if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.cont)
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.cont)
|
||||
{
|
||||
callObj.hunting.cont = "worked-and-mixed";
|
||||
contConf = `${layeredUnconf}${cont}${layeredUnconfAlpha};`;
|
||||
contBg = `${cont}${layeredInversionAlpha}`;
|
||||
cont = bold;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.cont = "worked";
|
||||
contConf = `${unconf}${cont}${inversionAlpha};`;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.cont)
|
||||
{
|
||||
callObj.hunting.cont = "mixed";
|
||||
contBg = `${cont}${layeredAlpha};`;
|
||||
cont = bold;
|
||||
}
|
||||
else if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.cont)
|
||||
{
|
||||
callObj.hunting.cont = "mixed-worked";
|
||||
contConf = `${unconf}${cont}${layeredAlpha};`;
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.hunting.cont = "hunted";
|
||||
contBg = `${cont}${inversionAlpha};`;
|
||||
cont = bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Station is calling us
|
||||
if (callObj.DXcall == window.opener.myDEcall)
|
||||
{
|
||||
callingBg = "#0000FF" + inversionAlpha;
|
||||
calling = "#FFFF00;text-shadow: 0px 0px 2px #FFFF00";
|
||||
}
|
||||
else if (callObj.CQ == true)
|
||||
{
|
||||
callingBg = calling + inversionAlpha;
|
||||
calling = bold;
|
||||
}
|
||||
|
||||
// Assemble all styles
|
||||
colorObject.call = "style='" + callConf + "background-color:" + callBg + ";color:" +
|
||||
call + ";" + callPointer + "'";
|
||||
colorObject.grid = "style='" + gridConf + "background-color:" + gridBg + ";color:" + grid + ";cursor:pointer'";
|
||||
colorObject.calling = "style='" + callingConf + "background-color:" + callingBg + ";color:" + calling + "'";
|
||||
colorObject.dxcc = "style='" + dxccConf + "background-color:" + dxccBg + ";color:" + dxcc + "'";
|
||||
colorObject.state = "style='" + stateConf + "background-color:" + stateBg + ";color:" + state + "'";
|
||||
colorObject.cnty = "style='" + cntyConf + "background-color:" + cntyBg + ";color:" + cnty + "'";
|
||||
colorObject.cont = "style='" + contConf + "background-color:" + contBg + ";color:" + cont + "'";
|
||||
colorObject.cqz = "style='" + cqzConf + "background-color:" + cqzBg + ";color:" + cqz + "'";
|
||||
colorObject.ituz = "style='" + ituzConf + "background-color:" + ituzBg + ";color:" + ituz + "'";
|
||||
colorObject.px = "style='" + wpxConf + "background-color:" + wpxBg + ";color:" + wpx + "'";
|
||||
|
||||
// Just in case, don't alert if we worked this callsign alread
|
||||
if (didWork && shouldAlert) shouldAlert = false;
|
||||
|
||||
callObj.shouldAlert = shouldAlert;
|
||||
|
||||
callObj.style = colorObject;
|
||||
|
||||
if (g_rosterSettings.columns.Spot)
|
||||
{
|
||||
callObj.spot = window.opener.getSpotTime(
|
||||
callObj.DEcall + callObj.mode + callObj.band + callObj.grid
|
||||
);
|
||||
if (callObj.spot == null)
|
||||
{
|
||||
callObj.spot = { when: 0, snr: 0 };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.spot = { when: 0, snr: 0 };
|
||||
}
|
||||
|
||||
rosterSettings.modes[callObj.mode] = true;
|
||||
rosterSettings.bands[callObj.band] = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
function renderCompactRosterHeaders()
|
||||
{
|
||||
return "<div id=\"buttonsDiv\" style=\"margin-left:0px;white-space:normal;\">";
|
||||
}
|
||||
|
||||
function renderCompactRosterRow(callObj)
|
||||
{
|
||||
var thisCall = callObj.DEcall;
|
||||
var tt =
|
||||
callObj.RSTsent +
|
||||
"㏈, " +
|
||||
parseInt(callObj.dt * 100) +
|
||||
"ms, " +
|
||||
callObj.delta +
|
||||
"hz" +
|
||||
(callObj.grid.length ? ", " + callObj.grid : "") +
|
||||
", " +
|
||||
(timeNowSec() - callObj.age).toDHMS();
|
||||
var worker =
|
||||
"<div class='compact' onClick='initiateQso(\"" +
|
||||
thisCall +
|
||||
callObj.band +
|
||||
callObj.mode +
|
||||
"\")' ";
|
||||
worker +=
|
||||
"id='" +
|
||||
thisCall +
|
||||
callObj.band +
|
||||
callObj.mode +
|
||||
"' title='" +
|
||||
tt +
|
||||
"'>";
|
||||
worker +=
|
||||
"<div class='compactCallsign' name='Callsign' " +
|
||||
callObj.style.call +
|
||||
" >" +
|
||||
thisCall.formatCallsign() +
|
||||
"</div>";
|
||||
worker +=
|
||||
"<div class='compactDXCC' name='DXCC (" +
|
||||
callObj.dxcc +
|
||||
")' " +
|
||||
callObj.style.dxcc +
|
||||
">" +
|
||||
window.opener.g_dxccToAltName[callObj.dxcc] +
|
||||
"</div>";
|
||||
worker += "</div>";
|
||||
|
||||
return worker;
|
||||
}
|
||||
|
||||
function renderCompactRosterFooter()
|
||||
{
|
||||
return "</div>";
|
||||
}
|
|
@ -0,0 +1,413 @@
|
|||
function renderNormalRosterHeaders(showBands, showModes)
|
||||
{
|
||||
let worker = ""
|
||||
worker = "<table id='callTable' class='rosterTable' align=left>";
|
||||
|
||||
worker += "<thead><th style='cursor:pointer;' onclick='showRosterBox(0);' align=left>Callsign</th>";
|
||||
|
||||
if (showBands)
|
||||
{ worker += "<th onclick='' >Band</th>"; }
|
||||
|
||||
if (showModes)
|
||||
{ worker += "<th onclick='' >Mode</th>"; }
|
||||
|
||||
worker += "<th style='cursor:pointer;' onclick='showRosterBox(1);' >Grid</th>";
|
||||
|
||||
if (g_rosterSettings.columns.Calling)
|
||||
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(10);' >Calling</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.Msg)
|
||||
{ worker += "<th >Msg</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.DXCC)
|
||||
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(5);' >DXCC</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.Flag)
|
||||
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(5);' >Flag</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.State)
|
||||
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(9);' >State</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.County)
|
||||
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(15);' >County</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.Cont)
|
||||
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(16);' >Cont</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.dB)
|
||||
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(2);' >dB</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.Freq)
|
||||
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(4);' >Freq</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.DT)
|
||||
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(3);' >DT</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.Dist)
|
||||
{
|
||||
worker += "<th style='cursor:pointer;' onclick='showRosterBox(7);' >Dist(" +
|
||||
window.opener.distanceUnit.value.toLowerCase() + ")</th>";
|
||||
}
|
||||
|
||||
if (g_rosterSettings.columns.Azim)
|
||||
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(8);' >Azim</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.CQz)
|
||||
{ worker += "<th>CQz</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.ITUz)
|
||||
{ worker += "<th>ITUz</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.PX)
|
||||
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(11);'>PX</th>"; }
|
||||
|
||||
if (window.opener.g_callsignLookups.lotwUseEnable == true && g_rosterSettings.columns.LoTW)
|
||||
{ worker += "<th >LoTW</th>"; }
|
||||
|
||||
if (window.opener.g_callsignLookups.eqslUseEnable == true && g_rosterSettings.columns.eQSL)
|
||||
{ worker += "<th >eQSL</th>"; }
|
||||
|
||||
if (window.opener.g_callsignLookups.oqrsUseEnable == true && g_rosterSettings.columns.OQRS)
|
||||
{ worker += "<th >OQRS</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.Spot)
|
||||
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(13);' >Spot</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.Life)
|
||||
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(12);' >Life</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.OAMS)
|
||||
{ worker += "<th title='Off-Air Message User' style='cursor:pointer;' onclick='showRosterBox(14);'>OAMS</th>"; }
|
||||
|
||||
if (g_rosterSettings.columns.Age)
|
||||
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(6);' >Age</th></thead>"; }
|
||||
|
||||
return worker
|
||||
}
|
||||
|
||||
function renderNormalRosterRow(callObj, showBands, showModes)
|
||||
{
|
||||
let thisCall = callObj.DEcall;
|
||||
let acks = window.opener.g_acknowledgedCalls;
|
||||
let grid = callObj.grid.length > 1 ? callObj.grid.substr(0, 4) : "-";
|
||||
|
||||
let geo = window.opener.g_worldGeoData[window.opener.g_dxccToGeoData[callObj.dxcc]];
|
||||
let cqzone = grid in window.opener.g_gridToCQZone ? window.opener.g_gridToCQZone[grid].join(", ") : "-";
|
||||
let ituzone = grid in window.opener.g_gridToITUZone ? window.opener.g_gridToITUZone[grid].join(", ") : "-";
|
||||
|
||||
let spotString = "";
|
||||
if (g_rosterSettings.columns.Spot && callObj.qrz == false)
|
||||
{
|
||||
spotString = getSpotString(callObj);
|
||||
}
|
||||
|
||||
let thisHash = thisCall + callObj.band + callObj.mode;
|
||||
let callStr = thisCall.formatCallsign()
|
||||
if (acks[thisCall])
|
||||
{
|
||||
callStr = `${callStr} <span class='acknowledged'><img class='ackBadge' src='${acks[thisCall].badge}'></span>`
|
||||
callObj.awardReason += ` - ${acks[thisCall].message}`
|
||||
}
|
||||
|
||||
let worker = "<tbody><tr id='" + thisHash + "'>";
|
||||
|
||||
worker +=
|
||||
"<td title='" +
|
||||
callObj.awardReason +
|
||||
"' name='Callsign' align=left " +
|
||||
callObj.style.call +
|
||||
" onClick='initiateQso(\"" +
|
||||
thisCall +
|
||||
callObj.band +
|
||||
callObj.mode +
|
||||
"\")'>" +
|
||||
callStr +
|
||||
"</td>";
|
||||
|
||||
if (showBands)
|
||||
{
|
||||
worker +=
|
||||
"<td style='color:#" +
|
||||
window.opener.g_pskColors[callObj.band] +
|
||||
"' >" +
|
||||
callObj.band +
|
||||
"</td>";
|
||||
}
|
||||
if (showModes)
|
||||
{
|
||||
let color = "888888";
|
||||
if (callObj.mode in g_modeColors)
|
||||
{ color = g_modeColors[callObj.mode]; }
|
||||
worker +=
|
||||
"<td style='color:#" + color + "' >" + callObj.mode + "</td>";
|
||||
}
|
||||
|
||||
worker +=
|
||||
"<td " +
|
||||
callObj.style.grid +
|
||||
" onClick='centerOn(\"" +
|
||||
grid +
|
||||
"\")' >" +
|
||||
grid +
|
||||
"</td>";
|
||||
if (g_rosterSettings.columns.Calling)
|
||||
{
|
||||
let lookString = callObj.CQ ? "name='CQ'" : "name='Calling'";
|
||||
worker +=
|
||||
"<td " +
|
||||
callObj.style.calling +
|
||||
" " +
|
||||
lookString +
|
||||
">" +
|
||||
callObj.DXcall.formatCallsign() +
|
||||
"</td>";
|
||||
}
|
||||
if (g_rosterSettings.columns.Msg)
|
||||
{ worker += "<td>" + callObj.msg + "</td>"; }
|
||||
|
||||
if (g_rosterSettings.columns.DXCC)
|
||||
{
|
||||
worker +=
|
||||
"<td title='" + window.opener.g_worldGeoData[window.opener.g_dxccToGeoData[callObj.dxcc]].pp +
|
||||
"' name='DXCC (" +
|
||||
callObj.dxcc +
|
||||
")' " +
|
||||
callObj.style.dxcc +
|
||||
">" +
|
||||
window.opener.g_dxccToAltName[callObj.dxcc] + "</td>";
|
||||
}
|
||||
if (g_rosterSettings.columns.Flag)
|
||||
{
|
||||
worker +=
|
||||
"<td align='center' style='margin:0;padding:0'><img style='padding-top:3px' src='./img/flags/16/" +
|
||||
geo.flag +
|
||||
"'></td>";
|
||||
}
|
||||
if (g_rosterSettings.columns.State)
|
||||
{
|
||||
worker +=
|
||||
"<td align='center' " +
|
||||
callObj.style.state +
|
||||
" >" +
|
||||
(callObj.state ? callObj.state.substr(3) : "") +
|
||||
"</td>";
|
||||
}
|
||||
if (g_rosterSettings.columns.County)
|
||||
{
|
||||
worker +=
|
||||
"<td align='center' " +
|
||||
callObj.style.cnty +
|
||||
" " +
|
||||
(callObj.cnty
|
||||
? (callObj.qual
|
||||
? ""
|
||||
: "title='ZIP Code matches multiple counties, click to do a full lookup' " +
|
||||
"onClick='window.opener.lookupCallsign(\"" +
|
||||
thisCall +
|
||||
"\",\"" +
|
||||
grid +
|
||||
"\")'"
|
||||
)
|
||||
: "") +
|
||||
">" +
|
||||
(callObj.cnty
|
||||
? (callObj.qual ? "" : "¿ ") +
|
||||
window.opener.g_cntyToCounty[callObj.cnty] +
|
||||
(callObj.qual ? "" : " ?")
|
||||
: "") +
|
||||
"</td>";
|
||||
}
|
||||
if (g_rosterSettings.columns.Cont)
|
||||
{
|
||||
worker +=
|
||||
"<td align='center' " +
|
||||
callObj.style.cont +
|
||||
" >" +
|
||||
(callObj.cont ? callObj.cont : "") +
|
||||
"</td>";
|
||||
}
|
||||
|
||||
if (g_rosterSettings.columns.dB)
|
||||
{
|
||||
worker +=
|
||||
"<td style='color:#DD44DD'><b>" +
|
||||
callObj.RSTsent +
|
||||
"</b></td>";
|
||||
}
|
||||
if (g_rosterSettings.columns.Freq)
|
||||
{ worker += "<td style='color:#00FF00'>" + callObj.delta + "</td>"; }
|
||||
if (g_rosterSettings.columns.DT)
|
||||
{ worker += "<td style='color:#1E90FF'>" + callObj.dt + "</td>"; }
|
||||
if (g_rosterSettings.columns.Dist)
|
||||
{
|
||||
worker +=
|
||||
"<td style='color:cyan'>" +
|
||||
parseInt(
|
||||
callObj.distance *
|
||||
MyCircle.validateRadius(window.opener.distanceUnit.value)
|
||||
) +
|
||||
"</td>";
|
||||
}
|
||||
if (g_rosterSettings.columns.Azim)
|
||||
{
|
||||
worker +=
|
||||
"<td style='color:yellow'>" +
|
||||
parseInt(callObj.heading) +
|
||||
"</td>";
|
||||
}
|
||||
|
||||
if (g_rosterSettings.columns.CQz)
|
||||
{
|
||||
worker +=
|
||||
"<td name='CQz' " +
|
||||
callObj.style.cqz +
|
||||
">" +
|
||||
callObj.cqza.join(",") +
|
||||
"</td>";
|
||||
}
|
||||
if (g_rosterSettings.columns.ITUz)
|
||||
{
|
||||
worker +=
|
||||
"<td name='ITUz'" +
|
||||
callObj.style.ituz +
|
||||
">" +
|
||||
callObj.ituza.join(",") +
|
||||
"</td>";
|
||||
}
|
||||
|
||||
if (g_rosterSettings.columns.PX)
|
||||
{
|
||||
worker +=
|
||||
"<td " +
|
||||
callObj.style.px +
|
||||
">" +
|
||||
(callObj.px ? callObj.px : "") +
|
||||
"</td>";
|
||||
}
|
||||
|
||||
if (
|
||||
window.opener.g_callsignLookups.lotwUseEnable == true &&
|
||||
g_rosterSettings.columns.LoTW
|
||||
)
|
||||
{
|
||||
if (thisCall in window.opener.g_lotwCallsigns)
|
||||
{
|
||||
if (g_rosterSettings.maxLoTW < 27)
|
||||
{
|
||||
let months = (g_day - window.opener.g_lotwCallsigns[thisCall]) / 30;
|
||||
if (months > g_rosterSettings.maxLoTW)
|
||||
{
|
||||
worker +=
|
||||
"<td style='color:yellow' align='center' title='Has not uploaded a QSO in " +
|
||||
Number(months).toYM() +
|
||||
"'>?</td>";
|
||||
}
|
||||
else
|
||||
{
|
||||
worker +=
|
||||
"<td style='color:#0F0' align='center' title=' Last Upload " +
|
||||
window.opener.userDayString(
|
||||
window.opener.g_lotwCallsigns[thisCall] * 86400000
|
||||
) +
|
||||
"'>✔</td>";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
worker +=
|
||||
"<td style='color:#0F0' align='center' title=' Last Upload " +
|
||||
window.opener.userDayString(
|
||||
window.opener.g_lotwCallsigns[thisCall] * 86400000
|
||||
) +
|
||||
"'>✔</td>";
|
||||
}
|
||||
}
|
||||
else worker += "<td></td>";
|
||||
}
|
||||
if (
|
||||
window.opener.g_callsignLookups.eqslUseEnable == true &&
|
||||
g_rosterSettings.columns.eQSL
|
||||
)
|
||||
{
|
||||
worker +=
|
||||
"<td style='color:#0F0;' align='center'>" +
|
||||
(thisCall in window.opener.g_eqslCallsigns ? "✔" : "") +
|
||||
"</td>";
|
||||
}
|
||||
if (
|
||||
window.opener.g_callsignLookups.oqrsUseEnable == true &&
|
||||
g_rosterSettings.columns.OQRS
|
||||
)
|
||||
{
|
||||
worker +=
|
||||
"<td style='color:#0F0;' align='center'>" +
|
||||
(thisCall in window.opener.g_oqrsCallsigns ? "✔" : "") +
|
||||
"</td>";
|
||||
}
|
||||
|
||||
if (g_rosterSettings.columns.Spot)
|
||||
{
|
||||
worker +=
|
||||
"<td style='color:#EEE;' class='spotCol' id='sp" +
|
||||
thisCall +
|
||||
callObj.band +
|
||||
callObj.mode +
|
||||
"'>" +
|
||||
spotString +
|
||||
"</td>";
|
||||
}
|
||||
if (g_rosterSettings.columns.Life)
|
||||
{
|
||||
worker +=
|
||||
"<td style='color:#EEE;' class='lifeCol' id='lm" +
|
||||
thisCall +
|
||||
callObj.band +
|
||||
callObj.mode +
|
||||
"'>" +
|
||||
(timeNowSec() - callObj.life).toDHMS() +
|
||||
"</td>";
|
||||
}
|
||||
|
||||
if (g_rosterSettings.columns.OAMS)
|
||||
{
|
||||
if (callObj.style.gt != 0)
|
||||
{
|
||||
if (callObj.reason.includes("oams"))
|
||||
{
|
||||
worker +=
|
||||
"<td align='center' style='margin:0;padding:0;cursor:pointer;background-clip:content-box;box-shadow: 0 0 4px 4px inset #2222FFFF;' onClick='openChatToCid(\"" +
|
||||
callObj.style.gt +
|
||||
"\")'><img height='16px' style='' src='./img/gt_chat.png'></td>";
|
||||
}
|
||||
else
|
||||
{
|
||||
worker +=
|
||||
"<td align='center' style='margin:0;padding:0;cursor:pointer;' onClick='openChatToCid(\"" +
|
||||
callObj.style.gt +
|
||||
"\")'><img height='16px' style='' src='./img/gt_chat.png'></td>";
|
||||
}
|
||||
}
|
||||
else worker += "<td></td>";
|
||||
}
|
||||
|
||||
if (g_rosterSettings.columns.Age)
|
||||
{
|
||||
worker +=
|
||||
"<td style='color:#EEE' class='timeCol' id='tm" +
|
||||
thisCall +
|
||||
callObj.band +
|
||||
callObj.mode +
|
||||
"'>" +
|
||||
(timeNowSec() - callObj.age).toDHMS() +
|
||||
"</td>";
|
||||
}
|
||||
|
||||
worker += "</tr></tbody>";
|
||||
|
||||
return worker;
|
||||
}
|
||||
|
||||
function renderNormalRosterFooter()
|
||||
{
|
||||
return "</table>";
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
function renderRoster(callRoster, rosterSettings)
|
||||
{
|
||||
// eQSL - function
|
||||
if (window.opener.g_callsignLookups.eqslUseEnable == true) useseQSLDiv.style.display = "";
|
||||
else useseQSLDiv.style.display = "none";
|
||||
|
||||
// OQRS - function
|
||||
if (window.opener.g_callsignLookups.oqrsUseEnable == true) usesOQRSDiv.style.display = "";
|
||||
else usesOQRSDiv.style.display = "none";
|
||||
|
||||
// dealing with spots
|
||||
if (g_rosterSettings.columns.Spot == true) onlySpotDiv.style.display = "";
|
||||
else onlySpotDiv.style.display = "none";
|
||||
|
||||
// callmode (all or only new)
|
||||
if (rosterSettings.callMode == "all") allOnlyNewDiv.style.display = "";
|
||||
else allOnlyNewDiv.style.display = "none";
|
||||
|
||||
// Show the roster count in the window title
|
||||
|
||||
// let visibleCallList = callRoster.filter(entry => entry.tx);
|
||||
|
||||
let visibleCallList = [];
|
||||
let band =
|
||||
window.opener.g_appSettings.gtBandFilter == "auto"
|
||||
? window.opener.g_appSettings.myBand
|
||||
: window.opener.g_appSettings.gtBandFilter.length == 0
|
||||
? ""
|
||||
: window.opener.g_appSettings.gtBandFilter;
|
||||
for (entry in callRoster)
|
||||
{
|
||||
// entry should populate in general
|
||||
if (callRoster[entry].tx)
|
||||
{
|
||||
// check setting for call roster clear on band change.
|
||||
// if true and band is current band, populate
|
||||
if (window.opener.g_appSettings.clearRosterOnBandChange)
|
||||
{
|
||||
if (callRoster[entry].callObj.band == band)
|
||||
{
|
||||
visibleCallList.push(callRoster[entry]);
|
||||
}
|
||||
}
|
||||
else if (!window.opener.g_appSettings.clearRosterOnBandChange)
|
||||
{
|
||||
visibleCallList.push(callRoster[entry]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let totalCount = Object.keys(callRoster).length;
|
||||
let visibleCount = visibleCallList.length;
|
||||
let huntedCount = visibleCallList.filter(obj => Object.keys(obj.callObj.hunting).length > 0).length
|
||||
let countParts = [];
|
||||
|
||||
if (totalCount != visibleCount)
|
||||
{
|
||||
countParts.push(`${totalCount} heard`);
|
||||
}
|
||||
|
||||
countParts.push(`${visibleCount} in roster`);
|
||||
|
||||
if (huntedCount != visibleCount)
|
||||
{
|
||||
countParts.push(`${huntedCount} wanted`);
|
||||
}
|
||||
|
||||
window.document.title = `Call Roster: ${countParts.join(" • ")}`;
|
||||
|
||||
if (g_rosterSettings.compact == false)
|
||||
{
|
||||
visibleCallList.sort(r_sortFunction[g_rosterSettings.lastSortIndex]);
|
||||
if (g_rosterSettings.lastSortReverse == 1)
|
||||
{
|
||||
visibleCallList.reverse();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Age sort for now... make this happen Tag
|
||||
visibleCallList.sort(r_sortFunction[6]).reverse();
|
||||
}
|
||||
|
||||
let showBands = (Object.keys(rosterSettings.bands).length > 1) || g_rosterSettings.columns.Band;
|
||||
let showModes = (Object.keys(rosterSettings.modes).length > 1) || g_rosterSettings.columns.Mode;
|
||||
|
||||
let worker = g_rosterSettings.compact ? renderCompactRosterHeaders() : renderNormalRosterHeaders(showBands, showModes)
|
||||
|
||||
// Third loop: render all rows
|
||||
for (let x in visibleCallList)
|
||||
{
|
||||
let callObj = visibleCallList[x].callObj;
|
||||
|
||||
// TODO: This is filtering
|
||||
if (callObj.shouldAlert == false && rosterSettings.onlyHits == true && callObj.qrz == false)
|
||||
{ continue; }
|
||||
|
||||
let thisCall = callObj.DEcall;
|
||||
|
||||
if (thisCall.match("^[A-Z][0-9][A-Z](/w+)?$"))
|
||||
{ callObj.style.call = "class='oneByOne'"; }
|
||||
if (thisCall == window.opener.g_instances[callObj.instance].status.DXcall)
|
||||
{
|
||||
if (window.opener.g_instances[callObj.instance].status.TxEnabled == 1)
|
||||
{
|
||||
callObj.style.call = "class='dxCalling'";
|
||||
}
|
||||
else
|
||||
{
|
||||
callObj.style.call = "class='dxCaller'";
|
||||
}
|
||||
}
|
||||
|
||||
worker += g_rosterSettings.compact ? renderCompactRosterRow(callObj) : renderNormalRosterRow(callObj, showBands, showModes)
|
||||
}
|
||||
|
||||
worker += g_rosterSettings.compact ? renderCompactRosterFooter() : renderNormalRosterFooter()
|
||||
RosterTable.innerHTML = worker;
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
function sendAlerts(callRoster, rosterSettings)
|
||||
{
|
||||
var dirPath = window.opener.g_scriptDir;
|
||||
var scriptExists = false;
|
||||
var script = "cr-alert.sh";
|
||||
|
||||
var shouldAlert = 0;
|
||||
|
||||
for (entry in callRoster)
|
||||
{
|
||||
var callObj = callRoster[entry].callObj;
|
||||
|
||||
// chrbayer: what does the tx field mean? no alerts are generated (at all) if this is in place...
|
||||
// if (!callObj.tx) continue;
|
||||
|
||||
// TODO: Get rid of realtime
|
||||
if (g_rosterSettings.realtime == false)
|
||||
{
|
||||
var call = callObj.DEcall;
|
||||
g_scriptReport[call] = Object.assign({}, callObj);
|
||||
g_scriptReport[call].dxccName =
|
||||
window.opener.g_dxccToAltName[callObj.dxcc];
|
||||
g_scriptReport[call].distance = parseInt(
|
||||
callObj.distance *
|
||||
MyCircle.validateRadius(window.opener.distanceUnit.value)
|
||||
);
|
||||
|
||||
delete g_scriptReport[call].DEcall;
|
||||
g_scriptReport[call].rect = null;
|
||||
delete g_scriptReport[call].rect;
|
||||
delete g_scriptReport[call].style;
|
||||
delete g_scriptReport[call].wspr;
|
||||
delete g_scriptReport[call].qso;
|
||||
delete g_scriptReport[call].instance;
|
||||
|
||||
if (rosterSettings.callMode != "all")
|
||||
{
|
||||
g_scriptReport[call].shouldAlert = true;
|
||||
g_scriptReport[call].reason.push(g_rosterSettings.hunting);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
callObj.alerted == false &&
|
||||
rosterSettings.callMode == "all" &&
|
||||
callObj.shouldAlert == true
|
||||
)
|
||||
{
|
||||
callObj.alerted = true;
|
||||
shouldAlert++;
|
||||
}
|
||||
else if (callObj.alerted == false && rosterSettings.callMode != "all")
|
||||
{
|
||||
callObj.alerted = true;
|
||||
shouldAlert++;
|
||||
}
|
||||
|
||||
callObj.shouldAlert = false;
|
||||
}
|
||||
|
||||
// NOTE: Ring alerts if needed
|
||||
try
|
||||
{
|
||||
if (fs.existsSync(dirPath))
|
||||
{
|
||||
if (window.opener.g_platform == "windows")
|
||||
{
|
||||
script = "cr-alert.bat";
|
||||
}
|
||||
if (
|
||||
fs.existsSync(dirPath + script) &&
|
||||
g_rosterSettings.realtime == false
|
||||
)
|
||||
{
|
||||
scriptExists = true;
|
||||
scriptIcon.innerHTML =
|
||||
"<div class='buttonScript' onclick='window.opener.toggleCRScript();'>" +
|
||||
(window.opener.g_crScript == 1
|
||||
? "<font color='lightgreen'>Script Enabled</font>"
|
||||
: "<font color='yellow'>Script Disabled</font>") +
|
||||
"</div>";
|
||||
scriptIcon.style.display = "block";
|
||||
}
|
||||
else
|
||||
{
|
||||
scriptIcon.style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
if (shouldAlert > 0)
|
||||
{
|
||||
if (window.opener.g_classicAlerts.huntRoster == true)
|
||||
{
|
||||
var notify = window.opener.huntRosterNotify.value;
|
||||
if (notify == "0")
|
||||
{
|
||||
var media = window.opener.huntRosterNotifyMedia.value;
|
||||
if (media != "none") window.opener.playAlertMediaFile(media);
|
||||
}
|
||||
else if (notify == "1")
|
||||
{
|
||||
window.opener.speakAlertString(
|
||||
window.opener.huntRosterNotifyWord.value
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
g_rosterSettings.realtime == false &&
|
||||
scriptExists &&
|
||||
window.opener.g_crScript == 1
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
fs.writeFileSync(
|
||||
dirPath + "cr-alert.json",
|
||||
JSON.stringify(g_scriptReport, null, 2)
|
||||
);
|
||||
|
||||
var thisProc = dirPath + script;
|
||||
var cp = require("child_process");
|
||||
var child = cp.spawn(thisProc, [], {
|
||||
detached: true,
|
||||
cwd: dirPath.slice(0, -1),
|
||||
stdio: ["ignore", "ignore", "ignore"]
|
||||
});
|
||||
child.unref();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
conosle.log(e);
|
||||
}
|
||||
g_scriptReport = Object();
|
||||
}
|
||||
else g_scriptReport = Object();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// GridTracker Copyright © 2021 GridTracker.org
|
||||
// GridTracker Copyright © 2022 GridTracker.org
|
||||
// All rights reserved.
|
||||
// See LICENSE for more information.
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "GridTracker",
|
||||
"product_string_do_not_use": "gridtracker",
|
||||
"version": "1.21.0928",
|
||||
"version": "1.21.1212",
|
||||
"betaVersion": "",
|
||||
"description": "GridTracker, an amateur radio companion",
|
||||
"author": "Stephen Loomis (N0TTL) and GridTracker.org",
|
||||
|
@ -31,7 +31,7 @@
|
|||
],
|
||||
"mac": {
|
||||
"icon": "gridview.icns",
|
||||
"copyright": "Copyright (c) 2021 GridTracker.org",
|
||||
"copyright": "Copyright (c) 2022 GridTracker.org",
|
||||
"plistStrings": {
|
||||
"CFBundleIdentifier": "org.gridtracker.gridtracker",
|
||||
"CFBundleDocumentTypes": []
|
||||
|
@ -39,7 +39,7 @@
|
|||
},
|
||||
"win": {
|
||||
"icon": "gridview.ico",
|
||||
"copyright": "Copyright (c) 2021 GridTracker.org"
|
||||
"copyright": "Copyright (c) 2022 GridTracker.org"
|
||||
},
|
||||
"nsis": {
|
||||
"installDirectory": "$PROGRAMFILES\\${_APPNAME}",
|
||||
|
|
|
@ -65,7 +65,7 @@ VIAddVersionKey CompanyName "${COMPANY}"
|
|||
VIAddVersionKey CompanyWebsite "${URL}"
|
||||
VIAddVersionKey FileVersion "${VERSION}"
|
||||
VIAddVersionKey FileDescription "An Amateur Radio Community"
|
||||
VIAddVersionKey LegalCopyright "2021 Gridtracker.org"
|
||||
VIAddVersionKey LegalCopyright "2022 Gridtracker.org"
|
||||
InstallDirRegKey HKLM "${REGKEY}" Path
|
||||
ShowUninstDetails nevershow
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue