From f0508b58669efc88ce38b7cd598a8f7d31a1ab0a Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Thu, 24 Jun 2021 11:06:31 -0500 Subject: [PATCH 01/60] some notes that might aid in refactoring --- package.nw/lib/roster.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/package.nw/lib/roster.js b/package.nw/lib/roster.js index d740b75..0c49fe5 100644 --- a/package.nw/lib/roster.js +++ b/package.nw/lib/roster.js @@ -436,6 +436,8 @@ function viewRoster() var bands = Object(); var modes = Object(); + // can the following block where we figure out how the roster is being used + // be a function itself that we can call in at the start of this? var callMode = g_rosterSettings.callsign; var onlyHits = false; var isAwardTracker = false; @@ -452,12 +454,18 @@ function viewRoster() isAwardTracker = true; g_rosterSettings.huntNeed = "confirmed"; } - + // this appears to be determine if we should show the OAMS collumn + // if the user is not in offline mode and has OAMS enabled, this could + // be it's own function maybe? var 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 = ""; @@ -479,18 +487,24 @@ function viewRoster() maxLoTWView.style.display = "none"; } + // 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 (callMode == "all") allOnlyNewDiv.style.display = ""; else allOnlyNewDiv.style.display = "none"; + // hunting mode - can this be comibined with the roster mode stuff on + // on line 441 above in that function or be it's own? var huntIndex, workedIndex, layeredMode; if (g_rosterSettings.huntNeed == "mixed") { @@ -520,6 +534,7 @@ function viewRoster() var now = timeNowSec(); // First loop, exclude calls, mostly based on "Exceptions" settings + // this whole section is full of individual if's that could be broken out for (var callHash in callRoster) { var entry = callRoster[callHash]; @@ -879,6 +894,8 @@ function viewRoster() } } + // these vars, do they rely on anything between the top and here? + // if not could they be put in the var list at the beginning? var hasGtPin = false; var newCallList = Array(); From 0b91db3d47028e4ffed6600fe8d6ab9a7b9deee3 Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Thu, 24 Jun 2021 18:04:46 -0500 Subject: [PATCH 02/60] add array with exception test function names, need to create functions yet --- package.nw/lib/roster.js | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/package.nw/lib/roster.js b/package.nw/lib/roster.js index 0c49fe5..f1db9bf 100644 --- a/package.nw/lib/roster.js +++ b/package.nw/lib/roster.js @@ -389,6 +389,38 @@ var r_sortFunction = [ myContCompare ]; +var r_excptTest = [ + timeChk, + crEnable, + blockedCall, + blockedFrom, + blcokedDXCC, + cqOnly, + useRegex, + reqGrid, + minDB, + maxDT, + minFreq, + maxFreq, + noMsg, + onlyMesg, + myDXCC, + lotwUse, + eqslUse, + oqrsUse, + noMyCQDX, + callWorked, + callConfirmed, + huntGrid, + huntDXCC, + huntDXCCs, + huntWPX, + huntCQ, + huntITU, + huntUSStates, + huntUSState +] + function showRosterBox(sortIndex) { if (g_rosterSettings.lastSortIndex != sortIndex) @@ -454,7 +486,7 @@ function viewRoster() isAwardTracker = true; g_rosterSettings.huntNeed = "confirmed"; } - // this appears to be determine if we should show the OAMS collumn + // 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? var canMsg = @@ -745,7 +777,6 @@ function viewRoster() entry.tx = false; continue; } - continue; } @@ -797,7 +828,6 @@ function viewRoster() entry.tx = false; continue; } - continue; } From a767d9dc35d2af6853268070b14c5da316983cc2 Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Thu, 24 Jun 2021 18:46:42 -0500 Subject: [PATCH 03/60] missing comma line 422 --- package.nw/lib/roster.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.nw/lib/roster.js b/package.nw/lib/roster.js index f1db9bf..d015832 100644 --- a/package.nw/lib/roster.js +++ b/package.nw/lib/roster.js @@ -419,7 +419,7 @@ var r_excptTest = [ huntITU, huntUSStates, huntUSState -] +]; function showRosterBox(sortIndex) { From f554d508622924833d3bb23789ad54e055cebc97 Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 17:26:44 -0500 Subject: [PATCH 04/60] big roster refactor - starting Co-authored-by: Sebastian Delmont Matthew Chambers --- package.nw/lib/roster.js | 1814 +---------------- .../lib/roster/prepareRosterSettings.js | 83 + package.nw/lib/roster/processFiltering.js | 363 ++++ package.nw/lib/roster/processHunting.js | 706 +++++++ .../lib/roster/processRosterFiltering.js | 369 ++++ package.nw/lib/roster/processRosterHunting.js | 700 +++++++ package.nw/lib/roster/renderCompactRoster.js | 55 + package.nw/lib/roster/renderNormalRoster.js | 400 ++++ package.nw/lib/roster/renderRoster.js | 102 + package.nw/lib/roster/sendAlerts.js | 135 ++ 10 files changed, 2918 insertions(+), 1809 deletions(-) create mode 100644 package.nw/lib/roster/prepareRosterSettings.js create mode 100644 package.nw/lib/roster/processFiltering.js create mode 100644 package.nw/lib/roster/processHunting.js create mode 100644 package.nw/lib/roster/processRosterFiltering.js create mode 100644 package.nw/lib/roster/processRosterHunting.js create mode 100644 package.nw/lib/roster/renderCompactRoster.js create mode 100644 package.nw/lib/roster/renderNormalRoster.js create mode 100644 package.nw/lib/roster/renderRoster.js create mode 100644 package.nw/lib/roster/sendAlerts.js diff --git a/package.nw/lib/roster.js b/package.nw/lib/roster.js index d015832..d7997f6 100644 --- a/package.nw/lib/roster.js +++ b/package.nw/lib/roster.js @@ -465,1815 +465,11 @@ function processRoster(roster) function viewRoster() { - var bands = Object(); - var modes = Object(); - - // can the following block where we figure out how the roster is being used - // be a function itself that we can call in at the start of this? - var callMode = g_rosterSettings.callsign; - var onlyHits = false; - var isAwardTracker = false; - - if (callMode == "hits") - { - callMode = "all"; - onlyHits = true; - } - if (referenceNeed.value == LOGBOOK_AWARD_TRACKER) - { - callMode = "all"; - onlyHits = false; - 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? - var 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"; - } - - // 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 (callMode == "all") allOnlyNewDiv.style.display = ""; - else allOnlyNewDiv.style.display = "none"; - - // hunting mode - can this be comibined with the roster mode stuff on - // on line 441 above in that function or be it's own? - var huntIndex, workedIndex, layeredMode; - if (g_rosterSettings.huntNeed == "mixed") - { - huntIndex = g_confirmed; - workedIndex = g_worked; - layeredMode = LAYERED_MODE_FOR[String(g_rosterSettings.reference)]; - } - else if (g_rosterSettings.huntNeed == "worked") - { - huntIndex = g_worked; - workedIndex = false; - layeredMode = false; - } - else if (g_rosterSettings.huntNeed == "confirmed") - { - huntIndex = g_confirmed; - workedIndex = g_worked; - layeredMode = false; - } - else - { - huntIndex = false; - workedIndex = false; - layeredMode = false; - } - - var now = timeNowSec(); - - // First loop, exclude calls, mostly based on "Exceptions" settings - // this whole section is full of individual if's that could be broken out - for (var callHash in callRoster) - { - var entry = callRoster[callHash]; - var callObj = entry.callObj; - - var call = entry.DEcall; - - entry.tx = true; - callObj.shouldAlert = false; - callObj.reason = Array(); - callObj.awardReason = "Callsign"; - - if (now - callObj.age > window.opener.g_mapSettings.rosterTime) - { - entry.tx = false; - entry.alerted = false; - callObj.qrz = false; - callObj.reset = true; - 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.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) - { - var 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 (callMode != "all") - { - if (entry.DXcall == "CQ DX" && callObj.dxcc == window.opener.g_myDXCC) - { - entry.tx = false; - continue; - } - - var hash = hashMaker(call, callObj, g_rosterSettings.reference); - if (callMode == "worked" && hash in g_worked.call) - { - entry.tx = false; - continue; - } - if (callMode == "confirmed" && hash in g_confirmed.call) - { - entry.tx = false; - continue; - } - - if (g_rosterSettings.hunting == "grid") - { - var hash = hashMaker(callObj.grid.substr(0, 4), - callObj, g_rosterSettings.reference); - if (huntIndex && hash in huntIndex.grid) - { - entry.tx = false; - continue; - } - if (callObj.grid.length == 0) - { - entry.tx = false; - continue; - } - continue; - } - if (g_rosterSettings.hunting == "dxcc") - { - var hash = hashMaker(String(callObj.dxcc), - callObj, g_rosterSettings.reference); - - if (huntIndex && (hash in huntIndex.dxcc)) - { - entry.tx = false; - continue; - } - 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; - } - var hash = hashMaker(String(callObj.px), - callObj, g_rosterSettings.reference); - - if (huntIndex && (hash in huntIndex.px)) - { - entry.tx = false; - continue; - } - - continue; - } - - if (g_rosterSettings.hunting == "cq") - { - var huntTotal = callObj.cqza.length; - if (huntTotal == 0 || !huntIndex) - { - entry.tx = false; - continue; - } - var huntFound = 0; - for (index in callObj.cqza) - { - var hash = hashMaker(callObj.cqza[index], callObj, g_rosterSettings.reference); - - if (hash in huntIndex.cqz) huntFound++; - } - if (huntFound == huntTotal) - { - entry.tx = false; - continue; - } - continue; - } - - if (g_rosterSettings.hunting == "itu") - { - var huntTotal = callObj.ituza.length; - if (huntTotal == 0 || !huntIndex) - { - entry.tx = false; - continue; - } - var huntFound = 0; - for (index in callObj.ituza) - { - var hash = hashMaker(callObj.ituza[index], callObj, g_rosterSettings.reference); - - if (hash in 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) - { - var state = callObj.state; - var finalDxcc = callObj.dxcc; - if (finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6) - { - if (state in window.opener.g_StateData) - { - var hash = hashMaker(state, callObj, g_rosterSettings.reference); - - if (huntIndex && hash in 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 (isAwardTracker) - { - var tx = false; - var baseHash = hashMaker("", callObj, g_rosterSettings.reference); - - for (var award in g_awardTracker) - { - if (g_awardTracker[award].enable) - { - tx = testAward(award, callObj, baseHash); - if (tx) - { - var x = g_awardTracker[award]; - callObj.awardReason = - g_awards[x.sponsor].awards[x.name].tooltip + - " (" + - g_awards[x.sponsor].sponsor + - ")"; - - break; - } - } - } - entry.tx = tx; - } - } - - // these vars, do they rely on anything between the top and here? - // if not could they be put in the var list at the beginning? - var hasGtPin = false; - - var newCallList = Array(); - var inversionAlpha = "DD"; - var row = "#000000"; - var bold = "#000000;font-weight: bold;"; - var unconf = "background-clip:padding-box;box-shadow: 0 0 7px 3px inset "; - var layeredAlpha = "77"; - var layeredInversionAlpha = "66"; - var layeredUnconf = "background-clip:padding-box;box-shadow: 0 0 4px 2px inset "; - var layeredUnconfAlpha = "AA"; - - // Second loop, hunting and highlighting - for (var callHash in callRoster) - { - var entry = callRoster[callHash]; - var 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, var it through - - 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' - var workHashSuffix, layeredHashSuffix; - if (layeredMode) - { - workHashSuffix = hashMaker("", callObj, layeredMode); - layeredHashSuffix = hashMaker("", callObj, g_rosterSettings.reference); - } - else - { - workHashSuffix = hashMaker("", callObj, g_rosterSettings.reference); - layeredHashSuffix = false - } - var workHash = workHashSuffix; // TODO: Remove after replacing all occurrences with Suffix - - var callsign = entry.DEcall; - - callObj.hunting = {} - callObj.callFlags = {} - - var colorObject = Object(); - - var callPointer = callObj.CQ == true ? "cursor:pointer" : ""; - - var didWork = false; - - var call = "#FFFF00"; - var grid = "#00FFFF"; - var calling = "#90EE90"; - var dxcc = "#FFA500"; - var state = "#90EE90"; - var cnty = "#CCDD00"; - var cont = "#00DDDD"; - var cqz = "#DDDDDD"; - var ituz = "#DDDDDD"; - var wpx = "#FFFF00"; - - hasGtPin = false; - var shouldAlert = false; - var callBg, gridBg, callingBg, dxccBg, stateBg, cntyBg, contBg, cqzBg, ituzBg, wpxBg, gtBg; - var 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 = - ""; - - var hash = callsign + workHashSuffix; - var 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 (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) - { - var hash = callsign + workHashSuffix; - var layeredHash = layeredMode && (callsign + layeredHashSuffix) - - if (huntIndex && !(hash in huntIndex.call)) - { - shouldAlert = true; - - callObj.reason.push("call"); - - if (workedIndex && hash in workedIndex.call) - { - if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in workedIndex.call) - // { - // callObj.hunting.call = "worked-and-mixed-worked"; - // callConf = `${layeredUnconf}${call}${layeredAlpha};`; - // } - else - { - callObj.hunting.call = "worked"; - callConf = `${unconf}${call}${inversionAlpha};`; - } - } - else - { - if (layeredMode && layeredHash in huntIndex.call) - { - callObj.hunting.call = "mixed"; - callBg = `${call}${layeredAlpha};`; - call = bold; - } - else if (layeredMode && layeredHash in 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) - { - var hash = callObj.grid.substr(0, 4) + workHashSuffix; - var layeredHash = layeredMode && (callObj.grid.substr(0, 4) + layeredHashSuffix) - - if (huntIndex && !(hash in huntIndex.grid)) - { - shouldAlert = true; - - callObj.reason.push("grid"); - - if (workedIndex && hash in workedIndex.grid) - { - if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.grid) - { - callObj.hunting.grid = "mixed"; - gridBg = `${grid}${layeredAlpha};`; - grid = bold; - } - else if (layeredMode && layeredHash in 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) - { - var hash = String(callObj.dxcc) + workHashSuffix; - var layeredHash = layeredMode && (String(callObj.dxcc) + layeredHashSuffix) - - if (huntIndex && !(hash in huntIndex.dxcc)) - { - shouldAlert = true; - - callObj.reason.push("dxcc"); - - if (workedIndex && hash in workedIndex.dxcc) - { - if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.dxcc) - { - callObj.hunting.dxcc = "mixed"; - dxccBg = `${dxcc}${layeredAlpha};`; - dxcc = bold; - } - else if (layeredMode && layeredHash in 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) - { - var stateSearch = callObj.state; - var finalDxcc = callObj.dxcc; - if (finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6) - { - if (stateSearch in window.opener.g_StateData) - { - var hash = stateSearch + workHashSuffix; - var layeredHash = layeredMode && (stateSearch + layeredHashSuffix) - - if (huntIndex && !(hash in huntIndex.state)) - { - shouldAlert = true; - - callObj.reason.push("state"); - - if (workedIndex && hash in workedIndex.state) - { - if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.state) - { - callObj.hunting.state = "mixed"; - stateBg = `${state}${layeredAlpha};`; - state = bold; - } - else if (layeredMode && layeredHash in 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) - { - var finalDxcc = callObj.dxcc; - if ( - callObj.cnty && - (finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6 || finalDxcc == 202) && - callObj.cnty.length > 0 - ) - { - var hash = callObj.cnty + (layeredMode ? layeredHashSuffix : workHashSuffix); - - if ((huntIndex && !(hash in huntIndex.cnty)) || callObj.qual == false) - { - if (callObj.qual == false) - { - var counties = window.opener.g_zipToCounty[callObj.zipcode]; - var foundHit = false; - for (var cnt in counties) - { - var hh = counties[cnt] + workHash; - callObj.cnty = counties[cnt]; - if (huntIndex && !(hh in huntIndex.cnty)) - { - foundHit = true; - break; - } - } - if (foundHit) shouldAlert = true; - } - else - { - shouldAlert = true; - } - - if (shouldAlert) - { - callObj.reason.push("cnty"); - - if (workedIndex && hash in 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) - { - var huntTotal = callObj.cqza.length; - var huntFound = 0, layeredFound = 0, workedFound = 0, layeredWorkedFound = 0; - - for (index in callObj.cqza) - { - var hash = callObj.cqza[index] + workHashSuffix; - var layeredHash = layeredMode && (callObj.cqza[index] + layeredHashSuffix) - - if (huntIndex && hash in huntIndex.cqz) huntFound++; - if (layeredMode && layeredHash in huntIndex.cqz) layeredFound++; - if (workedIndex && hash in workedIndex.cqz) workedFound++; - if (layeredMode && layeredHash in workedIndex.cqz) layeredWorkedFound++; - } - if (huntFound != huntTotal) - { - shouldAlert = true; - callObj.reason.push("cqz"); - - if (workedIndex && workedFound == huntTotal) - { - if (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 (layeredMode && layeredFound == huntTotal) - { - callObj.hunting.cqz = "mixed"; - cqzBg = `${cqz}${layeredAlpha};`; - cqz = bold; - } - else if (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) - { - var huntTotal = callObj.ituza.length; - var huntFound = 0, layeredFound = 0, workedFound = 0, layeredWorkedFound = 0; - - for (index in callObj.ituza) - { - var hash = callObj.ituza[index] + workHashSuffix; - var layeredHash = layeredMode && (callObj.ituza[index] + layeredHashSuffix) - - if (huntIndex && hash in huntIndex.ituz) huntFound++; - if (layeredMode && layeredHash in huntIndex.ituz) layeredFound++; - if (workedIndex && hash in workedIndex.ituz) workedFound++; - if (layeredMode && layeredHash in workedIndex.ituz) layeredWorkedFound++; - } - if (huntFound != huntTotal) - { - shouldAlert = true; - callObj.reason.push("ituz"); - - if (workedIndex && workedFound == huntTotal) - { - if (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 (layeredMode && layeredFound == huntTotal) - { - callObj.hunting.ituz = "mixed"; - ituzBg = `${ituz}${layeredAlpha};`; - ituz = bold; - } - else if (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) - { - var hash = String(callObj.px) + workHashSuffix; - var layeredHash = layeredMode && (String(callObj.px) + layeredHashSuffix) - - if (huntIndex && !(hash in huntIndex.px)) - { - shouldAlert = true; - - callObj.reason.push("wpx"); - - if (workedIndex && hash in workedIndex.px) - { - if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.px) - { - callObj.hunting.wpx = "mixed"; - wpxBg = `${wpx}${layeredAlpha};`; - wpx = bold; - } - else if (layeredMode && layeredHash in 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) - { - var hash = String(callObj.cont) + workHashSuffix; - var layeredHash = layeredMode && (String(callObj.cont) + layeredHashSuffix) - - if (huntIndex && !(hash in huntIndex.cont)) - { - shouldAlert = true; - - callObj.reason.push("cont"); - - if (workedIndex && hash in workedIndex.cont) - { - if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.cont) - { - callObj.hunting.cont = "mixed"; - contBg = `${cont}${layeredAlpha};`; - cont = bold; - } - else if (layeredMode && layeredHash in 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 && g_rosterSettings.cqOnly == false) - { - 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 }; - } - - modes[callObj.mode] = true; - bands[callObj.band] = true; - - newCallList.push(callObj); - } - } - - // Show the roster count in the window title - - var totalCount = Object.keys(callRoster).length; - var visibleCount = newCallList.length; - var huntedCount = newCallList.filter(obj => Object.keys(obj.hunting).length > 0).length - var 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(" • ")}`; - - // Render the roster - - if (g_rosterSettings.compact == false) - { - newCallList.sort(r_sortFunction[g_rosterSettings.lastSortIndex]); - if (g_rosterSettings.lastSortReverse == 1) - { - newCallList.reverse(); - } - } - else - { - // Age sort for now... make this happen Tag - newCallList.sort(r_sortFunction[6]).reverse(); - } - - var showBands = (Object.keys(bands).length > 1) || g_rosterSettings.columns.Band; - var showModes = (Object.keys(modes).length > 1) || g_rosterSettings.columns.Mode; - - var worker = ""; - - // Render the table headers for the regular roster table - if (g_rosterSettings.compact == false) - { - worker = ""; - - worker += ""; - - if (showBands) - { worker += ""; } - - if (showModes) - { worker += ""; } - - worker += ""; - - if (g_rosterSettings.columns.Calling) - { worker += ""; } - - if (g_rosterSettings.columns.Msg) - { worker += ""; } - - if (g_rosterSettings.columns.DXCC) - { worker += ""; } - - if (g_rosterSettings.columns.Flag) - { worker += ""; } - - if (g_rosterSettings.columns.State) - { worker += ""; } - - if (g_rosterSettings.columns.County) - { worker += ""; } - - if (g_rosterSettings.columns.Cont) - { worker += ""; } - - if (g_rosterSettings.columns.dB) - { worker += ""; } - - if (g_rosterSettings.columns.Freq) - { worker += ""; } - - if (g_rosterSettings.columns.DT) - { worker += ""; } - - if (g_rosterSettings.columns.Dist) - { - worker += ""; - } - - if (g_rosterSettings.columns.Azim) - { worker += ""; } - - if (g_rosterSettings.columns.CQz) - { worker += ""; } - - if (g_rosterSettings.columns.ITUz) - { worker += ""; } - - if (g_rosterSettings.columns.PX) - { worker += ""; } - - if (window.opener.g_callsignLookups.lotwUseEnable == true && g_rosterSettings.columns.LoTW) - { worker += ""; } - - if (window.opener.g_callsignLookups.eqslUseEnable == true && g_rosterSettings.columns.eQSL) - { worker += ""; } - - if (window.opener.g_callsignLookups.oqrsUseEnable == true && g_rosterSettings.columns.OQRS) - { worker += ""; } - - if (g_rosterSettings.columns.Spot) - { worker += ""; } - - if (g_rosterSettings.columns.Life) - { worker += ""; } - - if (g_rosterSettings.columns.OAMS) - { worker += ""; } - - if (g_rosterSettings.columns.Age) - { worker += ""; } - } - // No headers for compact roster table - else - { - worker = "
"; - } - - var shouldAlert = 0; - - // Render all rows - for (var x in newCallList) - { - var callObj = newCallList[x]; - - if (callObj.shouldAlert == false && onlyHits == true && callObj.qrz == false) - { continue; } - - var spotString = ""; - if (g_rosterSettings.columns.Spot && callObj.qrz == false) - { - spotString = getSpotString(callObj); - if (g_rosterSettings.onlySpot && spotString == "") continue; - } - var grid = callObj.grid.length > 1 ? callObj.grid.substr(0, 4) : "-"; - - var geo = window.opener.g_worldGeoData[window.opener.g_dxccToGeoData[callObj.dxcc]]; - var cqzone = grid in window.opener.g_gridToCQZone ? window.opener.g_gridToCQZone[grid].join(", ") : "-"; - var ituzone = grid in window.opener.g_gridToITUZone ? window.opener.g_gridToITUZone[grid].join(", ") : "-"; - var 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'"; - } - } - - if (g_rosterSettings.compact == false) - { - var acks = window.opener.g_acknowledgedCalls - - var thisHash = thisCall + callObj.band + callObj.mode; - var callStr = thisCall.formatCallsign() - if (acks[thisCall]) - { - callStr = `${callStr} ` - callObj.awardReason += ` - ${acks[thisCall].message}` - } - - worker += "
"; - worker += - ""; - - if (showBands) - { - worker += - ""; - } - if (showModes) - { - var color = "888888"; - if (callObj.mode in g_modeColors) - { color = g_modeColors[callObj.mode]; } - worker += - ""; - } - - worker += - ""; - if (g_rosterSettings.columns.Calling) - { - var lookString = callObj.CQ ? "name='CQ'" : "name='Calling'"; - worker += - ""; - } - if (g_rosterSettings.columns.Msg) - { worker += ""; } - - if (g_rosterSettings.columns.DXCC) - { - worker += - ""; - } - if (g_rosterSettings.columns.Flag) - { - worker += - ""; - } - if (g_rosterSettings.columns.State) - { - worker += - ""; - } - if (g_rosterSettings.columns.County) - { - worker += - ""; - } - if (g_rosterSettings.columns.Cont) - { - worker += - ""; - } - - if (g_rosterSettings.columns.dB) - { - worker += - ""; - } - if (g_rosterSettings.columns.Freq) - { worker += ""; } - if (g_rosterSettings.columns.DT) - { worker += ""; } - if (g_rosterSettings.columns.Dist) - { - worker += - ""; - } - if (g_rosterSettings.columns.Azim) - { - worker += - ""; - } - - if (g_rosterSettings.columns.CQz) - { - worker += - ""; - } - if (g_rosterSettings.columns.ITUz) - { - worker += - ""; - } - - if (g_rosterSettings.columns.PX) - { - worker += - ""; - } - - if ( - window.opener.g_callsignLookups.lotwUseEnable == true && - g_rosterSettings.columns.LoTW - ) - { - if (thisCall in window.opener.g_lotwCallsigns) - { - if (g_rosterSettings.maxLoTW < 27) - { - var months = (g_day - window.opener.g_lotwCallsigns[thisCall]) / 30; - if (months > g_rosterSettings.maxLoTW) - { - worker += - ""; - } - else - { - worker += - ""; - } - } - else - { - worker += - ""; - } - } - else worker += ""; - } - if ( - window.opener.g_callsignLookups.eqslUseEnable == true && - g_rosterSettings.columns.eQSL - ) - { - worker += - ""; - } - if ( - window.opener.g_callsignLookups.oqrsUseEnable == true && - g_rosterSettings.columns.OQRS - ) - { - worker += - ""; - } - - if (g_rosterSettings.columns.Spot) - { - worker += - ""; - } - if (g_rosterSettings.columns.Life) - { - worker += - ""; - } - - if (g_rosterSettings.columns.OAMS) - { - if (callObj.style.gt != 0) - { - if (callObj.reason.includes("oams")) - { - worker += - ""; - } - else - { - worker += - ""; - } - } - else worker += ""; - } - - if (g_rosterSettings.columns.Age) - { - worker += - ""; - } - - worker += ""; - } - else - { - var tt = - callObj.RSTsent + - "㏈, " + - parseInt(callObj.dt * 100) + - "ms, " + - callObj.delta + - "hz" + - (callObj.grid.length ? ", " + callObj.grid : "") + - ", " + - (timeNowSec() - callObj.age).toDHMS(); - worker += - "
"; - worker += - "
" + - thisCall.formatCallsign() + - "
"; - worker += - "
" + - window.opener.g_dxccToAltName[callObj.dxcc] + - "
"; - worker += "
"; - } - - 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 (callMode != "all") - { - g_scriptReport[call].shouldAlert = true; - g_scriptReport[call].reason.push(g_rosterSettings.hunting); - } - } - - if ( - callObj.alerted == false && - callMode == "all" && - callObj.shouldAlert == true - ) - { - callObj.alerted = true; - shouldAlert++; - } - else if (callObj.alerted == false && callMode != "all") - { - callObj.alerted = true; - shouldAlert++; - } - - callObj.shouldAlert = false; - } - - if (g_rosterSettings.compact == false) - { - worker += "
CallsignBandModeGridCallingMsgDXCCFlagStateCountyContdBFreqDTDist(" + - window.opener.distanceUnit.value.toLowerCase() + ")AzimCQzITUzPXLoTWeQSLOQRSSpotLifeOAMSAge
" + - callStr + - "" + - callObj.band + - "" + callObj.mode + "" + - grid + - "" + - callObj.DXcall.formatCallsign() + - "" + callObj.msg + "" + - window.opener.g_dxccToAltName[callObj.dxcc] + "" + - (callObj.state ? callObj.state.substr(3) : "") + - "" + - (callObj.cnty - ? (callObj.qual ? "" : "~ ") + - window.opener.g_cntyToCounty[callObj.cnty] + - (callObj.qual ? "" : " ~") - : "") + - "" + - (callObj.cont ? callObj.cont : "") + - "" + - callObj.RSTsent + - "" + callObj.delta + "" + callObj.dt + "" + - parseInt( - callObj.distance * - MyCircle.validateRadius(window.opener.distanceUnit.value) - ) + - "" + - parseInt(callObj.heading) + - "" + - callObj.cqza.join(",") + - "" + - callObj.ituza.join(",") + - "" + - (callObj.px ? callObj.px : "") + - "?" + - (thisCall in window.opener.g_eqslCallsigns ? "✔" : "") + - "" + - (thisCall in window.opener.g_oqrsCallsigns ? "✔" : "") + - "" + - spotString + - "" + - (timeNowSec() - callObj.life).toDHMS() + - "" + - (timeNowSec() - callObj.age).toDHMS() + - "
"; - RosterTable.innerHTML = worker; - } - else - { - RosterTable.innerHTML = worker + ""; - } - - var dirPath = window.opener.g_scriptDir; - var scriptExists = false; - var script = "cr-alert.sh"; - - 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 = - "
" + - (window.opener.g_crScript == 1 - ? "Script Enabled" - : "Script Disabled") + - "
"; - 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(); - } + var rosterSettings = prepareRosterSettings(); + processRosterFiltering(callRoster, rosterSettings); + processRosterHunting(callRoster, rosterSettings); + renderRoster(callRoster, rosterSettings); + sendAlerts(callRoster, rosterSettings); } function realtimeRoster() diff --git a/package.nw/lib/roster/prepareRosterSettings.js b/package.nw/lib/roster/prepareRosterSettings.js new file mode 100644 index 0000000..5aa845b --- /dev/null +++ b/package.nw/lib/roster/prepareRosterSettings.js @@ -0,0 +1,83 @@ +function prepareRosterSettings() +{ + var 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 +} diff --git a/package.nw/lib/roster/processFiltering.js b/package.nw/lib/roster/processFiltering.js new file mode 100644 index 0000000..9d6c21e --- /dev/null +++ b/package.nw/lib/roster/processFiltering.js @@ -0,0 +1,363 @@ +function processRosterFiltering() +{ + // First loop, exclude calls, mostly based on "Exceptions" settings + // this whole section is full of individual if's that could be broken out + for (var callHash in callRoster) + { + var entry = callRoster[callHash]; + var callObj = entry.callObj; + + var call = entry.DEcall; + + entry.tx = true; + callObj.shouldAlert = false; + callObj.reason = Array(); + callObj.awardReason = "Callsign"; + + if (now - callObj.age > window.opener.g_mapSettings.rosterTime) + { + entry.tx = false; + entry.alerted = false; + callObj.qrz = false; + callObj.reset = true; + 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.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) + { + var 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 (callMode != "all") + { + if (entry.DXcall == "CQ DX" && callObj.dxcc == window.opener.g_myDXCC) + { + entry.tx = false; + continue; + } + + var hash = hashMaker(call, callObj, g_rosterSettings.reference); + if (callMode == "worked" && hash in g_worked.call) + { + entry.tx = false; + continue; + } + if (callMode == "confirmed" && hash in g_confirmed.call) + { + entry.tx = false; + continue; + } + + if (g_rosterSettings.hunting == "grid") + { + var hash = hashMaker(callObj.grid.substr(0, 4), + callObj, g_rosterSettings.reference); + if (huntIndex && hash in huntIndex.grid) + { + entry.tx = false; + continue; + } + if (callObj.grid.length == 0) + { + entry.tx = false; + continue; + } + continue; + } + if (g_rosterSettings.hunting == "dxcc") + { + var hash = hashMaker(String(callObj.dxcc), + callObj, g_rosterSettings.reference); + + if (huntIndex && (hash in huntIndex.dxcc)) + { + entry.tx = false; + continue; + } + 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; + } + var hash = hashMaker(String(callObj.px), + callObj, g_rosterSettings.reference); + + if (huntIndex && (hash in huntIndex.px)) + { + entry.tx = false; + continue; + } + + continue; + } + + if (g_rosterSettings.hunting == "cq") + { + var huntTotal = callObj.cqza.length; + if (huntTotal == 0 || !huntIndex) + { + entry.tx = false; + continue; + } + var huntFound = 0; + for (index in callObj.cqza) + { + var hash = hashMaker(callObj.cqza[index], callObj, g_rosterSettings.reference); + + if (hash in huntIndex.cqz) huntFound++; + } + if (huntFound == huntTotal) + { + entry.tx = false; + continue; + } + continue; + } + + if (g_rosterSettings.hunting == "itu") + { + var huntTotal = callObj.ituza.length; + if (huntTotal == 0 || !huntIndex) + { + entry.tx = false; + continue; + } + var huntFound = 0; + for (index in callObj.ituza) + { + var hash = hashMaker(callObj.ituza[index], callObj, g_rosterSettings.reference); + + if (hash in 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) + { + var state = callObj.state; + var finalDxcc = callObj.dxcc; + if (finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6) + { + if (state in window.opener.g_StateData) + { + var hash = hashMaker(state, callObj, g_rosterSettings.reference); + + if (huntIndex && hash in 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 (isAwardTracker) + { + var tx = false; + var baseHash = hashMaker("", callObj, g_rosterSettings.reference); + + for (var award in g_awardTracker) + { + if (g_awardTracker[award].enable) + { + tx = testAward(award, callObj, baseHash); + if (tx) + { + var 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; + } + } +} diff --git a/package.nw/lib/roster/processHunting.js b/package.nw/lib/roster/processHunting.js new file mode 100644 index 0000000..c569e08 --- /dev/null +++ b/package.nw/lib/roster/processHunting.js @@ -0,0 +1,706 @@ +function processHunting() +{ + // these vars, do they rely on anything between the top and here? + // if not could they be put in the var list at the beginning? + var hasGtPin = false; + + var newCallList = Array(); + var inversionAlpha = "DD"; + var row = "#000000"; + var bold = "#000000;font-weight: bold;"; + var unconf = "background-clip:padding-box;box-shadow: 0 0 7px 3px inset "; + var layeredAlpha = "77"; + var layeredInversionAlpha = "66"; + var layeredUnconf = "background-clip:padding-box;box-shadow: 0 0 4px 2px inset "; + var 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 (var callHash in callRoster) + { + var entry = callRoster[callHash]; + var 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, var 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' + var workHashSuffix, layeredHashSuffix; + if (layeredMode) + { + workHashSuffix = hashMaker("", callObj, layeredMode); + layeredHashSuffix = hashMaker("", callObj, g_rosterSettings.reference); + } + else + { + workHashSuffix = hashMaker("", callObj, g_rosterSettings.reference); + layeredHashSuffix = false + } + var workHash = workHashSuffix; // TODO: Remove after replacing all occurrences with Suffix + + var callsign = entry.DEcall; + + callObj.hunting = {} + callObj.callFlags = {} + + var colorObject = Object(); + + var callPointer = callObj.CQ == true ? "cursor:pointer" : ""; + + var didWork = false; + + var call = "#FFFF00"; + var grid = "#00FFFF"; + var calling = "#90EE90"; + var dxcc = "#FFA500"; + var state = "#90EE90"; + var cnty = "#CCDD00"; + var cont = "#00DDDD"; + var cqz = "#DDDDDD"; + var ituz = "#DDDDDD"; + var wpx = "#FFFF00"; + + hasGtPin = false; + var shouldAlert = false; + var callBg, gridBg, callingBg, dxccBg, stateBg, cntyBg, contBg, cqzBg, ituzBg, wpxBg, gtBg; + var 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 = + ""; + + var hash = callsign + workHashSuffix; + var 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 (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) + { + var hash = callsign + workHashSuffix; + var layeredHash = layeredMode && (callsign + layeredHashSuffix) + + if (huntIndex && !(hash in huntIndex.call)) + { + shouldAlert = true; + + callObj.reason.push("call"); + + if (workedIndex && hash in workedIndex.call) + { + if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in workedIndex.call) + // { + // callObj.hunting.call = "worked-and-mixed-worked"; + // callConf = `${layeredUnconf}${call}${layeredAlpha};`; + // } + else + { + callObj.hunting.call = "worked"; + callConf = `${unconf}${call}${inversionAlpha};`; + } + } + else + { + if (layeredMode && layeredHash in huntIndex.call) + { + callObj.hunting.call = "mixed"; + callBg = `${call}${layeredAlpha};`; + call = bold; + } + else if (layeredMode && layeredHash in 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) + { + var hash = callObj.grid.substr(0, 4) + workHashSuffix; + var layeredHash = layeredMode && (callObj.grid.substr(0, 4) + layeredHashSuffix) + + if (huntIndex && !(hash in huntIndex.grid)) + { + shouldAlert = true; + + callObj.reason.push("grid"); + + if (workedIndex && hash in workedIndex.grid) + { + if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.grid) + { + callObj.hunting.grid = "mixed"; + gridBg = `${grid}${layeredAlpha};`; + grid = bold; + } + else if (layeredMode && layeredHash in 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) + { + var hash = String(callObj.dxcc) + workHashSuffix; + var layeredHash = layeredMode && (String(callObj.dxcc) + layeredHashSuffix) + + if (huntIndex && !(hash in huntIndex.dxcc)) + { + shouldAlert = true; + + callObj.reason.push("dxcc"); + + if (workedIndex && hash in workedIndex.dxcc) + { + if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.dxcc) + { + callObj.hunting.dxcc = "mixed"; + dxccBg = `${dxcc}${layeredAlpha};`; + dxcc = bold; + } + else if (layeredMode && layeredHash in 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) + { + var stateSearch = callObj.state; + var finalDxcc = callObj.dxcc; + if (finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6) + { + if (stateSearch in window.opener.g_StateData) + { + var hash = stateSearch + workHashSuffix; + var layeredHash = layeredMode && (stateSearch + layeredHashSuffix) + + if (huntIndex && !(hash in huntIndex.state)) + { + shouldAlert = true; + + callObj.reason.push("state"); + + if (workedIndex && hash in workedIndex.state) + { + if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.state) + { + callObj.hunting.state = "mixed"; + stateBg = `${state}${layeredAlpha};`; + state = bold; + } + else if (layeredMode && layeredHash in 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) + { + var finalDxcc = callObj.dxcc; + if ( + callObj.cnty && + (finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6 || finalDxcc == 202) && + callObj.cnty.length > 0 + ) + { + var hash = callObj.cnty + (layeredMode ? layeredHashSuffix : workHashSuffix); + + if ((huntIndex && !(hash in huntIndex.cnty)) || callObj.qual == false) + { + if (callObj.qual == false) + { + var counties = window.opener.g_zipToCounty[callObj.zipcode]; + var foundHit = false; + for (var cnt in counties) + { + var hh = counties[cnt] + workHash; + callObj.cnty = counties[cnt]; + if (huntIndex && !(hh in huntIndex.cnty)) + { + foundHit = true; + break; + } + } + if (foundHit) shouldAlert = true; + } + else + { + shouldAlert = true; + } + + if (shouldAlert) + { + callObj.reason.push("cnty"); + + if (workedIndex && hash in 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) + { + var huntTotal = callObj.cqza.length; + var huntFound = 0, layeredFound = 0, workedFound = 0, layeredWorkedFound = 0; + + for (index in callObj.cqza) + { + var hash = callObj.cqza[index] + workHashSuffix; + var layeredHash = layeredMode && (callObj.cqza[index] + layeredHashSuffix) + + if (huntIndex && hash in huntIndex.cqz) huntFound++; + if (layeredMode && layeredHash in huntIndex.cqz) layeredFound++; + if (workedIndex && hash in workedIndex.cqz) workedFound++; + if (layeredMode && layeredHash in workedIndex.cqz) layeredWorkedFound++; + } + if (huntFound != huntTotal) + { + shouldAlert = true; + callObj.reason.push("cqz"); + + if (workedIndex && workedFound == huntTotal) + { + if (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 (layeredMode && layeredFound == huntTotal) + { + callObj.hunting.cqz = "mixed"; + cqzBg = `${cqz}${layeredAlpha};`; + cqz = bold; + } + else if (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) + { + var huntTotal = callObj.ituza.length; + var huntFound = 0, layeredFound = 0, workedFound = 0, layeredWorkedFound = 0; + + for (index in callObj.ituza) + { + var hash = callObj.ituza[index] + workHashSuffix; + var layeredHash = layeredMode && (callObj.ituza[index] + layeredHashSuffix) + + if (huntIndex && hash in huntIndex.ituz) huntFound++; + if (layeredMode && layeredHash in huntIndex.ituz) layeredFound++; + if (workedIndex && hash in workedIndex.ituz) workedFound++; + if (layeredMode && layeredHash in workedIndex.ituz) layeredWorkedFound++; + } + if (huntFound != huntTotal) + { + shouldAlert = true; + callObj.reason.push("ituz"); + + if (workedIndex && workedFound == huntTotal) + { + if (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 (layeredMode && layeredFound == huntTotal) + { + callObj.hunting.ituz = "mixed"; + ituzBg = `${ituz}${layeredAlpha};`; + ituz = bold; + } + else if (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) + { + var hash = String(callObj.px) + workHashSuffix; + var layeredHash = layeredMode && (String(callObj.px) + layeredHashSuffix) + + if (huntIndex && !(hash in huntIndex.px)) + { + shouldAlert = true; + + callObj.reason.push("wpx"); + + if (workedIndex && hash in workedIndex.px) + { + if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.px) + { + callObj.hunting.wpx = "mixed"; + wpxBg = `${wpx}${layeredAlpha};`; + wpx = bold; + } + else if (layeredMode && layeredHash in 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) + { + var hash = String(callObj.cont) + workHashSuffix; + var layeredHash = layeredMode && (String(callObj.cont) + layeredHashSuffix) + + if (huntIndex && !(hash in huntIndex.cont)) + { + shouldAlert = true; + + callObj.reason.push("cont"); + + if (workedIndex && hash in workedIndex.cont) + { + if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.cont) + { + callObj.hunting.cont = "mixed"; + contBg = `${cont}${layeredAlpha};`; + cont = bold; + } + else if (layeredMode && layeredHash in 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 && g_rosterSettings.cqOnly == false) + { + 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 }; + } + + modes[callObj.mode] = true; + bands[callObj.band] = true; + + // NOTE: This is where calls that were filtered are passed into an array that will be used for the rendering loop + newCallList.push(callObj); + } + } + + return newCallList; +} diff --git a/package.nw/lib/roster/processRosterFiltering.js b/package.nw/lib/roster/processRosterFiltering.js new file mode 100644 index 0000000..9c41142 --- /dev/null +++ b/package.nw/lib/roster/processRosterFiltering.js @@ -0,0 +1,369 @@ +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 (var callHash in callRoster) + { + var entry = callRoster[callHash]; + var callObj = entry.callObj; + + var call = entry.DEcall; + + entry.tx = true; + callObj.shouldAlert = false; + callObj.reason = Array(); + callObj.awardReason = "Callsign"; + + if (now - callObj.age > window.opener.g_mapSettings.rosterTime) + { + entry.tx = false; + entry.alerted = false; + callObj.qrz = false; + callObj.reset = true; + 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.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) + { + var 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 (callMode != "all") + { + if (entry.DXcall == "CQ DX" && callObj.dxcc == window.opener.g_myDXCC) + { + entry.tx = false; + continue; + } + + var hash = hashMaker(call, callObj, g_rosterSettings.reference); + if (callMode == "worked" && hash in g_worked.call) + { + entry.tx = false; + continue; + } + if (callMode == "confirmed" && hash in g_confirmed.call) + { + entry.tx = false; + continue; + } + + if (g_rosterSettings.hunting == "grid") + { + var hash = hashMaker(callObj.grid.substr(0, 4), + callObj, g_rosterSettings.reference); + if (huntIndex && hash in huntIndex.grid) + { + entry.tx = false; + continue; + } + if (callObj.grid.length == 0) + { + entry.tx = false; + continue; + } + continue; + } + if (g_rosterSettings.hunting == "dxcc") + { + var hash = hashMaker(String(callObj.dxcc), + callObj, g_rosterSettings.reference); + + if (huntIndex && (hash in 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; + } + var hash = hashMaker(String(callObj.px), + callObj, g_rosterSettings.reference); + + if (huntIndex && (hash in huntIndex.px)) + { + entry.tx = false; + continue; + } + + continue; + } + + if (g_rosterSettings.hunting == "cq") + { + var huntTotal = callObj.cqza.length; + if (huntTotal == 0 || !huntIndex) + { + entry.tx = false; + continue; + } + var huntFound = 0; + for (index in callObj.cqza) + { + var hash = hashMaker(callObj.cqza[index], callObj, g_rosterSettings.reference); + + if (hash in huntIndex.cqz) huntFound++; + } + if (huntFound == huntTotal) + { + entry.tx = false; + continue; + } + continue; + } + + if (g_rosterSettings.hunting == "itu") + { + var huntTotal = callObj.ituza.length; + if (huntTotal == 0 || !huntIndex) + { + entry.tx = false; + continue; + } + var huntFound = 0; + for (index in callObj.ituza) + { + var hash = hashMaker(callObj.ituza[index], callObj, g_rosterSettings.reference); + + if (hash in 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) + { + var state = callObj.state; + var finalDxcc = callObj.dxcc; + if (finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6) + { + if (state in window.opener.g_StateData) + { + var hash = hashMaker(state, callObj, g_rosterSettings.reference); + + if (huntIndex && hash in 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 (isAwardTracker) + { + var tx = false; + var baseHash = hashMaker("", callObj, g_rosterSettings.reference); + + for (var award in g_awardTracker) + { + if (g_awardTracker[award].enable) + { + tx = testAward(award, callObj, baseHash); + if (tx) + { + var 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; + } + } +} diff --git a/package.nw/lib/roster/processRosterHunting.js b/package.nw/lib/roster/processRosterHunting.js new file mode 100644 index 0000000..6adaeab --- /dev/null +++ b/package.nw/lib/roster/processRosterHunting.js @@ -0,0 +1,700 @@ +function processRosterHunting(callRoster, rosterSettings) +{ + // these vars, do they rely on anything between the top and here? + // if not could they be put in the var list at the beginning? + var hasGtPin = false; + + var inversionAlpha = "DD"; + var row = "#000000"; + var bold = "#000000;font-weight: bold;"; + var unconf = "background-clip:padding-box;box-shadow: 0 0 7px 3px inset "; + var layeredAlpha = "77"; + var layeredInversionAlpha = "66"; + var layeredUnconf = "background-clip:padding-box;box-shadow: 0 0 4px 2px inset "; + var 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 (var callHash in callRoster) + { + var entry = callRoster[callHash]; + var 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, var 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 (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' + var workHashSuffix, layeredHashSuffix; + if (layeredMode) + { + workHashSuffix = hashMaker("", callObj, layeredMode); + layeredHashSuffix = hashMaker("", callObj, g_rosterSettings.reference); + } + else + { + workHashSuffix = hashMaker("", callObj, g_rosterSettings.reference); + layeredHashSuffix = false + } + var workHash = workHashSuffix; // TODO: Remove after replacing all occurrences with Suffix + + var callsign = entry.DEcall; + + callObj.hunting = {} + callObj.callFlags = {} + + var colorObject = Object(); + + var callPointer = callObj.CQ == true ? "cursor:pointer" : ""; + + var didWork = false; + + var call = "#FFFF00"; + var grid = "#00FFFF"; + var calling = "#90EE90"; + var dxcc = "#FFA500"; + var state = "#90EE90"; + var cnty = "#CCDD00"; + var cont = "#00DDDD"; + var cqz = "#DDDDDD"; + var ituz = "#DDDDDD"; + var wpx = "#FFFF00"; + + hasGtPin = false; + var shouldAlert = false; + var callBg, gridBg, callingBg, dxccBg, stateBg, cntyBg, contBg, cqzBg, ituzBg, wpxBg, gtBg; + var 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 = + ""; + + var hash = callsign + workHashSuffix; + var 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 (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) + { + var hash = callsign + workHashSuffix; + var layeredHash = layeredMode && (callsign + layeredHashSuffix) + + if (huntIndex && !(hash in huntIndex.call)) + { + shouldAlert = true; + + callObj.reason.push("call"); + + if (workedIndex && hash in workedIndex.call) + { + if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in workedIndex.call) + // { + // callObj.hunting.call = "worked-and-mixed-worked"; + // callConf = `${layeredUnconf}${call}${layeredAlpha};`; + // } + else + { + callObj.hunting.call = "worked"; + callConf = `${unconf}${call}${inversionAlpha};`; + } + } + else + { + if (layeredMode && layeredHash in huntIndex.call) + { + callObj.hunting.call = "mixed"; + callBg = `${call}${layeredAlpha};`; + call = bold; + } + else if (layeredMode && layeredHash in 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) + { + var hash = callObj.grid.substr(0, 4) + workHashSuffix; + var layeredHash = layeredMode && (callObj.grid.substr(0, 4) + layeredHashSuffix) + + if (huntIndex && !(hash in huntIndex.grid)) + { + shouldAlert = true; + + callObj.reason.push("grid"); + + if (workedIndex && hash in workedIndex.grid) + { + if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.grid) + { + callObj.hunting.grid = "mixed"; + gridBg = `${grid}${layeredAlpha};`; + grid = bold; + } + else if (layeredMode && layeredHash in 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) + { + var hash = String(callObj.dxcc) + workHashSuffix; + var layeredHash = layeredMode && (String(callObj.dxcc) + layeredHashSuffix) + + if (huntIndex && !(hash in huntIndex.dxcc)) + { + shouldAlert = true; + + callObj.reason.push("dxcc"); + + if (workedIndex && hash in workedIndex.dxcc) + { + if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.dxcc) + { + callObj.hunting.dxcc = "mixed"; + dxccBg = `${dxcc}${layeredAlpha};`; + dxcc = bold; + } + else if (layeredMode && layeredHash in 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) + { + var stateSearch = callObj.state; + var finalDxcc = callObj.dxcc; + if (finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6) + { + if (stateSearch in window.opener.g_StateData) + { + var hash = stateSearch + workHashSuffix; + var layeredHash = layeredMode && (stateSearch + layeredHashSuffix) + + if (huntIndex && !(hash in huntIndex.state)) + { + shouldAlert = true; + + callObj.reason.push("state"); + + if (workedIndex && hash in workedIndex.state) + { + if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.state) + { + callObj.hunting.state = "mixed"; + stateBg = `${state}${layeredAlpha};`; + state = bold; + } + else if (layeredMode && layeredHash in 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) + { + var finalDxcc = callObj.dxcc; + if ( + callObj.cnty && + (finalDxcc == 291 || finalDxcc == 110 || finalDxcc == 6 || finalDxcc == 202) && + callObj.cnty.length > 0 + ) + { + var hash = callObj.cnty + (layeredMode ? layeredHashSuffix : workHashSuffix); + + if ((huntIndex && !(hash in huntIndex.cnty)) || callObj.qual == false) + { + if (callObj.qual == false) + { + var counties = window.opener.g_zipToCounty[callObj.zipcode]; + var foundHit = false; + for (var cnt in counties) + { + var hh = counties[cnt] + workHash; + callObj.cnty = counties[cnt]; + if (huntIndex && !(hh in huntIndex.cnty)) + { + foundHit = true; + break; + } + } + if (foundHit) shouldAlert = true; + } + else + { + shouldAlert = true; + } + + if (shouldAlert) + { + callObj.reason.push("cnty"); + + if (workedIndex && hash in 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) + { + var huntTotal = callObj.cqza.length; + var huntFound = 0, layeredFound = 0, workedFound = 0, layeredWorkedFound = 0; + + for (index in callObj.cqza) + { + var hash = callObj.cqza[index] + workHashSuffix; + var layeredHash = layeredMode && (callObj.cqza[index] + layeredHashSuffix) + + if (huntIndex && hash in huntIndex.cqz) huntFound++; + if (layeredMode && layeredHash in huntIndex.cqz) layeredFound++; + if (workedIndex && hash in workedIndex.cqz) workedFound++; + if (layeredMode && layeredHash in workedIndex.cqz) layeredWorkedFound++; + } + if (huntFound != huntTotal) + { + shouldAlert = true; + callObj.reason.push("cqz"); + + if (workedIndex && workedFound == huntTotal) + { + if (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 (layeredMode && layeredFound == huntTotal) + { + callObj.hunting.cqz = "mixed"; + cqzBg = `${cqz}${layeredAlpha};`; + cqz = bold; + } + else if (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) + { + var huntTotal = callObj.ituza.length; + var huntFound = 0, layeredFound = 0, workedFound = 0, layeredWorkedFound = 0; + + for (index in callObj.ituza) + { + var hash = callObj.ituza[index] + workHashSuffix; + var layeredHash = layeredMode && (callObj.ituza[index] + layeredHashSuffix) + + if (huntIndex && hash in huntIndex.ituz) huntFound++; + if (layeredMode && layeredHash in huntIndex.ituz) layeredFound++; + if (workedIndex && hash in workedIndex.ituz) workedFound++; + if (layeredMode && layeredHash in workedIndex.ituz) layeredWorkedFound++; + } + if (huntFound != huntTotal) + { + shouldAlert = true; + callObj.reason.push("ituz"); + + if (workedIndex && workedFound == huntTotal) + { + if (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 (layeredMode && layeredFound == huntTotal) + { + callObj.hunting.ituz = "mixed"; + ituzBg = `${ituz}${layeredAlpha};`; + ituz = bold; + } + else if (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) + { + var hash = String(callObj.px) + workHashSuffix; + var layeredHash = layeredMode && (String(callObj.px) + layeredHashSuffix) + + if (huntIndex && !(hash in huntIndex.px)) + { + shouldAlert = true; + + callObj.reason.push("wpx"); + + if (workedIndex && hash in workedIndex.px) + { + if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.px) + { + callObj.hunting.wpx = "mixed"; + wpxBg = `${wpx}${layeredAlpha};`; + wpx = bold; + } + else if (layeredMode && layeredHash in 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) + { + var hash = String(callObj.cont) + workHashSuffix; + var layeredHash = layeredMode && (String(callObj.cont) + layeredHashSuffix) + + if (huntIndex && !(hash in huntIndex.cont)) + { + shouldAlert = true; + + callObj.reason.push("cont"); + + if (workedIndex && hash in workedIndex.cont) + { + if (layeredMode && layeredHash in 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 (layeredMode && layeredHash in huntIndex.cont) + { + callObj.hunting.cont = "mixed"; + contBg = `${cont}${layeredAlpha};`; + cont = bold; + } + else if (layeredMode && layeredHash in 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 && g_rosterSettings.cqOnly == false) + { + 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 }; + } + + modes[callObj.mode] = true; + bands[callObj.band] = true; + } + } +} diff --git a/package.nw/lib/roster/renderCompactRoster.js b/package.nw/lib/roster/renderCompactRoster.js new file mode 100644 index 0000000..271a0bc --- /dev/null +++ b/package.nw/lib/roster/renderCompactRoster.js @@ -0,0 +1,55 @@ +function renderCompactRosterHeaders() +{ + return "
"; +} + +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(); + worker += + "
"; + worker += + "
" + + thisCall.formatCallsign() + + "
"; + worker += + "
" + + window.opener.g_dxccToAltName[callObj.dxcc] + + "
"; + worker += "
"; + + return worker; +} + +function renderCompactRosterFooter() +{ + return "
"; +} diff --git a/package.nw/lib/roster/renderNormalRoster.js b/package.nw/lib/roster/renderNormalRoster.js new file mode 100644 index 0000000..80fa5a8 --- /dev/null +++ b/package.nw/lib/roster/renderNormalRoster.js @@ -0,0 +1,400 @@ +function renderNormalRosterHeaders() +{ + var worker = "" + worker = ""; + + worker += ""; + + if (showBands) + { worker += ""; } + + if (showModes) + { worker += ""; } + + worker += ""; + + if (g_rosterSettings.columns.Calling) + { worker += ""; } + + if (g_rosterSettings.columns.Msg) + { worker += ""; } + + if (g_rosterSettings.columns.DXCC) + { worker += ""; } + + if (g_rosterSettings.columns.Flag) + { worker += ""; } + + if (g_rosterSettings.columns.State) + { worker += ""; } + + if (g_rosterSettings.columns.County) + { worker += ""; } + + if (g_rosterSettings.columns.Cont) + { worker += ""; } + + if (g_rosterSettings.columns.dB) + { worker += ""; } + + if (g_rosterSettings.columns.Freq) + { worker += ""; } + + if (g_rosterSettings.columns.DT) + { worker += ""; } + + if (g_rosterSettings.columns.Dist) + { + worker += ""; + } + + if (g_rosterSettings.columns.Azim) + { worker += ""; } + + if (g_rosterSettings.columns.CQz) + { worker += ""; } + + if (g_rosterSettings.columns.ITUz) + { worker += ""; } + + if (g_rosterSettings.columns.PX) + { worker += ""; } + + if (window.opener.g_callsignLookups.lotwUseEnable == true && g_rosterSettings.columns.LoTW) + { worker += ""; } + + if (window.opener.g_callsignLookups.eqslUseEnable == true && g_rosterSettings.columns.eQSL) + { worker += ""; } + + if (window.opener.g_callsignLookups.oqrsUseEnable == true && g_rosterSettings.columns.OQRS) + { worker += ""; } + + if (g_rosterSettings.columns.Spot) + { worker += ""; } + + if (g_rosterSettings.columns.Life) + { worker += ""; } + + if (g_rosterSettings.columns.OAMS) + { worker += ""; } + + if (g_rosterSettings.columns.Age) + { worker += ""; } + + return worker +} + +function renderNormalRosterRow(callObj) +{ + var thisCall = callObj.DEcall; + var acks = window.opener.g_acknowledgedCalls; + + var thisHash = thisCall + callObj.band + callObj.mode; + var callStr = thisCall.formatCallsign() + if (acks[thisCall]) + { + callStr = `${callStr} ` + callObj.awardReason += ` - ${acks[thisCall].message}` + } + + var worker = ""; + worker += + ""; + + if (showBands) + { + worker += + ""; + } + if (showModes) + { + var color = "888888"; + if (callObj.mode in g_modeColors) + { color = g_modeColors[callObj.mode]; } + worker += + ""; + } + + worker += + ""; + if (g_rosterSettings.columns.Calling) + { + var lookString = callObj.CQ ? "name='CQ'" : "name='Calling'"; + worker += + ""; + } + if (g_rosterSettings.columns.Msg) + { worker += ""; } + + if (g_rosterSettings.columns.DXCC) + { + worker += + ""; + } + if (g_rosterSettings.columns.Flag) + { + worker += + ""; + } + if (g_rosterSettings.columns.State) + { + worker += + ""; + } + if (g_rosterSettings.columns.County) + { + worker += + ""; + } + if (g_rosterSettings.columns.Cont) + { + worker += + ""; + } + + if (g_rosterSettings.columns.dB) + { + worker += + ""; + } + if (g_rosterSettings.columns.Freq) + { worker += ""; } + if (g_rosterSettings.columns.DT) + { worker += ""; } + if (g_rosterSettings.columns.Dist) + { + worker += + ""; + } + if (g_rosterSettings.columns.Azim) + { + worker += + ""; + } + + if (g_rosterSettings.columns.CQz) + { + worker += + ""; + } + if (g_rosterSettings.columns.ITUz) + { + worker += + ""; + } + + if (g_rosterSettings.columns.PX) + { + worker += + ""; + } + + if ( + window.opener.g_callsignLookups.lotwUseEnable == true && + g_rosterSettings.columns.LoTW + ) + { + if (thisCall in window.opener.g_lotwCallsigns) + { + if (g_rosterSettings.maxLoTW < 27) + { + var months = (g_day - window.opener.g_lotwCallsigns[thisCall]) / 30; + if (months > g_rosterSettings.maxLoTW) + { + worker += + ""; + } + else + { + worker += + ""; + } + } + else + { + worker += + ""; + } + } + else worker += ""; + } + if ( + window.opener.g_callsignLookups.eqslUseEnable == true && + g_rosterSettings.columns.eQSL + ) + { + worker += + ""; + } + if ( + window.opener.g_callsignLookups.oqrsUseEnable == true && + g_rosterSettings.columns.OQRS + ) + { + worker += + ""; + } + + if (g_rosterSettings.columns.Spot) + { + worker += + ""; + } + if (g_rosterSettings.columns.Life) + { + worker += + ""; + } + + if (g_rosterSettings.columns.OAMS) + { + if (callObj.style.gt != 0) + { + if (callObj.reason.includes("oams")) + { + worker += + ""; + } + else + { + worker += + ""; + } + } + else worker += ""; + } + + if (g_rosterSettings.columns.Age) + { + worker += + ""; + } + + worker += ""; + + return worker; +} + +function renderNormalRosterFooter() +{ + return "
CallsignBandModeGridCallingMsgDXCCFlagStateCountyContdBFreqDTDist(" + + window.opener.distanceUnit.value.toLowerCase() + ")AzimCQzITUzPXLoTWeQSLOQRSSpotLifeOAMSAge
" + + callStr + + "" + + callObj.band + + "" + callObj.mode + "" + + grid + + "" + + callObj.DXcall.formatCallsign() + + "" + callObj.msg + "" + + window.opener.g_dxccToAltName[callObj.dxcc] + "" + + (callObj.state ? callObj.state.substr(3) : "") + + "" + + (callObj.cnty + ? (callObj.qual ? "" : "~ ") + + window.opener.g_cntyToCounty[callObj.cnty] + + (callObj.qual ? "" : " ~") + : "") + + "" + + (callObj.cont ? callObj.cont : "") + + "" + + callObj.RSTsent + + "" + callObj.delta + "" + callObj.dt + "" + + parseInt( + callObj.distance * + MyCircle.validateRadius(window.opener.distanceUnit.value) + ) + + "" + + parseInt(callObj.heading) + + "" + + callObj.cqza.join(",") + + "" + + callObj.ituza.join(",") + + "" + + (callObj.px ? callObj.px : "") + + "?" + + (thisCall in window.opener.g_eqslCallsigns ? "✔" : "") + + "" + + (thisCall in window.opener.g_oqrsCallsigns ? "✔" : "") + + "" + + spotString + + "" + + (timeNowSec() - callObj.life).toDHMS() + + "" + + (timeNowSec() - callObj.age).toDHMS() + + "
"; +} diff --git a/package.nw/lib/roster/renderRoster.js b/package.nw/lib/roster/renderRoster.js new file mode 100644 index 0000000..20f4be9 --- /dev/null +++ b/package.nw/lib/roster/renderRoster.js @@ -0,0 +1,102 @@ +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 + + var visibleCallList = callRoster.filter(entry => entry.tx); + + var totalCount = Object.keys(callRoster).length; + var visibleCount = visibleCallList.length; + var huntedCount = visibleCallList.filter(obj => Object.keys(obj.hunting).length > 0).length + var 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(); + } + + var showBands = (Object.keys(rosterSettings.bands).length > 1) || g_rosterSettings.columns.Band; + var showModes = (Object.keys(rosterSettings.modes).length > 1) || g_rosterSettings.columns.Mode; + + var worker = g_rosterSettings.compact ? renderCompactRosterHeaders() : renderNormalRosterHeaders() + + // Third loop: render all rows + for (var x in visibleCallList) + { + var callObj = visibleCallList[x]; + + // TODO: This is filtering + if (callObj.shouldAlert == false && onlyHits == true && callObj.qrz == false) + { continue; } + + var spotString = ""; + if (g_rosterSettings.columns.Spot && callObj.qrz == false) + { + spotString = getSpotString(callObj); + // TODO: This is filtering + if (g_rosterSettings.onlySpot && spotString == "") continue; + } + var grid = callObj.grid.length > 1 ? callObj.grid.substr(0, 4) : "-"; + + var geo = window.opener.g_worldGeoData[window.opener.g_dxccToGeoData[callObj.dxcc]]; + var cqzone = grid in window.opener.g_gridToCQZone ? window.opener.g_gridToCQZone[grid].join(", ") : "-"; + var ituzone = grid in window.opener.g_gridToITUZone ? window.opener.g_gridToITUZone[grid].join(", ") : "-"; + var 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) + } + + RosterTable.innerHTML = g_rosterSettings.compact ? renderCompactRosterFooter() : renderNormalRosterFooter() +} diff --git a/package.nw/lib/roster/sendAlerts.js b/package.nw/lib/roster/sendAlerts.js new file mode 100644 index 0000000..ab814f1 --- /dev/null +++ b/package.nw/lib/roster/sendAlerts.js @@ -0,0 +1,135 @@ +function sendAlerts(callRoster, rosterSettings) +{ + var dirPath = window.opener.g_scriptDir; + var scriptExists = false; + var script = "cr-alert.sh"; + + var shouldAlert = 0; + + for (var callObj in callRoster) + { 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 (callMode != "all") + { + g_scriptReport[call].shouldAlert = true; + g_scriptReport[call].reason.push(g_rosterSettings.hunting); + } + } + + if ( + callObj.alerted == false && + callMode == "all" && + callObj.shouldAlert == true + ) + { + callObj.alerted = true; + shouldAlert++; + } + else if (callObj.alerted == false && 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 = + "
" + + (window.opener.g_crScript == 1 + ? "Script Enabled" + : "Script Disabled") + + "
"; + 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(); +} From 7c7baef4c6e6cac214e4f9fe992e03ed6b6676cc Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 19:19:26 -0500 Subject: [PATCH 05/60] refactor so far --- package.nw/gt_roster.html | 7 ++ package.nw/lib/roster.js | 52 ------------- package.nw/lib/roster/sendAlerts.js | 116 ++++++++++++++-------------- 3 files changed, 65 insertions(+), 110 deletions(-) diff --git a/package.nw/gt_roster.html b/package.nw/gt_roster.html index 7cbc9f8..3909386 100644 --- a/package.nw/gt_roster.html +++ b/package.nw/gt_roster.html @@ -22,6 +22,13 @@ + + + + + + + diff --git a/package.nw/lib/roster.js b/package.nw/lib/roster.js index d7997f6..8ce9b2e 100644 --- a/package.nw/lib/roster.js +++ b/package.nw/lib/roster.js @@ -369,58 +369,6 @@ function myGTCompare(a, b) return 0; } -var r_sortFunction = [ - myCallCompare, - myGridCompare, - myDbCompare, - myDTCompare, - myFreqCompare, - myDxccCompare, - myTimeCompare, - myDistanceCompare, - myHeadingCompare, - myStateCompare, - myCQCompare, - myWPXCompare, - myLifeCompare, - mySpotCompare, - myGTCompare, - myCntyCompare, - myContCompare -]; - -var r_excptTest = [ - timeChk, - crEnable, - blockedCall, - blockedFrom, - blcokedDXCC, - cqOnly, - useRegex, - reqGrid, - minDB, - maxDT, - minFreq, - maxFreq, - noMsg, - onlyMesg, - myDXCC, - lotwUse, - eqslUse, - oqrsUse, - noMyCQDX, - callWorked, - callConfirmed, - huntGrid, - huntDXCC, - huntDXCCs, - huntWPX, - huntCQ, - huntITU, - huntUSStates, - huntUSState -]; - function showRosterBox(sortIndex) { if (g_rosterSettings.lastSortIndex != sortIndex) diff --git a/package.nw/lib/roster/sendAlerts.js b/package.nw/lib/roster/sendAlerts.js index ab814f1..7dcfa0f 100644 --- a/package.nw/lib/roster/sendAlerts.js +++ b/package.nw/lib/roster/sendAlerts.js @@ -52,84 +52,84 @@ function sendAlerts(callRoster, rosterSettings) } callObj.shouldAlert = false; -} -// NOTE: Ring alerts if needed -try -{ - if (fs.existsSync(dirPath)) + // NOTE: Ring alerts if needed + try { - if (window.opener.g_platform == "windows") + if (fs.existsSync(dirPath)) { - script = "cr-alert.bat"; - } - if ( - fs.existsSync(dirPath + script) && + if (window.opener.g_platform == "windows") + { + script = "cr-alert.bat"; + } + if ( + fs.existsSync(dirPath + script) && g_rosterSettings.realtime == false - ) - { - scriptExists = true; - scriptIcon.innerHTML = + ) + { + scriptExists = true; + scriptIcon.innerHTML = "
" + (window.opener.g_crScript == 1 ? "Script Enabled" : "Script Disabled") + "
"; - scriptIcon.style.display = "block"; - } - else - { - scriptIcon.style.display = "none"; + scriptIcon.style.display = "block"; + } + else + { + scriptIcon.style.display = "none"; + } } } -} -catch (e) {} + catch (e) {} -if (shouldAlert > 0) -{ - if (window.opener.g_classicAlerts.huntRoster == true) + if (shouldAlert > 0) { - var notify = window.opener.huntRosterNotify.value; - if (notify == "0") + if (window.opener.g_classicAlerts.huntRoster == true) { - var media = window.opener.huntRosterNotifyMedia.value; - if (media != "none") window.opener.playAlertMediaFile(media); + 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 + ); + } } - else if (notify == "1") - { - window.opener.speakAlertString( - window.opener.huntRosterNotifyWord.value - ); - } - } - if ( - g_rosterSettings.realtime == false && + if ( + g_rosterSettings.realtime == false && scriptExists && window.opener.g_crScript == 1 - ) - { - try + ) { - fs.writeFileSync( - dirPath + "cr-alert.json", - JSON.stringify(g_scriptReport, null, 2) - ); + 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(); + 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(); } - catch (e) - { - conosle.log(e); - } - g_scriptReport = Object(); + else g_scriptReport = Object(); } - else g_scriptReport = Object(); } From 26a1b513c2268d147b19744140f4a444d421c29c Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 20:42:07 -0500 Subject: [PATCH 06/60] fixed a bunch of broken refs to rosterSettings --- .../lib/roster/processRosterFiltering.js | 10 +- package.nw/lib/roster/processRosterHunting.js | 128 +++++++++--------- 2 files changed, 69 insertions(+), 69 deletions(-) diff --git a/package.nw/lib/roster/processRosterFiltering.js b/package.nw/lib/roster/processRosterFiltering.js index 9c41142..c593651 100644 --- a/package.nw/lib/roster/processRosterFiltering.js +++ b/package.nw/lib/roster/processRosterFiltering.js @@ -14,7 +14,7 @@ function processRosterFiltering(callRoster, rosterSettings) callObj.reason = Array(); callObj.awardReason = "Callsign"; - if (now - callObj.age > window.opener.g_mapSettings.rosterTime) + if (rosterSettings.now - callObj.age > window.opener.g_mapSettings.rosterTime) { entry.tx = false; entry.alerted = false; @@ -166,7 +166,7 @@ function processRosterFiltering(callRoster, rosterSettings) } } - if (callMode != "all") + if (rosterSettings.callMode != "all") { if (entry.DXcall == "CQ DX" && callObj.dxcc == window.opener.g_myDXCC) { @@ -175,12 +175,12 @@ function processRosterFiltering(callRoster, rosterSettings) } var hash = hashMaker(call, callObj, g_rosterSettings.reference); - if (callMode == "worked" && hash in g_worked.call) + if (rosterSettings.callMode == "worked" && hash in g_worked.call) { entry.tx = false; continue; } - if (callMode == "confirmed" && hash in g_confirmed.call) + if (rosterSettings.callMode == "confirmed" && hash in g_confirmed.call) { entry.tx = false; continue; @@ -338,7 +338,7 @@ function processRosterFiltering(callRoster, rosterSettings) continue; } } - if (isAwardTracker) + if (rosterSettings.isAwardTracker) { var tx = false; var baseHash = hashMaker("", callObj, g_rosterSettings.reference); diff --git a/package.nw/lib/roster/processRosterHunting.js b/package.nw/lib/roster/processRosterHunting.js index 6adaeab..ded6a15 100644 --- a/package.nw/lib/roster/processRosterHunting.js +++ b/package.nw/lib/roster/processRosterHunting.js @@ -46,9 +46,9 @@ function processRosterHunting(callRoster, rosterSettings) // In layered mode ("Hunting: mixed") the workHashSuffix becomes a more stricter 'live band', // while the layered suffix is a broader 'mixed band' var workHashSuffix, layeredHashSuffix; - if (layeredMode) + if (rosterSettings.layeredMode) { - workHashSuffix = hashMaker("", callObj, layeredMode); + workHashSuffix = hashMaker("", callObj, rosterSettings.layeredMode); layeredHashSuffix = hashMaker("", callObj, g_rosterSettings.reference); } else @@ -128,7 +128,7 @@ function processRosterHunting(callRoster, rosterSettings) // 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 (callMode == "all") + 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? @@ -142,17 +142,17 @@ function processRosterHunting(callRoster, rosterSettings) if (huntCallsign.checked == true) { var hash = callsign + workHashSuffix; - var layeredHash = layeredMode && (callsign + layeredHashSuffix) + var layeredHash = rosterSettings.layeredMode && (callsign + layeredHashSuffix) - if (huntIndex && !(hash in huntIndex.call)) + if (rosterSettings.huntIndex && !(hash in rosterSettings.huntIndex.call)) { shouldAlert = true; callObj.reason.push("call"); - if (workedIndex && hash in workedIndex.call) + if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.call) { - if (layeredMode && layeredHash in huntIndex.call) + if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.call) { callObj.hunting.call = "worked-and-mixed"; callConf = `${layeredUnconf}${call}${layeredUnconfAlpha};`; @@ -164,7 +164,7 @@ function processRosterHunting(callRoster, rosterSettings) // * so we cannot cover this particular combination // * and have to default to just showing it as plain "worked" // */ - // else if (layeredMode && layeredHash in workedIndex.call) + // else if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.call) // { // callObj.hunting.call = "worked-and-mixed-worked"; // callConf = `${layeredUnconf}${call}${layeredAlpha};`; @@ -177,13 +177,13 @@ function processRosterHunting(callRoster, rosterSettings) } else { - if (layeredMode && layeredHash in huntIndex.call) + if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.call) { callObj.hunting.call = "mixed"; callBg = `${call}${layeredAlpha};`; call = bold; } - else if (layeredMode && layeredHash in workedIndex.call) + else if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.call) { callObj.hunting.call = "mixed-worked"; callConf = `${unconf}${call}${layeredAlpha};`; @@ -218,17 +218,17 @@ function processRosterHunting(callRoster, rosterSettings) if (huntGrid.checked == true && callObj.grid.length > 1) { var hash = callObj.grid.substr(0, 4) + workHashSuffix; - var layeredHash = layeredMode && (callObj.grid.substr(0, 4) + layeredHashSuffix) + var layeredHash = rosterSettings.layeredMode && (callObj.grid.substr(0, 4) + layeredHashSuffix) - if (huntIndex && !(hash in huntIndex.grid)) + if (rosterSettings.huntIndex && !(hash in rosterSettings.huntIndex.grid)) { shouldAlert = true; callObj.reason.push("grid"); - if (workedIndex && hash in workedIndex.grid) + if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.grid) { - if (layeredMode && layeredHash in huntIndex.grid) + if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.grid) { callObj.hunting.grid = "worked-and-mixed"; gridConf = `${layeredUnconf}${grid}${layeredUnconfAlpha};`; @@ -243,13 +243,13 @@ function processRosterHunting(callRoster, rosterSettings) } else { - if (layeredMode && layeredHash in huntIndex.grid) + if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.grid) { callObj.hunting.grid = "mixed"; gridBg = `${grid}${layeredAlpha};`; grid = bold; } - else if (layeredMode && layeredHash in workedIndex.grid) + else if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.grid) { callObj.hunting.grid = "mixed-worked"; gridConf = `${unconf}${grid}${layeredAlpha};`; @@ -268,17 +268,17 @@ function processRosterHunting(callRoster, rosterSettings) if (huntDXCC.checked == true) { var hash = String(callObj.dxcc) + workHashSuffix; - var layeredHash = layeredMode && (String(callObj.dxcc) + layeredHashSuffix) + var layeredHash = rosterSettings.layeredMode && (String(callObj.dxcc) + layeredHashSuffix) - if (huntIndex && !(hash in huntIndex.dxcc)) + if (rosterSettings.huntIndex && !(hash in rosterSettings.huntIndex.dxcc)) { shouldAlert = true; callObj.reason.push("dxcc"); - if (workedIndex && hash in workedIndex.dxcc) + if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.dxcc) { - if (layeredMode && layeredHash in huntIndex.dxcc) + if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.dxcc) { callObj.hunting.dxcc = "worked-and-mixed"; dxccConf = `${layeredUnconf}${dxcc}${layeredUnconfAlpha};`; @@ -293,13 +293,13 @@ function processRosterHunting(callRoster, rosterSettings) } else { - if (layeredMode && layeredHash in huntIndex.dxcc) + if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.dxcc) { callObj.hunting.dxcc = "mixed"; dxccBg = `${dxcc}${layeredAlpha};`; dxcc = bold; } - else if (layeredMode && layeredHash in workedIndex.dxcc) + else if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.dxcc) { callObj.hunting.dxcc = "mixed-worked"; dxccConf = `${unconf}${dxcc}${layeredAlpha};`; @@ -324,17 +324,17 @@ function processRosterHunting(callRoster, rosterSettings) if (stateSearch in window.opener.g_StateData) { var hash = stateSearch + workHashSuffix; - var layeredHash = layeredMode && (stateSearch + layeredHashSuffix) + var layeredHash = rosterSettings.layeredMode && (stateSearch + layeredHashSuffix) - if (huntIndex && !(hash in huntIndex.state)) + if (rosterSettings.huntIndex && !(hash in rosterSettings.huntIndex.state)) { shouldAlert = true; callObj.reason.push("state"); - if (workedIndex && hash in workedIndex.state) + if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.state) { - if (layeredMode && layeredHash in huntIndex.state) + if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.state) { callObj.hunting.state = "worked-and-mixed"; stateConf = `${layeredUnconf}${state}${layeredUnconfAlpha};`; @@ -349,13 +349,13 @@ function processRosterHunting(callRoster, rosterSettings) } else { - if (layeredMode && layeredHash in huntIndex.state) + if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.state) { callObj.hunting.state = "mixed"; stateBg = `${state}${layeredAlpha};`; state = bold; } - else if (layeredMode && layeredHash in workedIndex.state) + else if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.state) { callObj.hunting.state = "mixed-worked"; stateConf = `${unconf}${state}${layeredAlpha};`; @@ -382,9 +382,9 @@ function processRosterHunting(callRoster, rosterSettings) callObj.cnty.length > 0 ) { - var hash = callObj.cnty + (layeredMode ? layeredHashSuffix : workHashSuffix); + var hash = callObj.cnty + (rosterSettings.layeredMode ? layeredHashSuffix : workHashSuffix); - if ((huntIndex && !(hash in huntIndex.cnty)) || callObj.qual == false) + if ((rosterSettings.huntIndex && !(hash in rosterSettings.huntIndex.cnty)) || callObj.qual == false) { if (callObj.qual == false) { @@ -394,7 +394,7 @@ function processRosterHunting(callRoster, rosterSettings) { var hh = counties[cnt] + workHash; callObj.cnty = counties[cnt]; - if (huntIndex && !(hh in huntIndex.cnty)) + if (rosterSettings.huntIndex && !(hh in rosterSettings.huntIndex.cnty)) { foundHit = true; break; @@ -411,7 +411,7 @@ function processRosterHunting(callRoster, rosterSettings) { callObj.reason.push("cnty"); - if (workedIndex && hash in workedIndex.cnty) + if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.cnty) { callObj.hunting.cnty = "worked"; cntyConf = `${unconf}${cnty}${inversionAlpha};`; @@ -436,21 +436,21 @@ function processRosterHunting(callRoster, rosterSettings) for (index in callObj.cqza) { var hash = callObj.cqza[index] + workHashSuffix; - var layeredHash = layeredMode && (callObj.cqza[index] + layeredHashSuffix) + var layeredHash = rosterSettings.layeredMode && (callObj.cqza[index] + layeredHashSuffix) - if (huntIndex && hash in huntIndex.cqz) huntFound++; - if (layeredMode && layeredHash in huntIndex.cqz) layeredFound++; - if (workedIndex && hash in workedIndex.cqz) workedFound++; - if (layeredMode && layeredHash in workedIndex.cqz) layeredWorkedFound++; + 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 (workedIndex && workedFound == huntTotal) + if (rosterSettings.workedIndex && workedFound == huntTotal) { - if (layeredMode && layeredFound == huntTotal) + if (rosterSettings.layeredMode && layeredFound == huntTotal) { callObj.hunting.cqz = "worked-and-mixed"; cqzConf = `${layeredUnconf}${cqz}${layeredUnconfAlpha};`; @@ -465,13 +465,13 @@ function processRosterHunting(callRoster, rosterSettings) } else { - if (layeredMode && layeredFound == huntTotal) + if (rosterSettings.layeredMode && layeredFound == huntTotal) { callObj.hunting.cqz = "mixed"; cqzBg = `${cqz}${layeredAlpha};`; cqz = bold; } - else if (layeredMode && layeredWorkedFound == huntTotal) + else if (rosterSettings.layeredMode && layeredWorkedFound == huntTotal) { callObj.hunting.cqz = "mixed-worked"; cqzConf = `${unconf}${cqz}${layeredAlpha};`; @@ -495,21 +495,21 @@ function processRosterHunting(callRoster, rosterSettings) for (index in callObj.ituza) { var hash = callObj.ituza[index] + workHashSuffix; - var layeredHash = layeredMode && (callObj.ituza[index] + layeredHashSuffix) + var layeredHash = rosterSettings.layeredMode && (callObj.ituza[index] + layeredHashSuffix) - if (huntIndex && hash in huntIndex.ituz) huntFound++; - if (layeredMode && layeredHash in huntIndex.ituz) layeredFound++; - if (workedIndex && hash in workedIndex.ituz) workedFound++; - if (layeredMode && layeredHash in workedIndex.ituz) layeredWorkedFound++; + 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 (workedIndex && workedFound == huntTotal) + if (rosterSettings.workedIndex && workedFound == huntTotal) { - if (layeredMode && layeredFound == huntTotal) + if (rosterSettings.layeredMode && layeredFound == huntTotal) { callObj.hunting.ituz = "worked-and-mixed"; ituzConf = `${layeredUnconf}${ituz}${layeredUnconfAlpha};`; @@ -524,13 +524,13 @@ function processRosterHunting(callRoster, rosterSettings) } else { - if (layeredMode && layeredFound == huntTotal) + if (rosterSettings.layeredMode && layeredFound == huntTotal) { callObj.hunting.ituz = "mixed"; ituzBg = `${ituz}${layeredAlpha};`; ituz = bold; } - else if (layeredMode && layeredWorkedFound == huntTotal) + else if (rosterSettings.layeredMode && layeredWorkedFound == huntTotal) { callObj.hunting.ituz = "mixed-worked"; ituzConf = `${unconf}${ituz}${layeredAlpha};`; @@ -549,17 +549,17 @@ function processRosterHunting(callRoster, rosterSettings) if (huntPX.checked == true && callObj.px) { var hash = String(callObj.px) + workHashSuffix; - var layeredHash = layeredMode && (String(callObj.px) + layeredHashSuffix) + var layeredHash = rosterSettings.layeredMode && (String(callObj.px) + layeredHashSuffix) - if (huntIndex && !(hash in huntIndex.px)) + if (rosterSettings.huntIndex && !(hash in rosterSettings.huntIndex.px)) { shouldAlert = true; callObj.reason.push("wpx"); - if (workedIndex && hash in workedIndex.px) + if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.px) { - if (layeredMode && layeredHash in huntIndex.px) + if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.px) { callObj.hunting.wpx = "worked-and-mixed"; wpxConf = `${layeredUnconf}${wpx}${layeredUnconfAlpha};`; @@ -574,13 +574,13 @@ function processRosterHunting(callRoster, rosterSettings) } else { - if (layeredMode && layeredHash in huntIndex.px) + if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.px) { callObj.hunting.wpx = "mixed"; wpxBg = `${wpx}${layeredAlpha};`; wpx = bold; } - else if (layeredMode && layeredHash in workedIndex.px) + else if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.px) { callObj.hunting.wpx = "mixed-worked"; wpxConf = `${unconf}${wpx}${layeredAlpha};`; @@ -599,17 +599,17 @@ function processRosterHunting(callRoster, rosterSettings) if (huntCont.checked == true && callObj.cont) { var hash = String(callObj.cont) + workHashSuffix; - var layeredHash = layeredMode && (String(callObj.cont) + layeredHashSuffix) + var layeredHash = rosterSettings.layeredMode && (String(callObj.cont) + layeredHashSuffix) - if (huntIndex && !(hash in huntIndex.cont)) + if (rosterSettings.huntIndex && !(hash in rosterSettings.huntIndex.cont)) { shouldAlert = true; callObj.reason.push("cont"); - if (workedIndex && hash in workedIndex.cont) + if (rosterSettings.workedIndex && hash in rosterSettings.workedIndex.cont) { - if (layeredMode && layeredHash in huntIndex.cont) + if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.cont) { callObj.hunting.cont = "worked-and-mixed"; contConf = `${layeredUnconf}${cont}${layeredUnconfAlpha};`; @@ -624,13 +624,13 @@ function processRosterHunting(callRoster, rosterSettings) } else { - if (layeredMode && layeredHash in huntIndex.cont) + if (rosterSettings.layeredMode && layeredHash in rosterSettings.huntIndex.cont) { callObj.hunting.cont = "mixed"; contBg = `${cont}${layeredAlpha};`; cont = bold; } - else if (layeredMode && layeredHash in workedIndex.cont) + else if (rosterSettings.layeredMode && layeredHash in rosterSettings.workedIndex.cont) { callObj.hunting.cont = "mixed-worked"; contConf = `${unconf}${cont}${layeredAlpha};`; @@ -693,8 +693,8 @@ function processRosterHunting(callRoster, rosterSettings) callObj.spot = { when: 0, snr: 0 }; } - modes[callObj.mode] = true; - bands[callObj.band] = true; + rosterSettings.modes[callObj.mode] = true; + rosterSettings.bands[callObj.band] = true; } } } From 79efcb68dd3bd0dae0c9c1a283a9ef30d3cb0ac5 Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 21:58:05 -0500 Subject: [PATCH 07/60] fix some more broken stuff --- package.nw/lib/roster/renderRoster.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/package.nw/lib/roster/renderRoster.js b/package.nw/lib/roster/renderRoster.js index 20f4be9..d245b2d 100644 --- a/package.nw/lib/roster/renderRoster.js +++ b/package.nw/lib/roster/renderRoster.js @@ -18,11 +18,20 @@ function renderRoster(callRoster, rosterSettings) // Show the roster count in the window title - var visibleCallList = callRoster.filter(entry => entry.tx); + // var visibleCallList = callRoster.filter(entry => entry.tx); + + var visibleCallList = []; + for (entry in callRoster) + { + if (entry.tx) + { + visibleCallList.push(callRoster[entry]); + } + } var totalCount = Object.keys(callRoster).length; var visibleCount = visibleCallList.length; - var huntedCount = visibleCallList.filter(obj => Object.keys(obj.hunting).length > 0).length + var huntedCount = visibleCallList.filter(obj => Object.keys(callObj.hunting).length > 0).length var countParts = []; if (totalCount != visibleCount) From 3d098a159e76ea0271ce97044119d201e94e1dd1 Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 22:00:27 -0500 Subject: [PATCH 08/60] re-added r_sortFunction that somehow wondered off --- package.nw/lib/roster.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/package.nw/lib/roster.js b/package.nw/lib/roster.js index 8ce9b2e..05a464d 100644 --- a/package.nw/lib/roster.js +++ b/package.nw/lib/roster.js @@ -246,6 +246,26 @@ function lockNewWindows() } } +var r_sortFunction = [ + myCallCompare, + myGridCompare, + myDbCompare, + myDTCompare, + myFreqCompare, + myDxccCompare, + myTimeCompare, + myDistanceCompare, + myHeadingCompare, + myStateCompare, + myCQCompare, + myWPXCompare, + myLifeCompare, + mySpotCompare, + myGTCompare, + myCntyCompare, + myContCompare +]; + function myCallCompare(a, b) { return a.DEcall.localeCompare(b.DEcall); From b000a5b377fdb474597dd0103ad7b14838f4e9e7 Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 22:08:06 -0500 Subject: [PATCH 09/60] more broke fixed --- package.nw/lib/roster/renderNormalRoster.js | 2 +- package.nw/lib/roster/renderRoster.js | 2 +- package.nw/lib/roster/sendAlerts.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.nw/lib/roster/renderNormalRoster.js b/package.nw/lib/roster/renderNormalRoster.js index 80fa5a8..3174d25 100644 --- a/package.nw/lib/roster/renderNormalRoster.js +++ b/package.nw/lib/roster/renderNormalRoster.js @@ -1,4 +1,4 @@ -function renderNormalRosterHeaders() +function renderNormalRosterHeaders(showBands, showModes) { var worker = "" worker = ""; diff --git a/package.nw/lib/roster/renderRoster.js b/package.nw/lib/roster/renderRoster.js index d245b2d..cc8f4b9 100644 --- a/package.nw/lib/roster/renderRoster.js +++ b/package.nw/lib/roster/renderRoster.js @@ -65,7 +65,7 @@ function renderRoster(callRoster, rosterSettings) var showBands = (Object.keys(rosterSettings.bands).length > 1) || g_rosterSettings.columns.Band; var showModes = (Object.keys(rosterSettings.modes).length > 1) || g_rosterSettings.columns.Mode; - var worker = g_rosterSettings.compact ? renderCompactRosterHeaders() : renderNormalRosterHeaders() + var worker = g_rosterSettings.compact ? renderCompactRosterHeaders() : renderNormalRosterHeaders(showBands, showModes) // Third loop: render all rows for (var x in visibleCallList) diff --git a/package.nw/lib/roster/sendAlerts.js b/package.nw/lib/roster/sendAlerts.js index 7dcfa0f..99a3188 100644 --- a/package.nw/lib/roster/sendAlerts.js +++ b/package.nw/lib/roster/sendAlerts.js @@ -29,7 +29,7 @@ function sendAlerts(callRoster, rosterSettings) delete g_scriptReport[call].qso; delete g_scriptReport[call].instance; - if (callMode != "all") + if (rosterSettings.callMode != "all") { g_scriptReport[call].shouldAlert = true; g_scriptReport[call].reason.push(g_rosterSettings.hunting); @@ -38,7 +38,7 @@ function sendAlerts(callRoster, rosterSettings) if ( callObj.alerted == false && - callMode == "all" && + rosterSettings.callMode == "all" && callObj.shouldAlert == true ) { From c1f46d4f2d3323723005fd2bb3768c6d09444e0e Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 22:12:23 -0500 Subject: [PATCH 10/60] fix sendAlerts undefined object --- package.nw/lib/roster/sendAlerts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.nw/lib/roster/sendAlerts.js b/package.nw/lib/roster/sendAlerts.js index 99a3188..b4eccd3 100644 --- a/package.nw/lib/roster/sendAlerts.js +++ b/package.nw/lib/roster/sendAlerts.js @@ -6,7 +6,7 @@ function sendAlerts(callRoster, rosterSettings) var shouldAlert = 0; - for (var callObj in callRoster) + for (callObj in callRoster) { if (!callObj.tx) continue } // TODO: Get rid of realtime From 5462bc08e5c22bf20ea19f558147880791703c95 Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 22:18:32 -0500 Subject: [PATCH 11/60] fix broken array --- package.nw/lib/roster/renderRoster.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.nw/lib/roster/renderRoster.js b/package.nw/lib/roster/renderRoster.js index cc8f4b9..de3350d 100644 --- a/package.nw/lib/roster/renderRoster.js +++ b/package.nw/lib/roster/renderRoster.js @@ -23,7 +23,7 @@ function renderRoster(callRoster, rosterSettings) var visibleCallList = []; for (entry in callRoster) { - if (entry.tx) + if (callRoster[entry].tx) { visibleCallList.push(callRoster[entry]); } From 9d80c6df09e10149b374410070a9f2fb50036e97 Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 22:21:19 -0500 Subject: [PATCH 12/60] fix line 34 --- package.nw/lib/roster/renderRoster.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.nw/lib/roster/renderRoster.js b/package.nw/lib/roster/renderRoster.js index de3350d..0aa0aaa 100644 --- a/package.nw/lib/roster/renderRoster.js +++ b/package.nw/lib/roster/renderRoster.js @@ -31,7 +31,7 @@ function renderRoster(callRoster, rosterSettings) var totalCount = Object.keys(callRoster).length; var visibleCount = visibleCallList.length; - var huntedCount = visibleCallList.filter(obj => Object.keys(callObj.hunting).length > 0).length + var huntedCount = visibleCallList.filter(obj => Object.keys(obj.callObj.hunting).length > 0).length var countParts = []; if (totalCount != visibleCount) From df1e578d9c1d2d16b9b183d0dad8505aaf40a413 Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 22:24:32 -0500 Subject: [PATCH 13/60] fix line 73 --- package.nw/lib/roster/renderRoster.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.nw/lib/roster/renderRoster.js b/package.nw/lib/roster/renderRoster.js index 0aa0aaa..8591b44 100644 --- a/package.nw/lib/roster/renderRoster.js +++ b/package.nw/lib/roster/renderRoster.js @@ -70,7 +70,7 @@ function renderRoster(callRoster, rosterSettings) // Third loop: render all rows for (var x in visibleCallList) { - var callObj = visibleCallList[x]; + var callObj = visibleCallList[x].callObj; // TODO: This is filtering if (callObj.shouldAlert == false && onlyHits == true && callObj.qrz == false) From ed3abd26391dc8dfd818472d72abf0878ec173f0 Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 22:26:40 -0500 Subject: [PATCH 14/60] lost show bands/modes on render call rows --- package.nw/lib/roster/renderNormalRoster.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.nw/lib/roster/renderNormalRoster.js b/package.nw/lib/roster/renderNormalRoster.js index 3174d25..9b33e4e 100644 --- a/package.nw/lib/roster/renderNormalRoster.js +++ b/package.nw/lib/roster/renderNormalRoster.js @@ -85,7 +85,7 @@ function renderNormalRosterHeaders(showBands, showModes) return worker } -function renderNormalRosterRow(callObj) +function renderNormalRosterRow(callObj, showBands, showModes) { var thisCall = callObj.DEcall; var acks = window.opener.g_acknowledgedCalls; From 81b34b0dfb352c16b219f183f13521273887725a Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 22:37:49 -0500 Subject: [PATCH 15/60] fix some small stuff --- package.nw/lib/roster/renderNormalRoster.js | 4 ++-- package.nw/lib/roster/renderRoster.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.nw/lib/roster/renderNormalRoster.js b/package.nw/lib/roster/renderNormalRoster.js index 9b33e4e..c1856ed 100644 --- a/package.nw/lib/roster/renderNormalRoster.js +++ b/package.nw/lib/roster/renderNormalRoster.js @@ -134,9 +134,9 @@ function renderNormalRosterRow(callObj, showBands, showModes) ""; if (g_rosterSettings.columns.Calling) { diff --git a/package.nw/lib/roster/renderRoster.js b/package.nw/lib/roster/renderRoster.js index 8591b44..b099e5e 100644 --- a/package.nw/lib/roster/renderRoster.js +++ b/package.nw/lib/roster/renderRoster.js @@ -73,7 +73,7 @@ function renderRoster(callRoster, rosterSettings) var callObj = visibleCallList[x].callObj; // TODO: This is filtering - if (callObj.shouldAlert == false && onlyHits == true && callObj.qrz == false) + if (callObj.shouldAlert == false && rosterSettings.onlyHits == true && callObj.qrz == false) { continue; } var spotString = ""; From 17d6defe4d48c0d68a83d23aed1fe40362566cf7 Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 22:50:49 -0500 Subject: [PATCH 16/60] bunch of stuff moved to the right places --- package.nw/lib/roster/renderNormalRoster.js | 11 +++++++++++ package.nw/lib/roster/renderRoster.js | 14 +------------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/package.nw/lib/roster/renderNormalRoster.js b/package.nw/lib/roster/renderNormalRoster.js index c1856ed..43b0440 100644 --- a/package.nw/lib/roster/renderNormalRoster.js +++ b/package.nw/lib/roster/renderNormalRoster.js @@ -89,6 +89,17 @@ function renderNormalRosterRow(callObj, showBands, showModes) { var thisCall = callObj.DEcall; var acks = window.opener.g_acknowledgedCalls; + var grid = callObj.grid.length > 1 ? callObj.grid.substr(0, 4) : "-"; + + var geo = window.opener.g_worldGeoData[window.opener.g_dxccToGeoData[callObj.dxcc]]; + var cqzone = grid in window.opener.g_gridToCQZone ? window.opener.g_gridToCQZone[grid].join(", ") : "-"; + var ituzone = grid in window.opener.g_gridToITUZone ? window.opener.g_gridToITUZone[grid].join(", ") : "-"; + + var spotString = ""; + if (g_rosterSettings.columns.Spot && callObj.qrz == false) + { + spotString = getSpotString(callObj); + } var thisHash = thisCall + callObj.band + callObj.mode; var callStr = thisCall.formatCallsign() diff --git a/package.nw/lib/roster/renderRoster.js b/package.nw/lib/roster/renderRoster.js index b099e5e..a75d5a2 100644 --- a/package.nw/lib/roster/renderRoster.js +++ b/package.nw/lib/roster/renderRoster.js @@ -76,18 +76,6 @@ function renderRoster(callRoster, rosterSettings) if (callObj.shouldAlert == false && rosterSettings.onlyHits == true && callObj.qrz == false) { continue; } - var spotString = ""; - if (g_rosterSettings.columns.Spot && callObj.qrz == false) - { - spotString = getSpotString(callObj); - // TODO: This is filtering - if (g_rosterSettings.onlySpot && spotString == "") continue; - } - var grid = callObj.grid.length > 1 ? callObj.grid.substr(0, 4) : "-"; - - var geo = window.opener.g_worldGeoData[window.opener.g_dxccToGeoData[callObj.dxcc]]; - var cqzone = grid in window.opener.g_gridToCQZone ? window.opener.g_gridToCQZone[grid].join(", ") : "-"; - var ituzone = grid in window.opener.g_gridToITUZone ? window.opener.g_gridToITUZone[grid].join(", ") : "-"; var thisCall = callObj.DEcall; if (thisCall.match("^[A-Z][0-9][A-Z](/w+)?$")) @@ -104,7 +92,7 @@ function renderRoster(callRoster, rosterSettings) } } - worker += g_rosterSettings.compact ? renderCompactRosterRow(callObj) : renderNormalRosterRow(callObj) + worker += g_rosterSettings.compact ? renderCompactRosterRow(callObj) : renderNormalRosterRow(callObj, showBands, showModes) } RosterTable.innerHTML = g_rosterSettings.compact ? renderCompactRosterFooter() : renderNormalRosterFooter() From 8f77f1e30b88c8fd4d909a48d4e96397f6de7e92 Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 22:51:52 -0500 Subject: [PATCH 17/60] fix grid --- package.nw/lib/roster/renderNormalRoster.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.nw/lib/roster/renderNormalRoster.js b/package.nw/lib/roster/renderNormalRoster.js index 43b0440..509f585 100644 --- a/package.nw/lib/roster/renderNormalRoster.js +++ b/package.nw/lib/roster/renderNormalRoster.js @@ -145,9 +145,9 @@ function renderNormalRosterRow(callObj, showBands, showModes) ""; if (g_rosterSettings.columns.Calling) { From bae7255c82c3c09008e4c3fd31787febc98aee2b Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 23:08:13 -0500 Subject: [PATCH 18/60] IT WORKS! --- package.nw/lib/roster/renderRoster.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.nw/lib/roster/renderRoster.js b/package.nw/lib/roster/renderRoster.js index a75d5a2..5984ec0 100644 --- a/package.nw/lib/roster/renderRoster.js +++ b/package.nw/lib/roster/renderRoster.js @@ -95,5 +95,6 @@ function renderRoster(callRoster, rosterSettings) worker += g_rosterSettings.compact ? renderCompactRosterRow(callObj) : renderNormalRosterRow(callObj, showBands, showModes) } - RosterTable.innerHTML = g_rosterSettings.compact ? renderCompactRosterFooter() : renderNormalRosterFooter() + worker += g_rosterSettings.compact ? renderCompactRosterFooter() : renderNormalRosterFooter() + RosterTable.innerHTML = worker; } From 0cb9b7518300c37f26a198419add607679074ba1 Mon Sep 17 00:00:00 2001 From: Matthew Chambers Date: Mon, 28 Jun 2021 23:18:43 -0500 Subject: [PATCH 19/60] tweak for compact mode --- package.nw/lib/roster/renderCompactRoster.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.nw/lib/roster/renderCompactRoster.js b/package.nw/lib/roster/renderCompactRoster.js index 271a0bc..616d96b 100644 --- a/package.nw/lib/roster/renderCompactRoster.js +++ b/package.nw/lib/roster/renderCompactRoster.js @@ -16,7 +16,7 @@ function renderCompactRosterRow(callObj) (callObj.grid.length ? ", " + callObj.grid : "") + ", " + (timeNowSec() - callObj.age).toDHMS(); - worker += + var worker = "
Date: Wed, 7 Jul 2021 15:08:03 -0400 Subject: [PATCH 24/60] clear call roster on band change: option added --- package.nw/GridTracker.html | 12 ++++++++++++ package.nw/lib/defaults.js | 1 + package.nw/lib/gt.js | 6 ++++++ package.nw/lib/roster/renderRoster.js | 21 ++++++++++++++++++++- 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/package.nw/GridTracker.html b/package.nw/GridTracker.html index c15e01e..f79f356 100644 --- a/package.nw/GridTracker.html +++ b/package.nw/GridTracker.html @@ -2905,6 +2905,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
" + - grid + + callObj.grid + "" + - callObj.grid + + grid + "
+
+ + + + + + + +
Clear Call Roster on Band change
+ +
+