Merge branch 'master' into cbayer-i18n

merge-requests/182/merge
Matthew Chambers 2022-05-17 18:38:11 -05:00
commit 670001a6db
25 zmienionych plików z 1283 dodań i 1497 usunięć

1
.gitignore vendored
Wyświetl plik

@ -11,3 +11,4 @@ debian/tmp
node_modules node_modules
package-lock.json package-lock.json
.vscode .vscode
desktop.ini

Wyświetl plik

@ -10,9 +10,9 @@ variables:
# We have code in here for releasing on both GS and S3, control it through variables # We have code in here for releasing on both GS and S3, control it through variables
# on GitLab, do not change it in this file. # on GitLab, do not change it in this file.
# #
GCLOUD_PROJECT_ID: "cent7-288417"
GCLOUD_SERVICE_ACCOUNT: /dev/null GCLOUD_SERVICE_ACCOUNT: /dev/null
GCLOUD_RELEASE_DEPLOY_PATH: gs://download.gridtracker.org/release/$CI_COMMIT_TAG GCLOUD_DEPLOY_PATH: gs://gt_download/$CI_COMMIT_TAG
GCLOUD_TESTING_DEPLOY_PATH: gs://download.gridtracker.org/testing/$CI_COMMIT_TAG
NR0Q_SERVER_ADDRESS: "" NR0Q_SERVER_ADDRESS: ""
NR0Q_SERVER_PASSWORD: "" NR0Q_SERVER_PASSWORD: ""
@ -86,15 +86,18 @@ win:package:
mkdir -p artifacts mkdir -p artifacts
echo -e "\e[0Ksection_start:`date +%s`:apt_get[collapsed=true]\r\e[0KGetting Build Dependencies" echo -e "\e[0Ksection_start:`date +%s`:apt_get[collapsed=true]\r\e[0KGetting Build Dependencies"
apt-get update && apt-get upgrade -y apt-get update && apt-get upgrade -y
apt-get install p7zip -y
wget https://nsis.sourceforge.io/mediawiki/images/4/47/Registry.zip wget https://nsis.sourceforge.io/mediawiki/images/4/47/Registry.zip
unzip Registry.zip unzip -bj Registry.zip Desktop/Plugin/registry.dll -d /usr/share/nsis/Plugins/x86-unicode/
mv Desktop/Plugin/registry.dll /usr/share/nsis/Plugins/x86-unicode/ unzip -bj Registry.zip Desktop/Include/Registry.nsh -d /usr/share/nsis/Include/
mv Desktop/Include/Registry.nsh /usr/share/nsis/Include/ wget https://nsis.sourceforge.io/mediawiki/images/1/18/NsProcess.zip
rm -Rf Desktop PocketPC Source 7zr e NsProcess.zip -y -o/usr/share/nsis/Include/ Include/nsProcess.nsh
eval $(ssh-agent -s) 7zr e NsProcess.zip -y -o/usr/share/nsis/Plugins/x86-unicode/ Plugin/nsProcessW.dll
echo "$NR0Q_PRIV" | tr -d '\r' | ssh-add - mv /usr/share/nsis/Plugins/x86-unicode/nsProcessW.dll /usr/share/nsis/Plugins/x86-unicode/nsProcess.dll
mkdir -p ~/.ssh; chmod 700 ~/.ssh ## eval $(ssh-agent -s)
scp -o StrictHostKeyChecking=no mchambers@$NR0Q_SERVER_ADDRESS:~/codecert.spc ./ ## echo "$NR0Q_PRIV" | tr -d '\r' | ssh-add -
## mkdir -p ~/.ssh; chmod 700 ~/.ssh
## scp -o StrictHostKeyChecking=no -P $NR0Q_SSH_PORT mchambers@$NR0Q_SERVER_ADDRESS:~/codecert.spc ./
script: script:
- | - |
# Making our Windows packages # Making our Windows packages
@ -104,30 +107,22 @@ win:package:
npm install --prefer-offline npm install --prefer-offline
npm run dist-win npm run dist-win
for dir in dist/*-win-* ; do for dir in dist/*-win-* ; do
if [ -d $dir ] ; then if [ -f $dir ] && [[ "$dir" == *"-Setup.exe" ]] ; then
rm $dir/locales/*.info
mkdir $dir/package.nw
for file in package.nw/* ; do
mv $dir/`basename $file` $dir/package.nw
done
elif [ -f $dir ] && [[ "$dir" == *"win-x86-Setup.exe"* ]] ; then
echo "deleting broken installer $dir" echo "deleting broken installer $dir"
rm $dir rm $dir
fi fi
done done
# Now we need to sign the executable before it get's stuffed into Nullsoft # Now we need to sign the executable before it get's stuffed into Nullsoft
# using mono signcode # using mono signcode
signcode -spc codecert.spc -t http://time.certum.pl/ -a sha256 dist/GridTracker-*-win-*/*.exe ## signcode -spc codecert.spc -t http://time.certum.pl/ -a sha256 dist/GridTracker-*-win-*/*.exe
# Now the executable should be signed # Now the executable should be signed
sed "s#GridTracker-\${VERSION}-win-x86/#`pwd`/dist/GridTracker-\${VERSION}-win-x86/#g" windows/setup.nsi.tmpl > windows/setup.nsi.tmp.1 sed "s#<versionplaceholder>#`node version.js`#g" windows/win_installer.nsi > windows/setup.nsi.tmp.1
sed "s#GridTracker-Installer.#`pwd`/dist/GridTracker-Installer.#g" windows/setup.nsi.tmp.1 > windows/setup.nsi.tmp.2 sed "s#<buildplaceholder>#`pwd`#g" windows/setup.nsi.tmp.1 > windows/setup.nsi
sed "s#define VERSION <placeholder#define VERSION `node version.js`#g" windows/setup.nsi.tmp.2 > windows/setup.nsi
makensis windows/setup.nsi makensis windows/setup.nsi
# clean up generated files # clean up generated files
rm windows/setup.nsi rm windows/setup.nsi
rm windows/setup.nsi.tmp.1 rm windows/setup.nsi.tmp.1
rm windows/setup.nsi.tmp.2 ## signcode -spc codecert.spc -t http://time.certum.pl/ -a sha256 dist/GridTracker-Installer.*.exe
signcode -spc codecert.spc -t http://time.certum.pl/ -a sha256 dist/GridTracker-Installer.*.exe
(cd dist ; mv GridTracker-Installer.*.exe ../artifacts) (cd dist ; mv GridTracker-Installer.*.exe ../artifacts)
echo -e "\e[0Ksection_end:`date +%s`:native_build\e[0K" echo -e "\e[0Ksection_end:`date +%s`:native_build\e[0K"
@ -282,51 +277,20 @@ arm:package:
echo "we made ARM packages!" echo "we made ARM packages!"
ls -laR artifacts ls -laR artifacts
# copy test assets to NR0Q's server # copy test assets to Google Storage
uploadtest: upload-Google:
stage: deploy stage: deploy
image: alpine image: google/cloud-sdk
variables: variables:
GIT_STRATEGY: none GIT_STRATEGY: none
rules: rules:
- if: '$CI_COMMIT_TAG =~ /^(test_).*/ && $NR0Q_SERVER_KEY != ""' - if: '$CI_COMMIT_TAG =~ /^(v|test_).*/'
before_script:
- |
apk add openssh-client
eval $(ssh-agent -s)
echo "$NR0Q_SERVER_KEY" | tr -d '\r' | ssh-add -
mkdir -p ~/.ssh; chmod 700 ~/.ssh
script: script:
- | - |
cd artifacts echo $GCP_SERVICE_KEY > gcloud-service-key.json
for FILE in *.* gcloud auth activate-service-account --key-file gcloud-service-key.json
do gcloud config set project $GCLOUD_PROJECT_ID
echo "Calculating MD5 Hash for $FILE" gsutil -m cp -R artifacts/* $GCLOUD_DEPLOY_PATH/
md5sum $FILE > $FILE.md5
done
ssh -o StrictHostKeyChecking=no gridtracker@$NR0Q_SERVER_ADDRESS "mkdir ~/$CI_COMMIT_TAG" && scp -o StrictHostKeyChecking=no -r ./* gridtracker@$NR0Q_SERVER_ADDRESS:~/$CI_COMMIT_TAG/ && ssh -o StrictHostKeyChecking=no gridtracker@$NR0Q_SERVER_ADDRESS "rm latest_test && ln -s $CI_COMMIT_TAG latest_test"
# copy release assets to NR0Q's server
uploadrelease:
stage: deploy
image: alpine
rules:
- if: '$CI_COMMIT_TAG =~ /^(v).*/ && $NR0Q_SERVER_KEY != ""'
before_script:
- |
apk add openssh-client
eval $(ssh-agent -s)
echo "$NR0Q_SERVER_KEY" | tr -d '\r' | ssh-add -
mkdir -p ~/.ssh; chmod 700 ~/.ssh
script:
- |
cd artifacts
for FILE in *.*
do
echo "Calculating MD5 Hash for $FILE"
md5sum $FILE > $FILE.md5
done
ssh -o StrictHostKeyChecking=no gridtracker@$NR0Q_SERVER_ADDRESS "mkdir ~/$CI_COMMIT_TAG" && scp -o StrictHostKeyChecking=no -r ./* gridtracker@$NR0Q_SERVER_ADDRESS:~/$CI_COMMIT_TAG/
# this only creates a "source code release" -- gitlab doesn't specify binaries # this only creates a "source code release" -- gitlab doesn't specify binaries
# except as links to external storage, which is suboptimal for now # except as links to external storage, which is suboptimal for now
@ -346,7 +310,7 @@ sourcerelease:
assets: assets:
links: links:
- name: Release Packages for $CI_COMMIT_TAG - name: Release Packages for $CI_COMMIT_TAG
url: https://fleetwood.mchambersradio.com/gridtracker/$CI_COMMIT_TAG/ url: https://https://storage.googleapis.com/gt_download/$CI_COMMIT_TAG/
external: true external: true
link_type: package link_type: package
script: script:
@ -355,8 +319,6 @@ sourcerelease:
update_arch_aur: update_arch_aur:
stage: deploy stage: deploy
image: archlinux:base-devel image: archlinux:base-devel
variables:
GIT_STRATEGY: none
rules: rules:
# only do this with a manual tag starting with v # only do this with a manual tag starting with v
- if: '$CI_COMMIT_TAG =~ /^v.*/ && $AUR_KEY != ""' - if: '$CI_COMMIT_TAG =~ /^v.*/ && $AUR_KEY != ""'
@ -386,7 +348,7 @@ update_arch_aur:
sudo -u builder makepkg -si --noconfirm PKGBUILD sudo -u builder makepkg -si --noconfirm PKGBUILD
# push the new version # push the new version
- | - |
makepkg --printsrcinfo > .SRCINFO sudo -u builder makepkg --printsrcinfo > .SRCINFO
git clone ssh://aur@aur.archlinux.org/gridtracker.git git clone ssh://aur@aur.archlinux.org/gridtracker.git
cp PKGBUILD gridtracker/PKGBUILD cp PKGBUILD gridtracker/PKGBUILD
cp .SRCINFO gridtracker/.SRCINFO cp .SRCINFO gridtracker/.SRCINFO

Wyświetl plik

@ -41,7 +41,7 @@ Run `npm install` and then `npm start`
Phoenix does not support ARM-based macs, so we have to explicitly tell it to use Intel-based versions of NWJS. Phoenix does not support ARM-based macs, so we have to explicitly tell it to use Intel-based versions of NWJS.
Run `npm install` and then `npm start-x64` Run `npm install` and then `npm run start-x64`
## ARM-based Raspberry ## ARM-based Raspberry
@ -107,3 +107,19 @@ Final build results are left in:
# Editing GeoJSON files # Editing GeoJSON files
We've had success using https://vector.rocks/ and then cleaning up the output with https://jsonformatter.org/ We've had success using https://vector.rocks/ and then cleaning up the output with https://jsonformatter.org/
# Hacks
### Roster Column Ordering
We've added internal support for reordering roster columns, but have yet to implement a UI to change these settings.
In the meantime you can:
* Open the roster window, right click on the "More Controls" link on the top right corner and select "Inspect" from the context menu.
* Select the "Console" tab in the Chrome DevTools window that should have appeared.
* Enter `g_rosterSettings.columnOrder` in the Console and press `[return]` to see the current list of columns.
* Enter the following in the Console, changing the values of `columnOrder` to fit your needs: `changeRosterColumnOrder(["Callsign", "Grid", "Spot"]);` and press `[return]`.
Any columns included in this list will be shown before all other columns.

Wyświetl plik

@ -8,7 +8,7 @@ pkgdesc="Companion program for WSJT-X for mapping contacts"
arch=('x86_64') arch=('x86_64')
url="https://gridtracker.org/grid-tracker/" url="https://gridtracker.org/grid-tracker/"
license=('BSD') license=('BSD')
depends=('nwjs-bin>=0.48.0') depends=('nwjs-bin>=0.54.0')
replaces=('gridtracker-bin') replaces=('gridtracker-bin')
source=("https://gitlab.com/gridtracker.org/$pkgname/-/archive/v$pkgver/$pkgname-v$pkgver.tar.gz") source=("https://gitlab.com/gridtracker.org/$pkgname/-/archive/v$pkgver/$pkgname-v$pkgver.tar.gz")
sha256sums=('REPLACE_WITH_SHASUM') sha256sums=('REPLACE_WITH_SHASUM')

24
debian/changelog vendored
Wyświetl plik

@ -1,3 +1,27 @@
gridtracker (1.22.0503) unstable; urgency=low
- Increment version for build with correct NWJS version
-- Matthew Chambers <nr0q@gridtracker.org> Mon, 01 May 2022 16:07:00 -0000
gridtracker (1.22.0502) unstable; urgency=low
[Bug Fixes]
- Fixed broken Call Roster due to online assets being moved from a web server to Google Storage Bucket.
- Don't highlight "CQ" rows if filtering by "CQ Only".
- Resolved #126 Windows Installer script updated to fix issues with install location and missing registry keys
- Resolved #124 removing IP-Geolocation when no all other means of locating failed, we now tell the user to
start WSJT-X or enter a location as Geo-Location services are costly and unreliable
- Resolved #137 missing libatomic dependency in Linux DEB and RPM spec files
[Enhancements]
- Include version number in main window title
- Call Roster colums refactored and wanted column added
-- Matthew Chambers <nr0q@gridtracker.org> Mon, 01 May 2022 02:25:40 -0000
gridtracker (1.21.1217) unstable; urgency=low
- Changed to newer NWJS to fix upstream bug that caused media playback to fail.
-- Matthew Chambers <nr0q@gridtracker.org> Fri, 17 Dec 2021 20:08:00 -0000
gridtracker (1.21.1212) unstable; urgency=low gridtracker (1.21.1212) unstable; urgency=low
Release build with the call roster refactor code that's been in the works for some time. Release build with the call roster refactor code that's been in the works for some time.
[Bug Fixes] [Bug Fixes]

Wyświetl plik

@ -15,26 +15,18 @@ for dir in dist/*-linux-* ; do
fi fi
done done
for dir in dist/*-win-* ; do for dir in dist/*-win-* ; do
if [ -d $dir ] ; then if [ -f $dir ] && [[ "$dir" == *"-Setup.exe" ]] ; then
mkdir $dir/package.nw
for file in package.nw/* ; do
mv $dir/`basename $file` $dir/package.nw
done
elif [ -f $dir ] && [[ "$dir" == *"win-x86-Setup.exe"* ]] ; then
echo "deleting broken installer $dir" echo "deleting broken installer $dir"
rm $dir rm $dir
fi fi
done done
sed "s#GridTracker-\${VERSION}-win-x86/#`pwd`/dist/GridTracker-\${VERSION}-win-x86/#g" windows/setup.nsi.tmpl > windows/setup.nsi.tmp.1 sed "s#<versionplaceholder>#`node version.js`#g" windows/win_installer.nsi > windows/setup.nsi.tmp.1
sed "s#GridTracker-Installer.#`pwd`/dist/GridTracker-Installer.#g" windows/setup.nsi.tmp.1 > windows/setup.nsi.tmp.2 sed "s#<buildplaceholder>#`pwd`#g" windows/setup.nsi.tmp.1 > windows/setup.nsi
sed "s#define VERSION <placeholder#define VERSION `node version.js`#g" windows/setup.nsi.tmp.2 > windows/setup.nsi
makensis windows/setup.nsi makensis windows/setup.nsi
# clean up generated files # clean up generated files
rm windows/setup.nsi rm windows/setup.nsi
rm windows/setup.nsi.tmp.1 rm windows/setup.nsi.tmp.1
rm windows/setup.nsi.tmp.2
mv dist/*{.exe,mac-x64.zip,.tar.gz} ../dist mv dist/*{.exe,mac-x64.zip,.tar.gz} ../dist
rpmbuild -D "version `node ./version.js`" --build-in-place -bb gridtracker.i386.spec rpmbuild -D "version `node ./version.js`" --build-in-place -bb gridtracker.i386.spec

Wyświetl plik

@ -1,9 +1,9 @@
Name: gridtracker Name: {{{ git_name name=gridtracker }}}
Summary: GridTracker: An amateur radio companion to WSJT-X or JTDX Summary: GridTracker: An amateur radio companion to WSJT-X or JTDX
Version: 1.21.1212 Version: {{{ git_version lead=1.22.0503 }}}
Release: 1%{?dist} Release: 1%{?dist}
BuildArch: noarch BuildArch: noarch
Source0: %{name}-%{version}.tar.gz Source0: {{{ git_dir_pack }}}
License: BSD 3-Clause License License: BSD 3-Clause License
URL: https://gridtracker.org URL: https://gridtracker.org
@ -19,7 +19,7 @@ working interesting stations. It also will upload QSO records to multiple
logging frameworks including Logbook of the World. logging frameworks including Logbook of the World.
%prep %prep
%setup -q GridTracker {{{ git_dir_setup_macro }}}
%build %build
@ -40,6 +40,21 @@ DESTDIR=${RPM_BUILD_ROOT} make clean
%license %{_docdir}/%{name}/ %license %{_docdir}/%{name}/
%changelog %changelog
* Mon May 02 2022 Matthew Chambers <nr0q@gridtracker.org> - 1.22.0503-1
- Increment version number for build with correct vesion of NWJS
* Mon May 02 2022 Matthew Chambers <nr0q@gridtracker.org> - 1.22.0502-1
- [Bug Fixes]
- Fixed broken Call Roster due to online assets being moved from a web server to Google Storage Bucket.
- Don't highlight "CQ" rows if filtering by "CQ Only".
- Resolved #126 Windows Installer script updated to fix issues with install location and missing registry keys
- Resolved #124 removing IP-Geolocation when no all other means of locating failed, we now tell the user to
start WSJT-X or enter a location as Geo-Location services are costly and unreliable
- Resolved #137 missing libatomic dependency in Linux DEB and RPM spec files
- [Enhancements]
- Include version number in main window title
- Call Roster colums refactored and wanted column added
* Fri Dec 17 2021 Matthew Chambers <nr0q@gridtracker.org> - 1.21.1217-1
- Changed to newer NWJS to fix upstream bug that caused media playback to fail.
* Sun Dec 12 2021 Matthew Chambers <nr0q@gridtracker.org> - 1.21.1212-1 * Sun Dec 12 2021 Matthew Chambers <nr0q@gridtracker.org> - 1.21.1212-1
- Release build with the call roster refactor code that's been in the works for some time. - Release build with the call roster refactor code that's been in the works for some time.
- [Bug Fixes] - [Bug Fixes]

Wyświetl plik

@ -17,9 +17,7 @@
"dist-mac": "build --concurrent --tasks mac-x64 package.nw", "dist-mac": "build --concurrent --tasks mac-x64 package.nw",
"dist-win": "build --concurrent --tasks win-x86,win-x64 package.nw", "dist-win": "build --concurrent --tasks win-x86,win-x64 package.nw",
"distsome": "build --debug --tasks linux-x64,mac-x64 package.nw", "distsome": "build --debug --tasks linux-x64,mac-x64 package.nw",
"start": "run package.nw" "start": "run package.nw",
}, "start-x64": "run --x64 package.nw"
"dependencies": {
"banana-i18n": "^2.1.0"
} }
} }

Wyświetl plik

@ -788,6 +788,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
id="myTooltip" id="myTooltip"
style=" style="
-webkit-user-select: text; -webkit-user-select: text;
user-select: text;
background-color: black; background-color: black;
padding: 5px; padding: 5px;
text-align: center; text-align: center;
@ -1103,7 +1104,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<br /> <br />
<div <div
class="button" class="button"
onclick="require('nw.gui').Shell.openExternal('http://app.gridtracker.org/gt_print.html');" onclick="require('nw.gui').Shell.openExternal('https://storage.googleapis.com/gt_app/gt_print.html');"
> >
Print Print
</div> </div>
@ -3555,7 +3556,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>GridTracker.org!</a >GridTracker.org!</a
> >
</p> </p>
<p data-i18n="settings.about.Copyright">Copyright &copy; 2021 GridTracker.org</p> <p>Copyright &copy; 2022 GridTracker.org</p>
<img src="./gridview.png" /> <br /> <img src="./gridview.png" /> <br />
</div> </div>
</div> </div>
@ -3647,6 +3648,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<h2 data-i18n="updatePopup.noUpdate">GridTracker is up to date!</h2> <h2 data-i18n="updatePopup.noUpdate">GridTracker is up to date!</h2>
<div data-i18n="updatePopup.ok" class="button" onclick="closeUpdateToDateDiv();">OK</div> <div data-i18n="updatePopup.ok" class="button" onclick="closeUpdateToDateDiv();">OK</div>
</div> </div>
<div id="selectNodeDiv" style="-webkit-user-select: text; display: block; z-index: -10000"></div> <div id="selectNodeDiv" style="-webkit-user-select: text; user-select: text; display: block; z-index: -10000"></div>
</body> </body>
</html> </html>

Wyświetl plik

@ -1,96 +1,20 @@
{ {
"2M0SYH": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"A41MK": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"AA5KD": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"AD0WB": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"AE4ON": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"AF2V": { "AF2V": {
"badge": "img/emojis/books.png", "badge": "img/emojis/books.png",
"message": "GridTracker Documentation" "message": "GridTracker Documentation"
}, },
"AI5CA": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"AJ6RX": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"BD3OOX": { "BD3OOX": {
"badge": "img/emojis/speech.png", "badge": "img/emojis/speech.png",
"message": "GridTracker Translator" "message": "GridTracker Translator"
}, },
"CX4CD": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"DE1JPJ": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"DL6RA": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"DL9QB": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"EI8GS": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"GI1MIC": { "GI1MIC": {
"badge": "img/emojis/pizza.png", "badge": "img/emojis/pizza.png",
"message": "GridTracker Tester" "message": "GridTracker Tester"
}, },
"GM4SJB": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"HA5OLA": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"HB9HKE": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"HB9VKL": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"HI80": { "HI80": {
"badge": "img/emojis/speech.png", "badge": "img/emojis/speech.png",
"message": "GridTracker Translator" "message": "GridTracker Translator"
}, },
"I4SOI": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"IK0ZSN": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"IW2BUW": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"IW3HMH": { "IW3HMH": {
"badge": "img/emojis/logbook.png", "badge": "img/emojis/logbook.png",
"message": "Creator of Log4OM" "message": "Creator of Log4OM"
@ -99,222 +23,42 @@
"badge": "img/emojis/books.png", "badge": "img/emojis/books.png",
"message": "GridTracker Documentation" "message": "GridTracker Documentation"
}, },
"K0GUZ": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"K1JT": { "K1JT": {
"badge": "img/emojis/star.png", "badge": "img/emojis/star.png",
"message": "Creator of FT8 and WSJT-X" "message": "Creator of FT8 and WSJT-X"
}, },
"K2PF": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"K4KPG": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"K4TLS": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"K5DCC": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"K5TUX": { "K5TUX": {
"badge": "img/emojis/penguin.png", "badge": "img/emojis/penguin.png",
"message": "GridTracker Partner" "message": "GridTracker Partner"
}, },
"K6WRF": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"K7CGA": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"K7YD": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"K8VSY": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"K9AN": { "K9AN": {
"badge": "img/emojis/star.png", "badge": "img/emojis/star.png",
"message": "Co-Creator of FT8" "message": "Co-Creator of FT8"
}, },
"K9BAW": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"K9MIH": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KA0AZS": { "KA0AZS": {
"badge": "img/emojis/pizza.png", "badge": "img/emojis/pizza.png",
"message": "GridTracker Tester" "message": "GridTracker Tester"
}, },
"KA4JON": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KA7JAZ": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KB2BK": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KB2YSI": { "KB2YSI": {
"badge": "img/emojis/coffee.png", "badge": "img/emojis/coffee.png",
"message": "GridTracker Developer" "message": "GridTracker Developer"
}, },
"KB4RSM": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KB5ITC": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KB5KUY": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KC4HN": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KC7ZXY": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KD0YTE": { "KD0YTE": {
"badge": "img/emojis/pizza.png", "badge": "img/emojis/pizza.png",
"message": "GridTracker Tester" "message": "GridTracker Tester"
}, },
"KD9QGP": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KE0UL": { "KE0UL": {
"badge": "img/emojis/grandfather.png", "badge": "img/emojis/grandfather.png",
"message": "GridTracker's Grandfather" "message": "GridTracker's Grandfather"
}, },
"KE1Q": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KE4GNB": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KE4WLE": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KE8HIM": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KF5QHQ": { "KF5QHQ": {
"badge": "img/emojis/trophy.png", "badge": "img/emojis/trophy.png",
"message": "GridTracker Developer" "message": "GridTracker Developer"
}, },
"KG5RJ": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KI0Y": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KI2D": { "KI2D": {
"badge": "img/emojis/flatbread.png", "badge": "img/emojis/flatbread.png",
"message": "GridTracker Developer" "message": "GridTracker Developer"
}, },
"KJ6RJY": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KJ7KRN": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KK4WZI": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KL4NE": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KM3T": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KM4RL": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KM4TY": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KM5GN": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KM6JS": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KM6LBW": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KN4YZY": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KN6NCT": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KNC6EWM": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KO4BCN": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KQ4Y": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"KW4AU": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"LA6YJA": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"LU7DK": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"N0GTO": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"N0TTL": { "N0TTL": {
"badge": "img/emojis/star.png", "badge": "img/emojis/star.png",
"message": "Creator of GridTracker" "message": "Creator of GridTracker"
@ -327,122 +71,10 @@
"badge": "img/emojis/books.png", "badge": "img/emojis/books.png",
"message": "GridTracker Documentation" "message": "GridTracker Documentation"
}, },
"N3TQM": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"N3UGI": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"N4MCC": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"N4SFS": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"N6GEB": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"N7HQ": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"N8VWQ": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"NR0Q": { "NR0Q": {
"badge": "img/emojis/coffee.png", "badge": "img/emojis/coffee.png",
"message": "GridTracker Developer" "message": "GridTracker Developer"
}, },
"OH1LEU": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"OH3NZW": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"ON4VT": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"ON7IVE": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"OZ1LNR": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"OZ8QI": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"PA0LMA": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"PD9DP": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"SM0ONR": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"SV2RIM": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"VA3DJL": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"VA7CND": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"VE3FMQ": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"VE3HNA": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"VE4MAR": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"VE7LGP": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"VK2WJ": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"VK4OO": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"W0SP": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"W0YRE": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"W4DHK": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"W4IPA": { "W4IPA": {
"badge": "img/emojis/beer-mug.png", "badge": "img/emojis/beer-mug.png",
"message": "GridTracker Tester" "message": "GridTracker Tester"
@ -451,60 +83,8 @@
"badge": "img/emojis/pizza.png", "badge": "img/emojis/pizza.png",
"message": "GridTracker Tester" "message": "GridTracker Tester"
}, },
"W6FVO": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"W8PSP": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"W9LL": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"W9VZR": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"WA2LAN": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"WA4YA": { "WA4YA": {
"badge": "img/emojis/trophy.png", "badge": "img/emojis/trophy.png",
"message": "GridTracker Developer" "message": "GridTracker Developer"
},
"WA6JQB": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"WA8P": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"WB0SMX": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"WB5WAJ": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"WB6RJH": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"WD5FBW": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"WS4S": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
},
"ZL4CAT": {
"badge": "img/emojis/money-bag.png",
"message": "GridTracker Donor"
} }
} }

Wyświetl plik

@ -28,6 +28,8 @@
<script src="./lib/roster/renderCompactRoster.js" type="text/javascript"></script> <script src="./lib/roster/renderCompactRoster.js" type="text/javascript"></script>
<script src="./lib/roster/renderNormalRoster.js" type="text/javascript"></script> <script src="./lib/roster/renderNormalRoster.js" type="text/javascript"></script>
<script src="./lib/roster/renderRoster.js" type="text/javascript"></script> <script src="./lib/roster/renderRoster.js" type="text/javascript"></script>
<script src="./lib/roster/rosterColumns.js" type="text/javascript"></script>
<script src="./lib/roster/rosterColumnFunctions.js" type="text/javascript"></script>
<script src="./lib/roster/sendAlerts.js" type="text/javascript"></script> <script src="./lib/roster/sendAlerts.js" type="text/javascript"></script>
<script src="./lib/screens.js"></script> <script src="./lib/screens.js"></script>
</head> </head>

Wyświetl plik

@ -1,4 +1,4 @@
// GridTracker Copyright © 2021 GridTracker.org // GridTracker Copyright © 2022 GridTracker.org
// All rights reserved. // All rights reserved.
// See LICENSE for more information. // See LICENSE for more information.
@ -607,9 +607,13 @@ function lotwCallback(buffer, flag)
if (lotwQSHeader !== null) if (lotwQSHeader !== null)
{ {
if (lotwQSHeader[1].toUpperCase() == "QSORX") if (lotwQSHeader[1].toUpperCase() == "QSORX")
{ g_adifLogSettings.lastFetch.lotw_qso = lotwQSHeader[2] } {
elseif(lotwQSHeader[1].toUpperCase() == "QSL") g_adifLogSettings.lastFetch.lotw_qso = lotwQSHeader[2]
g_adifLogSettings.lastFetch.lotw_qsl = lotwQSHeader[2]; }
else if (lotwQSHeader[1].toUpperCase() == "QSL")
{
g_adifLogSettings.lastFetch.lotw_qsl = lotwQSHeader[2];
}
} }
rawAdiBuffer = cleanAndPrepADIF( rawAdiBuffer = cleanAndPrepADIF(
@ -663,39 +667,86 @@ var g_isGettingLOTW = false;
function grabLOtWLog(test) function grabLOtWLog(test)
{ {
var dLoTWQSO = Date.parse(g_adifLogSettings.lastFetch.lotw_qso); var lastQSLDateString = "";
var dLoTWQSL = Date.parse(g_adifLogSettings.lastFetch.lotw_qsl);
var tmpDate = ((new Date().getTime()) - 300);
// Be nice to LoTW and only fetch if last fetch was > 5 mins ago if (test == true && g_isGettingLOTW == false)
if ((g_isGettingLOTW == false) &&
(((isNaN(dLoTWQSO) == false) && (dLoTWQSO < tmpDate)) ||
((isNaN(dLoTWQSL) == false) && (dLoTWQSL < tmpDate))
))
{ {
var lastQSLDateString = lotwTestResult.innerHTML = "Testing";
"&qso_qsorxsince=" + g_adifLogSettings.lastFetch.lotw_qso + lastQSLDateString = "&qso_qsosince=2100-01-01";
"&qso_qslsince=" + g_adifLogSettings.lastFetch.lotw_qsl;
if (test == true)
{
lotwTestResult.innerHTML = "Testing";
lastQSLDateString = "&qso_qsosince=2100-01-01";
}
// Fetch QSOs // Fetch Test Results
getABuffer( getABuffer(
"https://lotw.arrl.org/lotwuser/lotwreport.adi?login=" + "https://lotw.arrl.org/lotwuser/lotwreport.adi?login=" +
lotwLogin.value + lotwLogin.value +
"&password=" + "&password=" +
encodeURIComponent(lotwPassword.value) + encodeURIComponent(lotwPassword.value) +
"&qso_query=1&qso_qsl=no&qso_qsldetail=yes&qso_withown=yes" + "&qso_query=1&qso_qsl=no&qso_qsldetail=yes&qso_withown=yes" +
lastQSLDateString, lastQSLDateString,
lotwCallback, lotwCallback,
test, test,
"https", "https",
443, 443,
lotwLogImg, lotwLogImg,
"g_isGettingLOTW", "g_isGettingLOTW",
150000
);
}
if (test == false)
{
setTimeout(grabLoTWQSO, 500);
setTimeout(grabLoTWQSL, 10000);
}
}
function grabLoTWQSO()
{
var dLoTWQSO = Date.parse(dateToISO8601(g_adifLogSettings.lastFetch.lotw_qso, "Z"));
var tmpDate = ((new Date().getTime()) - 300);
if ((g_isGettingLOTW == false) && ((isNaN(dLoTWQSO) == false) && (dLoTWQSO < tmpDate)))
{
// Fetch QSOs
lastQSLDateString = "&qso_qsorxsince=" + g_adifLogSettings.lastFetch.lotw_qso;
getABuffer(
"https://lotw.arrl.org/lotwuser/lotwreport.adi?login=" +
lotwLogin.value +
"&password=" +
encodeURIComponent(lotwPassword.value) +
"&qso_query=1&qso_qsl=no&qso_qsldetail=yes&qso_withown=yes" +
lastQSLDateString,
lotwCallback,
false,
"https",
443,
lotwLogImg,
"g_isGettingLOTW",
120000
);
}
}
function grabLoTWQSL()
{
var dLoTWQSL = Date.parse(dateToISO8601(g_adifLogSettings.lastFetch.lotw_qsl, "Z"));
var tmpDate = ((new Date().getTime()) - 300);
if ((g_isGettingLOTW == false) && ((isNaN(dLoTWQSL) == false) && (dLoTWQSL < tmpDate)))
{
lastQSLDateString = "&qso_qslsince=" + g_adifLogSettings.lastFetch.lotw_qsl;
getABuffer(
"https://lotw.arrl.org/lotwuser/lotwreport.adi?login=" +
lotwLogin.value +
"&password=" +
encodeURIComponent(lotwPassword.value) +
"&qso_query=1&qso_qsl=yes&qso_qsldetail=yes&qso_withown=yes" +
lastQSLDateString,
lotwCallback,
false,
"https",
443,
lotwLogImg,
"g_isGettingLOTW",
120000 120000
); );
@ -1457,11 +1508,6 @@ function getABuffer(
}) })
.on("end", function () .on("end", function ()
{ {
if (typeof callback === "function")
{
// Call it, since we have confirmed it is callable
callback(fileBuffer, flag, cookies);
}
if (typeof stringOfFlag != "undefined") if (typeof stringOfFlag != "undefined")
{ {
window[stringOfFlag] = false; window[stringOfFlag] = false;
@ -1471,6 +1517,11 @@ function getABuffer(
imgToGray.parentNode.style.background = ""; imgToGray.parentNode.style.background = "";
imgToGray.style.webkitFilter = ""; imgToGray.style.webkitFilter = "";
} }
if (typeof callback === "function")
{
// Call it, since we have confirmed it is callable
callback(fileBuffer, flag, cookies);
}
}) })
.on("error", function () .on("error", function ()
{ {
@ -1638,7 +1689,7 @@ function sendTcpMessage(msg, length, port, address)
client.setTimeout(30000); client.setTimeout(30000);
client.connect(port, address, function () client.connect(port, address, function ()
{ {
client.write(msg); client.write(Buffer.from(msg, "utf-8"));
}); });
client.on("close", function () {}); client.on("close", function () {});
@ -1647,7 +1698,7 @@ function sendTcpMessage(msg, length, port, address)
function valueToAdiField(field, value) function valueToAdiField(field, value)
{ {
var adi = "<" + field + ":"; var adi = "<" + field + ":";
adi += String(value).length + ">"; adi += Buffer.byteLength(String(value)) + ">";
adi += String(value) + " "; adi += String(value) + " ";
return adi; return adi;
} }
@ -1927,7 +1978,7 @@ function finishSendingReport(record, localMode)
for (let key in record) for (let key in record)
{ {
report += "<" + key + ":" + record[key].length + ">" + record[key] + " "; report += "<" + key + ":" + Buffer.byteLength(record[key]) + ">" + record[key] + " ";
} }
report += "<EOR>"; report += "<EOR>";
@ -2109,7 +2160,7 @@ function finishSendingReport(record, localMode)
for (var key in record) for (var key in record)
{ {
report += report +=
"<" + key + ":" + record[key].length + ">" + record[key] + " "; "<" + key + ":" + Buffer.byteLength(record[key]) + ">" + record[key] + " ";
} }
report += "<EOR>"; report += "<EOR>";
} }

Wyświetl plik

@ -279,7 +279,7 @@ function oqrsDownload(fromSettings)
{ {
oqrsUpdatedTd.innerHTML = "<b><i>Downloading...</i></b>"; oqrsUpdatedTd.innerHTML = "<b><i>Downloading...</i></b>";
getBuffer( getBuffer(
"http://app.gridtracker.org/callsigns/clublog.json", "https://storage.googleapis.com/gt_app/callsigns/clublog.json",
processoqrsCallsigns, processoqrsCallsigns,
null, null,
"http", "http",
@ -539,7 +539,7 @@ function ulsDownload()
ulsUpdatedTd.innerHTML = "<b><i>Downloading...</i></b>"; ulsUpdatedTd.innerHTML = "<b><i>Downloading...</i></b>";
ulsCountTd.innerHTML = 0; ulsCountTd.innerHTML = 0;
getChunkedBuffer( getChunkedBuffer(
"http://app.gridtracker.org/callsigns/callsigns.txt", "https://storage.googleapis.com/gt_app/callsigns/callsigns.txt",
processulsCallsigns, processulsCallsigns,
null, null,
"http", "http",

Wyświetl plik

@ -1,3 +1,9 @@
// FIXME ****************************************************************************** //
// The datepicker's "Time" section doesn't work. This really needs to be fixed before
// the next big RTTY Roundup or Field Day where there may be a lot of hams that want
// to use this feature to only reference their log starting when the contest starts.
// Which isn't always 00:00 UTC.
// ************************************************************************************ //
var picker = { var picker = {
attach: function (opt) attach: function (opt)
{ {

Wyświetl plik

@ -1,265 +1,266 @@
var validSettings = [ var validSettings = [
"HRDLogbookLogSettings", "HRDLogbookLogSettings",
"N1MMSettings", "N1MMSettings",
"acLogSettings", "acLogSettings",
"adifLogSettings", "adifLogSettings",
"alertSettings", "alertSettings",
"appSettings", "appSettings",
"audioSettings", "audioSettings",
"awardTracker", "awardTracker",
"bandActivity", "bandActivity",
"blockedCQ", "blockedCQ",
"blockedCalls", "blockedCalls",
"blockedDxcc", "blockedDxcc",
"callsignLookups", "callsignLookups",
"classicAlerts", "classicAlerts",
"classicAlertsVersion", "classicAlertsVersion",
"currentVersion", "currentVersion",
"dxkLogSettings", "dxkLogSettings",
"log4OMSettings", "log4OMSettings",
"mapMemory", "mapMemory",
"mapSettings", "mapSettings",
"msgSettings", "msgSettings",
"receptionSettings", "receptionSettings",
"rosterSettings", "rosterSettings",
"savedAlerts", "savedAlerts",
"speechSettings", "speechSettings",
"startupLogs", "startupLogs",
"trustedQslSettings", "trustedQslSettings",
"screenSettings", "screenSettings",
"legendColors" "legendColors"
]; ];
var def_appSettings = { var def_appSettings = {
alertMute: 0, alertMute: 0,
rosterAlwaysOnTop: false, rosterAlwaysOnTop: false,
centerGridsquare: "", centerGridsquare: "",
chatUUID: "", chatUUID: "",
crScript: 0, crScript: 0,
distanceUnit: "MI", distanceUnit: "MI",
earthImgSrc: 0, earthImgSrc: 0,
gridViewMode: 3, gridViewMode: 3,
gridsquareDecayTime: 300, gridsquareDecayTime: 300,
gtAgree: "", gtAgree: "",
gtBandFilter: "", gtBandFilter: "",
gtFlagImgSrc: 0, gtFlagImgSrc: 0,
gtModeFilter: "", gtModeFilter: "",
gtPropFilter: "mixed", gtPropFilter: "mixed",
gtMsgEnable: true, gtMsgEnable: true,
gtShareEnable: true, gtShareEnable: true,
heatEnabled: 0, heatEnabled: 0,
loadAdifAtStartup: false, loadAdifAtStartup: false,
lookupLoginCq: "", lookupLoginCq: "",
lookupLoginQrz: "", lookupLoginQrz: "",
lookupLoginQth: "", lookupLoginQth: "",
lookupOnTx: false, lookupOnTx: false,
lookupCloseLog: false, lookupCloseLog: false,
lookupMerge: true, lookupMerge: true,
lookupMissingGrid: false, lookupMissingGrid: false,
lookupPasswordCq: "", lookupPasswordCq: "",
lookupPasswordQrz: "", lookupPasswordQrz: "",
lookupPasswordQth: "", lookupPasswordQth: "",
lookupService: "CALLOOK", lookupService: "CALLOOK",
lookupCallookPreferred: false, lookupCallookPreferred: false,
moonPath: 0, clearRosterOnBandChange: false,
moonTrack: 0, moonPath: 0,
mouseTrack: 0, moonTrack: 0,
multicast: false, mouseTrack: 0,
myBand: "OOB", multicast: false,
myDEGrid: "", myBand: "OOB",
myDEcall: "NOCALL", myDEGrid: "",
myMode: "", myDEcall: "NOCALL",
myRawCall: "NOCALL", myMode: "",
myRawFreq: "", myRawCall: "NOCALL",
myRawGrid: "", myRawFreq: "",
pathWidthWeight: 1.0, myRawGrid: "",
pushPinMode: false, pathWidthWeight: 1.0,
qrzPathWidthWeight: 1.2, pushPinMode: false,
sixWideMode: 0, qrzPathWidthWeight: 1.2,
savedAppData: null, sixWideMode: 0,
soundCard: "default", savedAppData: null,
spotsEnabled: 0, soundCard: "default",
stopAskingVersion: false, spotsEnabled: 0,
useLocalTime: 0, stopAskingVersion: false,
wsjtForwardUdpEnable: false, useLocalTime: 0,
wsjtForwardUdpIp: "127.0.0.1", wsjtForwardUdpEnable: false,
wsjtForwardUdpPort: 2238, wsjtForwardUdpIp: "127.0.0.1",
wsjtIP: "", wsjtForwardUdpPort: 2238,
wsjtUdpPort: 0, wsjtIP: "",
workingCallsignEnable: false, wsjtUdpPort: 0,
workingCallsigns: {}, workingCallsignEnable: false,
workingDateEnable: false, workingCallsigns: {},
workingDate: 0, workingDateEnable: false,
gtSpotEnable: true workingDate: 0,
}; gtSpotEnable: true
};
var def_mapSettings = {
animate: true, var def_mapSettings = {
animateSpeed: 4, animate: true,
CQhilite: true, animateSpeed: 4,
fitQRZ: false, CQhilite: true,
focusRig: true, fitQRZ: false,
gridAlpha: 136, focusRig: true,
haltAllOnTx: true, gridAlpha: 136,
legend: true, haltAllOnTx: true,
longitude: 0.0, legend: true,
latitude: 0.0, longitude: 0.0,
loudness: 1, latitude: 0.0,
mapIndex: 19, loudness: 1,
mergeOverlay: false, mapIndex: 19,
mouseOver: true, mergeOverlay: false,
nightLoudness: 0.8, mouseOver: true,
nightMapEnable: false, nightLoudness: 0.8,
nightMapIndex: 20, nightMapEnable: false,
nightPathColor: 361, nightMapIndex: 20,
nightQrzPathColor: 1, nightPathColor: 361,
offlineMode: false, nightQrzPathColor: 1,
pathColor: 0, offlineMode: false,
qrzDxccFallback: false, pathColor: 0,
qrzPathColor: 1, qrzDxccFallback: false,
rosterTime: 120, qrzPathColor: 1,
shadow: 0.1, rosterTime: 120,
splitQSL: true, shadow: 0.1,
strikes: false, splitQSL: true,
strikesAlert: 2, strikes: false,
strikesGlobal: false, strikesAlert: 2,
strikesNotify: false, strikesGlobal: false,
trafficDecode: true, strikesNotify: false,
usNexrad: false, trafficDecode: true,
zoom: 4, usNexrad: false,
mapTrans: 0.5 zoom: 4,
}; mapTrans: 0.5
};
var def_adifLogSettings = {
menu: { var def_adifLogSettings = {
buttonAdifCheckBox: false, menu: {
buttonClubCheckBox: false, buttonAdifCheckBox: false,
buttonLOTWCheckBox: false, buttonClubCheckBox: false,
buttonQRZCheckBox: false, buttonLOTWCheckBox: false,
buttonPsk24CheckBox: true buttonQRZCheckBox: false,
}, buttonPsk24CheckBox: true
startup: { },
loadAdifCheckBox: false, startup: {
loadPsk24CheckBox: false, loadAdifCheckBox: false,
loadQRZCheckBox: false, loadPsk24CheckBox: false,
loadLOTWCheckBox: false, loadQRZCheckBox: false,
loadClubCheckBox: false, loadLOTWCheckBox: false,
loadGTCheckBox: true loadClubCheckBox: false,
}, loadGTCheckBox: true
qsolog: { },
logQRZqsoCheckBox: false, qsolog: {
logGTqsoCheckBox: true, logQRZqsoCheckBox: false,
logLOTWqsoCheckBox: false, logGTqsoCheckBox: true,
logHRDLOGqsoCheckBox: false, logLOTWqsoCheckBox: false,
logClubqsoCheckBox: false, logHRDLOGqsoCheckBox: false,
logCloudlogQSOCheckBox: false, logClubqsoCheckBox: false,
logeQSLQSOCheckBox: false logCloudlogQSOCheckBox: false,
}, logeQSLQSOCheckBox: false
nickname: { },
nicknameeQSLCheckBox: false nickname: {
}, nicknameeQSLCheckBox: false
text: { },
lotwLogin: "", text: {
clubCall: "", lotwLogin: "",
clubEmail: "", clubCall: "",
clubPassword: "", clubEmail: "",
lotwPassword: "", clubPassword: "",
lotwTrusted: "", lotwPassword: "",
lotwStation: "", lotwTrusted: "",
qrzApiKey: "", lotwStation: "",
HRDLOGCallsign: "", qrzApiKey: "",
HRDLOGUploadCode: "", HRDLOGCallsign: "",
CloudlogURL: "http://127.0.0.1/index.php/api/qso", HRDLOGUploadCode: "",
CloudlogAPI: "", CloudlogURL: "http://127.0.0.1/index.php/api/qso",
eQSLUser: "", CloudlogAPI: "",
eQSLPassword: "", eQSLUser: "",
eQSLNickname: "" eQSLPassword: "",
}, eQSLNickname: ""
downloads: {}, },
lastFetch: { downloads: {},
lotw_qso: "1970-01-01", lastFetch: {
lotw_qsl: "1970-01-01" lotw_qso: "1970-01-01",
} lotw_qsl: "1970-01-01"
}; }
};
var def_msgSettings = {
msgAlertSelect: 1, var def_msgSettings = {
msgAlertWord: "New chat message", msgAlertSelect: 1,
msgAlertMedia: "none", msgAlertWord: "New chat message",
msgFrequencySelect: 0, msgAlertMedia: "none",
msgActionSelect: 1, msgFrequencySelect: 0,
msgAwaySelect: 0, msgActionSelect: 1,
msgAwayText: "I am away from the shack at the moment" msgAwaySelect: 0,
}; msgAwayText: "I am away from the shack at the moment"
};
var def_receptionSettings = {
lastSequenceNumber: "0", // Treat as a string, it's friggin big var def_receptionSettings = {
lastDownloadTimeSec: 0, lastSequenceNumber: "0", // Treat as a string, it's friggin big
viewHistoryTimeSec: 900, lastDownloadTimeSec: 0,
viewPaths: false, viewHistoryTimeSec: 900,
pathColor: -1, viewPaths: false,
pathNightColor: 361, pathColor: -1,
spotWidth: 0.8, pathNightColor: 361,
mergeSpots: true spotWidth: 0.8,
}; mergeSpots: true
};
var def_N1MMSettings = {
enable: false, var def_N1MMSettings = {
port: 2333, enable: false,
ip: "127.0.0.1" port: 2333,
}; ip: "127.0.0.1"
var def_log4OMSettings = { };
enable: false, var def_log4OMSettings = {
port: 2236, enable: false,
ip: "127.0.0.1" port: 2236,
}; ip: "127.0.0.1"
var def_dxkLogSettings = { };
enable: false, var def_dxkLogSettings = {
port: 52000, enable: false,
ip: "127.0.0.1" port: 52000,
}; ip: "127.0.0.1"
var def_HRDLogbookLogSettings = { };
enable: false, var def_HRDLogbookLogSettings = {
port: 7826, enable: false,
ip: "127.0.0.1" port: 7826,
}; ip: "127.0.0.1"
var def_acLogSettings = { };
enable: false, var def_acLogSettings = {
port: 1100, enable: false,
ip: "127.0.0.1" port: 1100,
}; ip: "127.0.0.1"
var def_trustedQslSettings = { };
stationFile: "", var def_trustedQslSettings = {
stationFileValid: false, stationFile: "",
binaryFile: "", stationFileValid: false,
binaryFileValid: false binaryFile: "",
}; binaryFileValid: false
var def_callsignLookups = { };
lotwUseEnable: true, var def_callsignLookups = {
lotwWeeklyEnable: true, lotwUseEnable: true,
lotwLastUpdate: 0, lotwWeeklyEnable: true,
eqslUseEnable: true, lotwLastUpdate: 0,
eqslWeeklyEnable: true, eqslUseEnable: true,
eqslLastUpdate: 0, eqslWeeklyEnable: true,
ulsUseEnable: true, eqslLastUpdate: 0,
ulsWeeklyEnable: true, ulsUseEnable: true,
ulsLastUpdate: 0, ulsWeeklyEnable: true,
oqrsUseEnable: false, ulsLastUpdate: 0,
oqrsWeeklyEnable: false, oqrsUseEnable: false,
oqrsLastUpdate: 0 oqrsWeeklyEnable: false,
}; oqrsLastUpdate: 0
};
var def_bandActivity = {
lastUpdate: {}, var def_bandActivity = {
lines: {} lastUpdate: {},
}; lines: {}
};
var def_legendColors = {
QSO: "#EEEE00", var def_legendColors = {
QSL: "#EE0000", QSO: "#EEEE00",
QSX: "#1111EE", QSL: "#EE0000",
CQ: "#00FF00", QSX: "#1111EE",
CQDX: "#00FFFF", CQ: "#00FF00",
QRZ: "#FFFF00", CQDX: "#00FFFF",
QTH: "#FFA600" QRZ: "#FFFF00",
}; QTH: "#FFA600"
};

Wyświetl plik

@ -2,28 +2,14 @@
// All rights reserved. // All rights reserved.
// See LICENSE for more information. // See LICENSE for more information.
const pjson = require("./package.json"); const pjson = require("./package.json");
var gtVersion = parseInt(pjson.version.replace(/\./g, "")); var gtVersionStr = pjson.version
var gtVersion = parseInt(gtVersionStr.replace(/\./g, ""));
var gtBeta = pjson.betaVersion; var gtBeta = pjson.betaVersion;
var banana = require("../../node_modules/banana-i18n/dist/banana-i18n.js"); var banana = require("../../node_modules/banana-i18n/dist/banana-i18n.js");
var g_startVersion = 0; var g_startVersion = 0;
if (typeof localStorage.currentVersion != "undefined") { g_startVersion = localStorage.currentVersion; } if (typeof localStorage.currentVersion != "undefined") { g_startVersion = localStorage.currentVersion; }
// const messages = {
// 'en': {
// 'appname-sub-title': 'Example Application'
// },
// 'ru' : {
// 'appname-sub-title': 'Демонстрационное приложение'
// },
// 'zn' : {
// 'appname-sub-title': '业余无线电数据通信助手'
// }
// };
// const banana = new Banana('en');
// banana.load(messages);
if ( if (
typeof localStorage.currentVersion == "undefined" || typeof localStorage.currentVersion == "undefined" ||
localStorage.currentVersion != String(gtVersion) localStorage.currentVersion != String(gtVersion)
@ -132,14 +118,6 @@ function loadAllSettings()
def_adifLogSettings def_adifLogSettings
); );
g_msgSettings = loadDefaultsAndMerge("msgSettings", def_msgSettings); g_msgSettings = loadDefaultsAndMerge("msgSettings", def_msgSettings);
// one-time override of oams pop-up messages: if pop-ups disabled
// and new version, reset msgActionSelect to 1 (pop up)
if (g_msgSettings.msgActionSelect == 0 &&
String(gtVersion) != String(g_startVersion))
{
g_msgSettings.msgActionSelect = 1;
localStorage.msgSettings = JSON.stringify(g_msgSettings);
}
g_receptionSettings = loadDefaultsAndMerge( g_receptionSettings = loadDefaultsAndMerge(
"receptionSettings", "receptionSettings",
def_receptionSettings def_receptionSettings
@ -1114,7 +1092,11 @@ function addDeDx(
details.grid.length < 6 && details.grid.length < 6 &&
(details.grid.substr(0, 4) == finalGrid.substr(0, 4) || (details.grid.substr(0, 4) == finalGrid.substr(0, 4) ||
details.grid.length == 0) details.grid.length == 0)
) { details.grid = finalGrid; } )
{
details.grid = finalGrid;
details.grid4 = finalGrid.substr(0, 4);
}
} }
if (finalRSTsent.length > 0) details.RSTsent = finalRSTsent; if (finalRSTsent.length > 0) details.RSTsent = finalRSTsent;
if (finalRSTrecv.length > 0) details.RSTrecv = finalRSTrecv; if (finalRSTrecv.length > 0) details.RSTrecv = finalRSTrecv;
@ -1134,6 +1116,7 @@ function addDeDx(
{ {
details = {}; details = {};
details.grid = finalGrid; details.grid = finalGrid;
details.grid4 = finalGrid.length > 0 ? finalGrid.substr(0, 4) : "-";
details.RSTsent = finalRSTsent; details.RSTsent = finalRSTsent;
details.RSTrecv = finalRSTrecv; details.RSTrecv = finalRSTrecv;
details.msg = "-"; details.msg = "-";
@ -1175,10 +1158,9 @@ function addDeDx(
finalGrid.length > 0 finalGrid.length > 0
) )
{ {
var fourGrid = finalGrid.substr(0, 4); if (details.grid4 in g_gridToState && g_gridToState[details.grid4].length == 1)
if (fourGrid in g_gridToState && g_gridToState[fourGrid].length == 1)
{ {
details.state = g_gridToState[fourGrid][0]; details.state = g_gridToState[details.grid4][0];
} }
lookupCall = true; lookupCall = true;
} }
@ -3124,30 +3106,23 @@ function makeTitleInfo(mapWindow)
? myMode ? myMode
: g_appSettings.gtModeFilter; : g_appSettings.gtModeFilter;
var space = " "; var space = " ";
var news = "GridTracker [Band: " + band + " Mode: " + mode; var news = `GridTracker ${gtVersionStr} [Band: ${band} Mode: ${mode}`;
var end = "]"; var end = "]";
if (mapWindow) if (mapWindow)
{ {
news += " Layer: " + g_viewInfo[g_currentOverlay][1]; news += ` Layer: ${g_viewInfo[g_currentOverlay][1]}`;
} }
if (g_currentOverlay == 0 && g_appSettings.gridViewMode == 1) { return news + end; } if (g_currentOverlay == 0 && g_appSettings.gridViewMode == 1) { return news + end; }
var workline = var workline = ` - Worked ${g_viewInfo[g_currentOverlay][2]} Confirmed ${g_viewInfo[g_currentOverlay][3]}`
" - Worked " +
g_viewInfo[g_currentOverlay][2] +
" Confirmed " +
g_viewInfo[g_currentOverlay][3];
if ( if (
g_viewInfo[g_currentOverlay][2] <= g_viewInfo[g_currentOverlay][4] && g_viewInfo[g_currentOverlay][2] <= g_viewInfo[g_currentOverlay][4] &&
g_viewInfo[g_currentOverlay][4] > 0 g_viewInfo[g_currentOverlay][4] > 0
) )
{ {
end = end = ` Needed ${(g_viewInfo[g_currentOverlay][4] - g_viewInfo[g_currentOverlay][2])}]`;
" Needed " +
(g_viewInfo[g_currentOverlay][4] - g_viewInfo[g_currentOverlay][2]) +
"]";
} }
return news + workline + end; return news + workline + end;
} }
@ -5141,7 +5116,7 @@ function clearLogFilesAndCounts()
g_adifLogSettings.downloads = {}; g_adifLogSettings.downloads = {};
g_adifLogSettings.lastFetch.lotw_qso = "1940-01-01"; g_adifLogSettings.lastFetch.lotw_qso = "1940-01-01";
g_adifLogSettings.lastFetch.lotw_qsl = "1940-01-01"; g_adifLogSettings.lastFetch.lotw_qsl = "1940-01-01";
localStorage.adifLogSettings = JSON.stringify(g_adifLogSettings); saveAdifSettings();
} }
function getCurrentBandModeHTML() function getCurrentBandModeHTML()
@ -10099,7 +10074,7 @@ function renderStatsBox()
worker += worker +=
"<br/> In Section: " + "<br/> In Section: " +
scoreSection + scoreSection +
"<br/>Error Generating Stats<br/>Please take a screenshot and send to gridtracker@gmail.com"; "<br/>Error Generating Stats<br/>Please take a screenshot and send to team@gridtracker.org";
} }
setStatsDiv("statViewDiv", worker); setStatsDiv("statViewDiv", worker);
@ -11170,7 +11145,7 @@ function checkForNewVersion(showUptoDate)
if (typeof nw != "undefined") if (typeof nw != "undefined")
{ {
getBuffer( getBuffer(
"http://app.gridtracker.org/version.txt?lang=", "https://storage.googleapis.com/gt_app/version.txt",
versionCheck, versionCheck,
showUptoDate, showUptoDate,
"http", "http",
@ -11179,15 +11154,20 @@ function checkForNewVersion(showUptoDate)
} }
} }
function checkForNewAcks() function downloadAcknowledgements()
{ {
getBuffer( if (g_mapSettings.offlineMode == false)
"http://app.gridtracker.org/acknowledgements.json?lang=" + g_localeString, {
updateAcks, getBuffer(
null, "https://storage.googleapis.com/gt_app/acknowledgements.json",
http, updateAcks,
80 null,
); "http",
80
);
setTimeout(downloadAcknowledgements, 8640000);
}
} }
function renderBandActivity() function renderBandActivity()
@ -11329,7 +11309,13 @@ function pskBandActivityCallback(buffer, flag)
renderBandActivity(); renderBandActivity();
} }
/* FIXME ******************************************************************************
Should we somewhere in settings, have a checkbox to enable / disable PSK spots
specifically? We can disable the overall spots, both PSK and OAMS, and OAMS has a
checkbox in the OAMS tab. I'm thinking for the situation where I only want to
pull in OAMS spots and not PSK reporter's spots.
************************************************************************************
*/
function pskGetBandActivity() function pskGetBandActivity()
{ {
if (g_mapSettings.offlineMode == true) return; if (g_mapSettings.offlineMode == true) return;
@ -11593,14 +11579,7 @@ function updateBasedOnIni()
{ {
if (typeof nw != "undefined") if (typeof nw != "undefined")
{ {
// lets see if we can find our location the hard way alert("Location not available!\nEither start WSJT-X/JTDX or enter your grid square in the settings ");
getBuffer(
"https://api.ipstack.com/check?access_key=8c9233ec1c09861a707951ab3718a7f6&format=1",
ipLocation,
null,
"https",
443
);
} }
} }
} }
@ -12078,27 +12057,6 @@ function selectElementContents(el)
} }
} }
function ipLocation(buffer, flag)
{
var obj = JSON.parse(buffer);
if (
typeof obj != "undefined" &&
obj != null &&
typeof obj.latitude != "undefined"
)
{
g_appSettings.centerGridsquare = latLonToGridSquare(
obj.latitude,
obj.longitude
).substr(0, 6);
if (g_appSettings.centerGridsquare.length > 0)
{
homeQTHInput.value = g_appSettings.centerGridsquare;
if (ValidateGridsquare(homeQTHInput, null)) setCenterGridsquare();
}
}
}
function popupNewWindows() function popupNewWindows()
{ {
if (typeof nw != "undefined") if (typeof nw != "undefined")
@ -12741,8 +12699,29 @@ function versionCheck(buffer, flag)
function updateAcks(buffer) function updateAcks(buffer)
{ {
g_acks = JSON.parse(buffer); try
fs.writeFileSync("./data/acknowledgements.json", JSON.stringify(g_acks)); {
g_acknowledgedCalls = JSON.parse(buffer);
}
catch (e)
{
// can't write, somethings broke
}
}
function readAcksFromDisk()
{
try
{
var fileBuf = fs.readFileSync(g_NWappData + "acknowledgements.json");
var loadedData = JSON.parse(fileBuf);
// some validation here?
g_acknowledgedCalls = loadedData;
}
catch (e)
{
// file failed to load, probably not downloaded
}
} }
function onExitAppToGoWebsite() function onExitAppToGoWebsite()
@ -14608,6 +14587,7 @@ function callookResults(buffer, gridPass)
callObject.lat = results.location.latitude; callObject.lat = results.location.latitude;
callObject.lon = results.location.longitude; callObject.lon = results.location.longitude;
callObject.grid = results.location.gridsquare; callObject.grid = results.location.gridsquare;
callObject.grid4 = callObject.grid.length > 1 ? callObject.grid.substr(0, 4) : "-";
callObject.efdate = results.otherInfo.grantDate; callObject.efdate = results.otherInfo.grantDate;
callObject.expdate = results.otherInfo.expiryDate; callObject.expdate = results.otherInfo.expiryDate;
callObject.frn = results.otherInfo.frn; callObject.frn = results.otherInfo.frn;

Wyświetl plik

@ -129,6 +129,27 @@ Number.prototype.toDHMS = function ()
return val; return val;
}; };
Number.prototype.toDHMS15 = function ()
{
// round to earliest 15 seconds
var seconds = Math.floor(this / 15) * 15;
var days = Math.floor(seconds / (3600 * 24));
seconds -= days * 3600 * 24;
var hrs = Math.floor(seconds / 3600);
seconds -= hrs * 3600;
var mnts = Math.floor(seconds / 60);
seconds -= mnts * 60;
days = days ? days + "d " : "";
hrs = hrs ? hrs + "h " : "";
mnts = mnts ? mnts + "m " : "";
var first = days + hrs + mnts;
if (first == "") val = seconds + "s";
else val = first + (seconds > 0 ? seconds + "s" : "");
return val;
};
Number.prototype.toDHM = function () Number.prototype.toDHM = function ()
{ {
var seconds = this; var seconds = this;
@ -143,6 +164,8 @@ Number.prototype.toDHM = function ()
hrs = hrs ? hrs + "h " : ""; hrs = hrs ? hrs + "h " : "";
mnts = mnts || seconds ? mnts + "m " : ""; mnts = mnts || seconds ? mnts + "m " : "";
val = days + hrs + mnts; val = days + hrs + mnts;
if (val == "") val = "0m";
return val; return val;
}; };

Wyświetl plik

@ -134,8 +134,9 @@ var g_defaultSettings = {
controlsExtended: false, controlsExtended: false,
compact: false, compact: false,
settingProfiles: false, settingProfiles: false,
lastSortIndex: 6,
lastSortReverse: 1 sortColumn: "Age",
sortReverse: false
}; };
const LOGBOOK_LIVE_BAND_LIVE_MODE = "0"; const LOGBOOK_LIVE_BAND_LIVE_MODE = "0";
@ -219,11 +220,34 @@ function loadSettings()
} }
g_rosterSettings = deepmerge(g_defaultSettings, readSettings); g_rosterSettings = deepmerge(g_defaultSettings, readSettings);
if ("GT" in g_rosterSettings.columns) delete g_rosterSettings.columns.GT; fixLegacySettings();
writeRosterSettings(); writeRosterSettings();
} }
function fixLegacySettings()
{
// Not sure why, but Paul Traina added this settings cleanup in August 2020.
if ("GT" in g_rosterSettings.columns) delete g_rosterSettings.columns.GT;
// In January 2022, we refactored roster column sorting
if (g_rosterSettings.lastSortIndex)
{
g_rosterSettings.sortColumn = LEGACY_COLUMN_SORT_ID[g_rosterSettings.lastSortIndex] || "Age";
delete g_rosterSettings.lastSortIndex;
}
// In January 2022, we refactored roster column sorting
if (g_rosterSettings.lastSortReverse)
{
g_rosterSettings.sortReverse = g_rosterSettings.lastSortReverse;
delete g_rosterSettings.lastSortReverse;
}
// In January 2022, we added a `columnOrder` setting, which we need to ensure always includes all columns
g_rosterSettings.columnOrder = validateRosterColumnOrder(g_rosterSettings.columnOrder);
}
function writeRosterSettings() function writeRosterSettings()
{ {
localStorage.rosterSettings = JSON.stringify(g_rosterSettings); localStorage.rosterSettings = JSON.stringify(g_rosterSettings);
@ -266,178 +290,6 @@ 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.callObj.DEcall.localeCompare(b.callObj.DEcall);
}
function myGridCompare(a, b)
{
let gridA = a.callObj.grid ? a.callObj.grid : "0";
let gridB = b.callObj.grid ? b.callObj.grid : "0";
if (gridA > gridB) return 1;
if (gridA < gridB) return -1;
return 0;
}
function myDxccCompare(a, b)
{
return window.opener.myDxccCompare(a.callObj, b.callObj);
}
function myTimeCompare(a, b)
{
if (a.callObj.age > b.callObj.age) return 1;
if (a.callObj.age < b.callObj.age) return -1;
return 0;
}
function myLifeCompare(a, b)
{
if (a.callObj.life > b.callObj.life) return 1;
if (a.callObj.life < b.callObj.life) return -1;
return 0;
}
function mySpotCompare(a, b)
{
let cutoff = timeNowSec() - window.opener.g_receptionSettings.viewHistoryTimeSec;
if (a.callObj.spot.when <= cutoff) return -1;
if (b.callObj.spot.when <= cutoff) return 1;
let aSNR = Number(a.callObj.spot.snr);
let bSNR = Number(b.callObj.spot.snr);
if (aSNR > bSNR) return 1;
if (aSNR < bSNR) return -1;
if (a.callObj.spot.when > b.callObj.spot.when) return 1;
if (a.callObj.spot.when < b.callObj.spot.when) return -1;
return 0;
}
function myDbCompare(a, b)
{
if (a.callObj.RSTsent > b.callObj.RSTsent) return 1;
if (a.callObj.RSTsent < b.callObj.RSTsent) return -1;
return 0;
}
function myFreqCompare(a, b)
{
if (a.callObj.delta > b.callObj.delta) return 1;
if (a.callObj.delta < b.callObj.delta) return -1;
return 0;
}
function myDTCompare(a, b)
{
if (a.callObj.dt > b.callObj.dt) return 1;
if (a.callObj.dt < b.callObj.dt) return -1;
return 0;
}
function myDistanceCompare(a, b)
{
if (a.callObj.distance > b.callObj.distance) return 1;
if (a.callObj.distance < b.callObj.distance) return -1;
return 0;
}
function myHeadingCompare(a, b)
{
if (a.callObj.heading > b.callObj.heading) return 1;
if (a.callObj.heading < b.callObj.heading) return -1;
return 0;
}
function myStateCompare(a, b)
{
if (a.callObj.state == null) return 1;
if (b.callObj.state == null) return -1;
if (a.callObj.state > b.callObj.state) return 1;
if (a.callObj.state < b.callObj.state) return -1;
return 0;
}
function myCQCompare(a, b)
{
return a.callObj.DXcall.localeCompare(b.callObj.DXcall);
}
function myWPXCompare(a, b)
{
if (a.callObj.px == null) return 1;
if (b.callObj.px == null) return -1;
if (a.callObj.px > b.callObj.px) return 1;
if (a.callObj.px < b.callObj.px) return -1;
return 0;
}
function myCntyCompare(a, b)
{
if (a.callObj.cnty == null) return 1;
if (b.callObj.cnty == null) return -1;
if (a.callObj.cnty.substr(3) > b.callObj.cnty.substr(3)) return 1;
if (a.callObj.cnty.substr(3) < b.callObj.cnty.substr(3)) return -1;
return 0;
}
function myContCompare(a, b)
{
if (a.callObj.cont == null) return 1;
if (b.callObj.cont == null) return -1;
if (a.callObj.cont > b.callObj.cont) return 1;
if (a.callObj.cont < b.callObj.cont) return -1;
return 0;
}
function myGTCompare(a, b)
{
if (a.callObj.style.gt != 0 && b.callObj.style.gt == 0) return 1;
if (a.callObj.style.gt == 0 && b.callObj.style.gt != 0) return -1;
return 0;
}
function showRosterBox(sortIndex)
{
if (g_rosterSettings.lastSortIndex != sortIndex)
{
g_rosterSettings.lastSortIndex = sortIndex;
g_rosterSettings.lastSortReverse = 0;
}
else
{
g_rosterSettings.lastSortReverse ^= 1;
}
writeRosterSettings();
window.opener.goProcessRoster();
}
function hashMaker(start, callObj, reference) function hashMaker(start, callObj, reference)
{ {
if (reference == LOGBOOK_LIVE_BAND_LIVE_MODE) return `${start}${callObj.band}${callObj.mode}`; if (reference == LOGBOOK_LIVE_BAND_LIVE_MODE) return `${start}${callObj.band}${callObj.mode}`;
@ -524,7 +376,7 @@ function getSpotString(callObj)
{ {
when = timeNowSec() - callObj.spot.when; when = timeNowSec() - callObj.spot.when;
if (when <= window.opener.g_receptionSettings.viewHistoryTimeSec) if (when <= window.opener.g_receptionSettings.viewHistoryTimeSec)
{ result = parseInt(when).toDHMS(); } { result = parseInt(when).toDHM(); }
} }
if (result) result += " / " + callObj.spot.snr; if (result) result += " / " + callObj.spot.snr;
return result; return result;
@ -1308,7 +1160,7 @@ function stateChangedValue(what)
{ {
let callState = r_currentUSState.replace("CN-", ""); let callState = r_currentUSState.replace("CN-", "");
getBuffer( getBuffer(
"http://app.gridtracker.org/callsigns/" + callState + ".callsigns.json", "https://storage.googleapis.com/gt_app/callsigns/" + callState + ".callsigns.json",
callsignResult, callsignResult,
r_currentUSState, r_currentUSState,
"http", "http",
@ -1674,7 +1526,7 @@ function init()
if (window.opener.g_mapSettings.offlineMode == false) if (window.opener.g_mapSettings.offlineMode == false)
{ {
getBuffer( getBuffer(
"http://app.gridtracker.org/callsigns/manifest.json", "https://storage.googleapis.com/gt_app/callsigns/manifest.json",
manifestResult, manifestResult,
null, null,
"http", "http",
@ -1852,8 +1704,10 @@ function init()
item = new nw.MenuItem({ type: "separator" }); item = new nw.MenuItem({ type: "separator" });
g_menu.append(item); g_menu.append(item);
for (let key in g_rosterSettings.columns) for (let columnIndex in g_rosterSettings.columnOrder)
{ {
let key = g_rosterSettings.columnOrder[columnIndex];
let itemx = new nw.MenuItem({ let itemx = new nw.MenuItem({
type: "checkbox", type: "checkbox",
label: key, label: key,

Wyświetl plik

@ -117,12 +117,12 @@ function processRosterHunting(callRoster, rosterSettings)
{ {
callObj.callFlags.oams = true; callObj.callFlags.oams = true;
// grab the CID // grab the CID
colorObject.gt = window.opener.g_gtCallsigns[callsign]; callObj.gt = window.opener.g_gtCallsigns[callsign];
hasGtPin = true; hasGtPin = true;
} }
else else
{ {
colorObject.gt = 0; callObj.gt = 0;
} }
// We only do hunt highlighting when showing all entries // We only do hunt highlighting when showing all entries
@ -652,7 +652,7 @@ function processRosterHunting(callRoster, rosterSettings)
callingBg = "#0000FF" + inversionAlpha; callingBg = "#0000FF" + inversionAlpha;
calling = "#FFFF00;text-shadow: 0px 0px 2px #FFFF00"; calling = "#FFFF00;text-shadow: 0px 0px 2px #FFFF00";
} }
else if (callObj.CQ == true) else if (callObj.CQ == true && !g_rosterSettings.cqOnly)
{ {
callingBg = calling + inversionAlpha; callingBg = calling + inversionAlpha;
calling = bold; calling = bold;

Wyświetl plik

@ -1,413 +1,27 @@
function renderNormalRosterHeaders(showBands, showModes) function renderNormalRosterHeaders(columns)
{ {
let worker = "" let html = "<table id='callTable' class='rosterTable' align=left><thead>"
worker = "<table id='callTable' class='rosterTable' align=left>"; html = html + columns.map(column => renderHeaderForColumn(column)).join("\n")
html = html + "</thead><tbody>"
worker += "<thead><th style='cursor:pointer;' onclick='showRosterBox(0);' align=left>Callsign</th>"; return html
if (showBands)
{ worker += "<th onclick='' >Band</th>"; }
if (showModes)
{ worker += "<th onclick='' >Mode</th>"; }
worker += "<th style='cursor:pointer;' onclick='showRosterBox(1);' >Grid</th>";
if (g_rosterSettings.columns.Calling)
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(10);' >Calling</th>"; }
if (g_rosterSettings.columns.Msg)
{ worker += "<th >Msg</th>"; }
if (g_rosterSettings.columns.DXCC)
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(5);' >DXCC</th>"; }
if (g_rosterSettings.columns.Flag)
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(5);' >Flag</th>"; }
if (g_rosterSettings.columns.State)
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(9);' >State</th>"; }
if (g_rosterSettings.columns.County)
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(15);' >County</th>"; }
if (g_rosterSettings.columns.Cont)
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(16);' >Cont</th>"; }
if (g_rosterSettings.columns.dB)
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(2);' >dB</th>"; }
if (g_rosterSettings.columns.Freq)
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(4);' >Freq</th>"; }
if (g_rosterSettings.columns.DT)
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(3);' >DT</th>"; }
if (g_rosterSettings.columns.Dist)
{
worker += "<th style='cursor:pointer;' onclick='showRosterBox(7);' >Dist(" +
window.opener.distanceUnit.value.toLowerCase() + ")</th>";
}
if (g_rosterSettings.columns.Azim)
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(8);' >Azim</th>"; }
if (g_rosterSettings.columns.CQz)
{ worker += "<th>CQz</th>"; }
if (g_rosterSettings.columns.ITUz)
{ worker += "<th>ITUz</th>"; }
if (g_rosterSettings.columns.PX)
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(11);'>PX</th>"; }
if (window.opener.g_callsignLookups.lotwUseEnable == true && g_rosterSettings.columns.LoTW)
{ worker += "<th >LoTW</th>"; }
if (window.opener.g_callsignLookups.eqslUseEnable == true && g_rosterSettings.columns.eQSL)
{ worker += "<th >eQSL</th>"; }
if (window.opener.g_callsignLookups.oqrsUseEnable == true && g_rosterSettings.columns.OQRS)
{ worker += "<th >OQRS</th>"; }
if (g_rosterSettings.columns.Spot)
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(13);' >Spot</th>"; }
if (g_rosterSettings.columns.Life)
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(12);' >Life</th>"; }
if (g_rosterSettings.columns.OAMS)
{ worker += "<th title='Off-Air Message User' style='cursor:pointer;' onclick='showRosterBox(14);'>OAMS</th>"; }
if (g_rosterSettings.columns.Age)
{ worker += "<th style='cursor:pointer;' onclick='showRosterBox(6);' >Age</th></thead>"; }
return worker
} }
function renderNormalRosterRow(callObj, showBands, showModes) function renderNormalRosterRow(columns, callObj)
{ {
let thisCall = callObj.DEcall; callObj.grid4 = callObj.grid4 || (callObj.grid && callObj.grid.length > 1) ? callObj.grid.substr(0, 4) : "-";
let acks = window.opener.g_acknowledgedCalls; callObj.hash = callObj.hash || `${callObj.DEcall}${callObj.band}${callObj.mode}`;
let grid = callObj.grid.length > 1 ? callObj.grid.substr(0, 4) : "-";
let geo = window.opener.g_worldGeoData[window.opener.g_dxccToGeoData[callObj.dxcc]]; let html = `<tr id='${callObj.hash}'>`;
let cqzone = grid in window.opener.g_gridToCQZone ? window.opener.g_gridToCQZone[grid].join(", ") : "-";
let ituzone = grid in window.opener.g_gridToITUZone ? window.opener.g_gridToITUZone[grid].join(", ") : "-";
let spotString = ""; html = html + columns.map(column => renderEntryForColumn(column, callObj)).join("\n")
if (g_rosterSettings.columns.Spot && callObj.qrz == false)
{
spotString = getSpotString(callObj);
}
let thisHash = thisCall + callObj.band + callObj.mode; html += "</tr>";
let callStr = thisCall.formatCallsign()
if (acks[thisCall])
{
callStr = `${callStr} <span class='acknowledged'><img class='ackBadge' src='${acks[thisCall].badge}'></span>`
callObj.awardReason += ` - ${acks[thisCall].message}`
}
let worker = "<tbody><tr id='" + thisHash + "'>"; return html;
worker +=
"<td title='" +
callObj.awardReason +
"' name='Callsign' align=left " +
callObj.style.call +
" onClick='initiateQso(\"" +
thisCall +
callObj.band +
callObj.mode +
"\")'>" +
callStr +
"</td>";
if (showBands)
{
worker +=
"<td style='color:#" +
window.opener.g_pskColors[callObj.band] +
"' >" +
callObj.band +
"</td>";
}
if (showModes)
{
let color = "888888";
if (callObj.mode in g_modeColors)
{ color = g_modeColors[callObj.mode]; }
worker +=
"<td style='color:#" + color + "' >" + callObj.mode + "</td>";
}
worker +=
"<td " +
callObj.style.grid +
" onClick='centerOn(\"" +
grid +
"\")' >" +
grid +
"</td>";
if (g_rosterSettings.columns.Calling)
{
let lookString = callObj.CQ ? "name='CQ'" : "name='Calling'";
worker +=
"<td " +
callObj.style.calling +
" " +
lookString +
">" +
callObj.DXcall.formatCallsign() +
"</td>";
}
if (g_rosterSettings.columns.Msg)
{ worker += "<td>" + callObj.msg + "</td>"; }
if (g_rosterSettings.columns.DXCC)
{
worker +=
"<td title='" + window.opener.g_worldGeoData[window.opener.g_dxccToGeoData[callObj.dxcc]].pp +
"' name='DXCC (" +
callObj.dxcc +
")' " +
callObj.style.dxcc +
">" +
window.opener.g_dxccToAltName[callObj.dxcc] + "</td>";
}
if (g_rosterSettings.columns.Flag)
{
worker +=
"<td align='center' style='margin:0;padding:0'><img style='padding-top:3px' src='./img/flags/16/" +
geo.flag +
"'></td>";
}
if (g_rosterSettings.columns.State)
{
worker +=
"<td align='center' " +
callObj.style.state +
" >" +
(callObj.state ? callObj.state.substr(3) : "") +
"</td>";
}
if (g_rosterSettings.columns.County)
{
worker +=
"<td align='center' " +
callObj.style.cnty +
" " +
(callObj.cnty
? (callObj.qual
? ""
: "title='ZIP Code matches multiple counties, click to do a full lookup' " +
"onClick='window.opener.lookupCallsign(\"" +
thisCall +
"\",\"" +
grid +
"\")'"
)
: "") +
">" +
(callObj.cnty
? (callObj.qual ? "" : "¿ ") +
window.opener.g_cntyToCounty[callObj.cnty] +
(callObj.qual ? "" : " ?")
: "") +
"</td>";
}
if (g_rosterSettings.columns.Cont)
{
worker +=
"<td align='center' " +
callObj.style.cont +
" >" +
(callObj.cont ? callObj.cont : "") +
"</td>";
}
if (g_rosterSettings.columns.dB)
{
worker +=
"<td style='color:#DD44DD'><b>" +
callObj.RSTsent +
"</b></td>";
}
if (g_rosterSettings.columns.Freq)
{ worker += "<td style='color:#00FF00'>" + callObj.delta + "</td>"; }
if (g_rosterSettings.columns.DT)
{ worker += "<td style='color:#1E90FF'>" + callObj.dt + "</td>"; }
if (g_rosterSettings.columns.Dist)
{
worker +=
"<td style='color:cyan'>" +
parseInt(
callObj.distance *
MyCircle.validateRadius(window.opener.distanceUnit.value)
) +
"</td>";
}
if (g_rosterSettings.columns.Azim)
{
worker +=
"<td style='color:yellow'>" +
parseInt(callObj.heading) +
"</td>";
}
if (g_rosterSettings.columns.CQz)
{
worker +=
"<td name='CQz' " +
callObj.style.cqz +
">" +
callObj.cqza.join(",") +
"</td>";
}
if (g_rosterSettings.columns.ITUz)
{
worker +=
"<td name='ITUz'" +
callObj.style.ituz +
">" +
callObj.ituza.join(",") +
"</td>";
}
if (g_rosterSettings.columns.PX)
{
worker +=
"<td " +
callObj.style.px +
">" +
(callObj.px ? callObj.px : "") +
"</td>";
}
if (
window.opener.g_callsignLookups.lotwUseEnable == true &&
g_rosterSettings.columns.LoTW
)
{
if (thisCall in window.opener.g_lotwCallsigns)
{
if (g_rosterSettings.maxLoTW < 27)
{
let months = (g_day - window.opener.g_lotwCallsigns[thisCall]) / 30;
if (months > g_rosterSettings.maxLoTW)
{
worker +=
"<td style='color:yellow' align='center' title='Has not uploaded a QSO in " +
Number(months).toYM() +
"'>?</td>";
}
else
{
worker +=
"<td style='color:#0F0' align='center' title=' Last Upload&#10;" +
window.opener.userDayString(
window.opener.g_lotwCallsigns[thisCall] * 86400000
) +
"'>&#10004;</td>";
}
}
else
{
worker +=
"<td style='color:#0F0' align='center' title=' Last Upload&#10;" +
window.opener.userDayString(
window.opener.g_lotwCallsigns[thisCall] * 86400000
) +
"'>&#10004;</td>";
}
}
else worker += "<td></td>";
}
if (
window.opener.g_callsignLookups.eqslUseEnable == true &&
g_rosterSettings.columns.eQSL
)
{
worker +=
"<td style='color:#0F0;' align='center'>" +
(thisCall in window.opener.g_eqslCallsigns ? "&#10004;" : "") +
"</td>";
}
if (
window.opener.g_callsignLookups.oqrsUseEnable == true &&
g_rosterSettings.columns.OQRS
)
{
worker +=
"<td style='color:#0F0;' align='center'>" +
(thisCall in window.opener.g_oqrsCallsigns ? "&#10004;" : "") +
"</td>";
}
if (g_rosterSettings.columns.Spot)
{
worker +=
"<td style='color:#EEE;' class='spotCol' id='sp" +
thisCall +
callObj.band +
callObj.mode +
"'>" +
spotString +
"</td>";
}
if (g_rosterSettings.columns.Life)
{
worker +=
"<td style='color:#EEE;' class='lifeCol' id='lm" +
thisCall +
callObj.band +
callObj.mode +
"'>" +
(timeNowSec() - callObj.life).toDHMS() +
"</td>";
}
if (g_rosterSettings.columns.OAMS)
{
if (callObj.style.gt != 0)
{
if (callObj.reason.includes("oams"))
{
worker +=
"<td align='center' style='margin:0;padding:0;cursor:pointer;background-clip:content-box;box-shadow: 0 0 4px 4px inset #2222FFFF;' onClick='openChatToCid(\"" +
callObj.style.gt +
"\")'><img height='16px' style='' src='./img/gt_chat.png'></td>";
}
else
{
worker +=
"<td align='center' style='margin:0;padding:0;cursor:pointer;' onClick='openChatToCid(\"" +
callObj.style.gt +
"\")'><img height='16px' style='' src='./img/gt_chat.png'></td>";
}
}
else worker += "<td></td>";
}
if (g_rosterSettings.columns.Age)
{
worker +=
"<td style='color:#EEE' class='timeCol' id='tm" +
thisCall +
callObj.band +
callObj.mode +
"'>" +
(timeNowSec() - callObj.age).toDHMS() +
"</td>";
}
worker += "</tr></tbody>";
return worker;
} }
function renderNormalRosterFooter() function renderNormalRosterFooter()
{ {
return "</table>"; return "</tbody></table>";
} }

Wyświetl plik

@ -1,12 +1,38 @@
function renderRoster(callRoster, rosterSettings) function renderRoster(callRoster, rosterSettings)
{ {
// eQSL - function let columnOverrides = {
if (window.opener.g_callsignLookups.eqslUseEnable == true) useseQSLDiv.style.display = ""; Callsign: true,
else useseQSLDiv.style.display = "none"; Grid: true
}
// OQRS - function if (window.opener.g_callsignLookups.eqslUseEnable == true)
if (window.opener.g_callsignLookups.oqrsUseEnable == true) usesOQRSDiv.style.display = ""; {
else usesOQRSDiv.style.display = "none"; useseQSLDiv.style.display = "";
}
else
{
columnOverrides.eQSL = false;
useseQSLDiv.style.display = "none";
}
if (window.opener.g_callsignLookups.oqrsUseEnable == true)
{
usesOQRSDiv.style.display = "";
}
else
{
columnOverrides.OQRS = false;
usesOQRSDiv.style.display = "none";
}
if (window.opener.g_callsignLookups.lotwUseEnable == true)
{
// Do nothing
}
else
{
columnOverrides.LoTW = false;
}
// dealing with spots // dealing with spots
if (g_rosterSettings.columns.Spot == true) onlySpotDiv.style.display = ""; if (g_rosterSettings.columns.Spot == true) onlySpotDiv.style.display = "";
@ -67,24 +93,23 @@ function renderRoster(callRoster, rosterSettings)
window.document.title = `Call Roster: ${countParts.join(" • ")}`; window.document.title = `Call Roster: ${countParts.join(" • ")}`;
if (g_rosterSettings.compact == false) if (g_rosterSettings.compact)
{ {
visibleCallList.sort(r_sortFunction[g_rosterSettings.lastSortIndex]); sortCallList(visibleCallList, "Age", false);
if (g_rosterSettings.lastSortReverse == 1)
{
visibleCallList.reverse();
}
} }
else else
{ {
// Age sort for now... make this happen Tag sortCallList(visibleCallList, g_rosterSettings.sortColumn, g_rosterSettings.sortReverse);
visibleCallList.sort(r_sortFunction[6]).reverse();
} }
let showBands = (Object.keys(rosterSettings.bands).length > 1) || g_rosterSettings.columns.Band; let showBands = (Object.keys(rosterSettings.bands).length > 1) || g_rosterSettings.columns.Band;
let showModes = (Object.keys(rosterSettings.modes).length > 1) || g_rosterSettings.columns.Mode; let showModes = (Object.keys(rosterSettings.modes).length > 1) || g_rosterSettings.columns.Mode;
let worker = g_rosterSettings.compact ? renderCompactRosterHeaders() : renderNormalRosterHeaders(showBands, showModes) columnOverrides.Band = showBands
columnOverrides.Mode = showModes
const rosterColumns = rosterColumnList(g_rosterSettings.columns, columnOverrides)
let worker = g_rosterSettings.compact ? renderCompactRosterHeaders() : renderNormalRosterHeaders(rosterColumns)
// Third loop: render all rows // Third loop: render all rows
for (let x in visibleCallList) for (let x in visibleCallList)
@ -95,11 +120,9 @@ function renderRoster(callRoster, rosterSettings)
if (callObj.shouldAlert == false && rosterSettings.onlyHits == true && callObj.qrz == false) if (callObj.shouldAlert == false && rosterSettings.onlyHits == true && callObj.qrz == false)
{ continue; } { continue; }
let thisCall = callObj.DEcall; if (callObj.DEcall.match("^[A-Z][0-9][A-Z](/w+)?$"))
if (thisCall.match("^[A-Z][0-9][A-Z](/w+)?$"))
{ callObj.style.call = "class='oneByOne'"; } { callObj.style.call = "class='oneByOne'"; }
if (thisCall == window.opener.g_instances[callObj.instance].status.DXcall) if (callObj.DEcall == window.opener.g_instances[callObj.instance].status.DXcall)
{ {
if (window.opener.g_instances[callObj.instance].status.TxEnabled == 1) if (window.opener.g_instances[callObj.instance].status.TxEnabled == 1)
{ {
@ -111,7 +134,7 @@ function renderRoster(callRoster, rosterSettings)
} }
} }
worker += g_rosterSettings.compact ? renderCompactRosterRow(callObj) : renderNormalRosterRow(callObj, showBands, showModes) worker += g_rosterSettings.compact ? renderCompactRosterRow(callObj) : renderNormalRosterRow(rosterColumns, callObj)
} }
worker += g_rosterSettings.compact ? renderCompactRosterFooter() : renderNormalRosterFooter() worker += g_rosterSettings.compact ? renderCompactRosterFooter() : renderNormalRosterFooter()

Wyświetl plik

@ -0,0 +1,95 @@
function rosterColumnList(settings = {}, overrides = {})
{
return g_rosterSettings.columnOrder.filter(column =>
{
return column && (settings[column] || overrides[column]) && !(overrides[column] === false)
})
}
function renderHeaderForColumn(column)
{
const columnInfo = ROSTER_COLUMNS[column]
let attrs = (columnInfo && columnInfo.tableHeader && columnInfo.tableHeader()) || {}
attrs.html = attrs.html || column
if (columnInfo.compare)
{
attrs.style = "cursor: pointer"
attrs.onClick = `setRosterSorting('${column}');`
}
return renderRosterTableHTML("th", attrs)
}
function renderEntryForColumn(column, entry)
{
const columnInfo = ROSTER_COLUMNS[column]
let attrs = (columnInfo && columnInfo.tableData && columnInfo.tableData(entry)) || {}
return renderRosterTableHTML("td", attrs)
}
function renderRosterTableHTML(tag, attrs)
{
let innerHtml = attrs.html || ""
delete attrs.html
let rawAttrs = attrs.rawAttrs || ""
delete attrs.rawAttrs
let attrEntries = Object.entries(attrs).filter(kv => !!kv[1])
return `<${tag} ${rawAttrs} ${attrEntries.map((kv) => `${kv[0]}="${kv[1].replace(/"/g, "&quot;")}"`).join(" ")}>${innerHtml}</${tag}>`
}
function setRosterSorting(column)
{
if (g_rosterSettings.sortColumn === column)
{
g_rosterSettings.sortReverse = !g_rosterSettings.sortReverse
}
else
{
g_rosterSettings.sortColumn = column
g_rosterSettings.sortReverse = false
}
writeRosterSettings();
window.opener.goProcessRoster();
}
function sortCallList(callList, sortColumn, sortReverse)
{
const columnInfo = ROSTER_COLUMNS[sortColumn]
callList.sort((columnInfo && columnInfo.compare) || ROSTER_COLUMNS.Age.compare)
if (sortReverse)
{
callList.reverse()
}
}
function validateRosterColumnOrder(columns)
{
let correctedColumnOrder = (columns || DEFAULT_COLUMN_ORDER || []).slice();
DEFAULT_COLUMN_ORDER.forEach(column =>
{
if (!correctedColumnOrder.includes(column)) correctedColumnOrder.push(column);
})
correctedColumnOrder = correctedColumnOrder.filter(column => !!ROSTER_COLUMNS[column])
return correctedColumnOrder;
}
function changeRosterColumnOrder(columns)
{
g_rosterSettings.columnOrder = validateRosterColumnOrder(columns);
writeRosterSettings();
window.opener.goProcessRoster();
}

Wyświetl plik

@ -0,0 +1,378 @@
const DEFAULT_COLUMN_ORDER = [
"Callsign", "Band", "Mode", "Grid", "Calling", "Msg",
"DXCC", "Flag", "State", "County", "Cont",
"dB", "Freq", "DT", "Dist", "Azim",
"CQz", "ITUz", "PX",
"LoTW", "eQSL", "OQRS",
"Life", "Spot", "OAMS", "Age"
]
const LEGACY_COLUMN_SORT_ID = {
0: "Callsign",
1: "Grid",
2: "dB",
3: "DT",
4: "Freq",
5: "DXCC",
7: "Dist",
8: "Azim",
9: "State",
10: "Calling",
11: "PX",
12: "Life",
13: "Spot",
14: "OAMS",
15: "County",
16: "Cont"
}
const getterSimpleComparer = (getter) => (a, b) =>
{
const aVal = getter(a);
const bVal = getter(b);
if (aVal == null) return 1;
if (bVal == null) return -1;
if (aVal > bVal) return 1;
if (aVal < bVal) return -1;
return 0;
}
const callObjSimpleComparer = (attr) => getterSimpleComparer((elem) => elem.callObj[attr])
const callObjLocaleComparer = (attr) => (a, b) =>
{
if (a.callObj[attr] == null) return 1;
if (b.callObj[attr] == null) return -1;
return a.callObj[attr].localeCompare(b.callObj[attr]);
}
const ROSTER_COLUMNS = {
Callsign: {
compare: callObjLocaleComparer("DEcall"),
tableHeader: () => ({ align: "left" }),
tableData: (callObj) =>
{
let attrs = {
title: callObj.awardReason,
name: "Callsign",
align: "left",
onClick: `initiateQso("${callObj.hash}")`,
rawAttrs: callObj.style.call,
html: html = callObj.DEcall.formatCallsign()
}
let acks = window.opener.g_acknowledgedCalls;
if (acks[callObj.DEcall])
{
attrs.html = `${attrs.html} <span class='acknowledged'><img class='ackBadge' src='${acks[callObj.DEcall].badge}'></span>`
attrs.title = `${attrs.title} - ${acks[callObj.DEcall].message}`
}
return attrs
}
},
Band: {
compare: false,
tableData: (callObj) => ({
style: `color: #${window.opener.g_pskColors[callObj.band]};`,
html: callObj.band
})
},
Mode: {
compare: false,
tableData: (callObj) => ({
style: `color: #${g_modeColors[callObj.mode] || "888888"};`,
html: callObj.mode
})
},
Grid: {
compare: callObjSimpleComparer("grid"),
tableData: (callObj) => ({
rawAttrs: callObj.style.grid,
onClick: `centerOn("${callObj.grid4}")`,
html: callObj.grid4
})
},
Calling: {
compare: callObjLocaleComparer("DXcall"),
tableData: (callObj) => ({
rawAttrs: callObj.style.calling,
name: callObj.CQ ? "CQ" : "Calling",
html: callObj.DXcall.formatCallsign()
})
},
Msg: {
compare: callObjLocaleComparer("DXcall"),
tableData: (callObj) => ({ html: callObj.msg })
},
DXCC: {
compare: (a, b) => window.opener.myDxccCompare(a.callObj, b.callObj),
tableData: (callObj) => ({
title: window.opener.g_worldGeoData[window.opener.g_dxccToGeoData[callObj.dxcc]].pp,
name: `DXCC (${callObj.dxcc})`,
rawAttrs: callObj.style.dxcc,
html: window.opener.g_dxccToAltName[callObj.dxcc]
})
},
Flag: {
compare: (a, b) => window.opener.myDxccCompare(a.callObj, b.callObj),
tableData: (callObj) => ({
align: "center",
style: "margin:0; padding:0;",
html: `<img style='padding-top:3px' src='./img/flags/16/${window.opener.g_worldGeoData[window.opener.g_dxccToGeoData[callObj.dxcc]].flag}'>`
})
},
State: {
compare: callObjSimpleComparer("state"),
tableData: (callObj) => ({
align: "center",
rawAttrs: callObj.style.state,
html: callObj.state ? callObj.state.substr(3) : ""
})
},
County: {
// Not sure why this comparison uses substring, but this is what the original code did
compare: getterSimpleComparer((elem) => elem.callObj.cnty && elem.callObj.cnty.substr(3)),
tableData: (callObj) =>
{
let attrs = {
align: "center",
rawAttrs: callObj.style.cnty,
html: callObj.cnty ? window.opener.g_cntyToCounty[callObj.cnty] : ""
}
if (callObj.cnty && callObj.qual)
{
attrs.title = "ZIP Code matches multiple counties, click to do a full lookup"
attrs.onClick = `lookupZip("${callObj.DEcall}", "${callObj.grid4}")`
attrs.html = `¿ ${attrs.html} ?`
}
return attrs
}
},
Cont: {
compare: callObjSimpleComparer("cont"),
tableData: (callObj) => ({
align: "center",
rawAttrs: callObj.style.cont,
html: callObj.cont ? callObj.cont : ""
})
},
dB: {
compare: callObjSimpleComparer("RSTsent"),
tableData: (callObj) => ({
style: "color:#DD44DD;",
html: `<b>${callObj.RSTsent}</b>`
})
},
Freq: {
compare: callObjSimpleComparer("delta"),
tableData: (callObj) => ({
style: "color: #00FF00;",
html: callObj.delta
})
},
DT: {
compare: callObjSimpleComparer("dt"),
tableData: (callObj) => ({
style: "color: #1E90FF;",
html: callObj.dt
})
},
Dist: {
compare: callObjSimpleComparer("distance"),
tableHeader: () => ({ html: `Dist (${window.opener.distanceUnit.value.toLowerCase()})` }),
tableData: (callObj) => ({
style: "color: cyan;",
html: Math.round(callObj.distance * MyCircle.validateRadius(window.opener.distanceUnit.value))
})
},
Azim: {
compare: callObjSimpleComparer("heading"),
tableData: (callObj) => ({
style: "color: yellow;",
html: Math.round(callObj.heading)
})
},
CQz: {
compare: false,
tableData: (callObj) => ({
name: "CQz",
rawAttrs: callObj.style.cqz,
html: callObj.cqza.join(",")
})
},
ITUz: {
compare: false,
tableData: (callObj) => ({
name: "ITUz",
rawAttrs: callObj.style.ituz,
html: callObj.ituza.join(",")
})
},
PX: {
compare: callObjSimpleComparer("px"),
tableData: (callObj) => ({
rawAttrs: callObj.style.px,
html: callObj.px ? callObj.px : ""
})
},
LoTW: {
compare: false,
tableData: (callObj) =>
{
if (callObj.DEcall in window.opener.g_lotwCallsigns)
{
if (g_rosterSettings.maxLoTW < 27)
{
let months = (g_day - window.opener.g_lotwCallsigns[callObj.DEcall]) / 30;
if (months > g_rosterSettings.maxLoTW)
{
return {
style: "color: yellow;",
align: "center",
title: `Has not updated a QSO in ${Number(months).toYM()}`,
html: "?"
}
}
else
{
return {
style: "color: #0F0;",
align: "center",
title: `Last Upload&#10;${
window.opener.userDayString(window.opener.g_lotwCallsigns[callObj.DEcall] * 86400000)
}`,
html: "&#10004;"
}
}
}
else
{
return {
style: "color: #0F0;",
align: "center",
title: `Last Upload&#10;${
window.opener.userDayString(window.opener.g_lotwCallsigns[callObj.DEcall] * 86400000)
}`,
html: "&#10004;"
}
}
}
}
},
eQSL: {
compare: false,
tableData: (callObj) => ({
style: "color: #0F0;",
align: "center",
html: (callObj.DEcall in window.opener.g_eqslCallsigns ? "&#10004;" : "")
})
},
OQRS: {
compare: false,
tableData: (callObj) => ({
style: "color: #0F0;",
align: "center",
html: (callObj.DEcall in window.opener.g_oqrsCallsigns ? "&#10004;" : "")
})
},
Life: {
compare: callObjSimpleComparer("life"),
tableData: (callObj) => ({
style: "color: #EEE;",
class: "lifeCol",
id: `lm${callObj.hash}`,
html: (timeNowSec() - callObj.life).toDHMS15()
})
},
OAMS: {
tableHeader: () => ({ description: "Off-Air Message User" }),
compare: getterSimpleComparer((elem) => elem.callObj.gt != 0 ? 1 : 0),
tableData: (callObj) =>
{
if (callObj.gt != 0)
{
if (callObj.reason.includes("oams"))
{
return {
align: "center",
style: "margin: 0; padding: 0; cursor: pointer; background-clip: content-box; box-shadow: 0 0 4px 4px inset #2222FFFF;",
onClick: `openChatToCid("${callObj.gt}")`,
html: "<img height='16px' style='' src='./img/gt_chat.png' />"
}
}
else
{
return {
align: "center",
style: "margin: 0; padding: 0; cursor: pointer;",
onClick: `openChatToCid("${callObj.gt}")`,
html: "<img height='16px' style='' src='./img/gt_chat.png' />"
}
}
}
}
},
Age: {
compare: callObjSimpleComparer("time"),
tableData: (callObj) => ({
style: "color: #EEE;",
class: "timeCol",
id: `tm${callObj.hash}`,
title: (timeNowSec() - callObj.age).toDHMS(),
html: (timeNowSec() - callObj.age).toDHMS15()
})
},
Spot: {
compare: (a, b) =>
{
let cutoff = timeNowSec() - window.opener.g_receptionSettings.viewHistoryTimeSec;
if (a.callObj.spot.when <= cutoff) return -1;
if (b.callObj.spot.when <= cutoff) return 1;
let aSNR = Number(a.callObj.spot.snr);
let bSNR = Number(b.callObj.spot.snr);
if (aSNR > bSNR) return 1;
if (aSNR < bSNR) return -1;
if (a.callObj.spot.when > b.callObj.spot.when) return 1;
if (a.callObj.spot.when < b.callObj.spot.when) return -1;
return 0;
},
tableData: (callObj) => ({
style: "color: #EEE;",
class: "spotCol",
id: `sp${callObj.hash}`,
html: getSpotString(callObj)
})
}
}

Wyświetl plik

@ -1,7 +1,7 @@
{ {
"name": "GridTracker", "name": "GridTracker",
"product_string_do_not_use": "gridtracker", "product_string_do_not_use": "gridtracker",
"version": "1.21.1212", "version": "1.22.0503",
"betaVersion": "", "betaVersion": "",
"description": "GridTracker, an amateur radio companion", "description": "GridTracker, an amateur radio companion",
"author": "Stephen Loomis (N0TTL) and GridTracker.org", "author": "Stephen Loomis (N0TTL) and GridTracker.org",
@ -23,7 +23,7 @@
"start": "run --mirror https://dl.nwjs.io/ ." "start": "run --mirror https://dl.nwjs.io/ ."
}, },
"build": { "build": {
"nwVersion": "0.54.0", "nwVersion": "0.59.0",
"output": "../dist/.", "output": "../dist/.",
"targets": [ "targets": [
"zip", "zip",

Wyświetl plik

@ -0,0 +1,170 @@
/*
GridTracker Installation Script
*/
# Installer Attributes
RequestExecutionLevel highest
SetCompressor /SOLID LZMA
Unicode true
!include Sections.nsh
!include Registry.nsh
!include LogicLib.nsh
ReserveFile "${NSISDIR}/Plugins/x86-unicode/registry.dll"
CRCCheck on
# Define Common Variables
!define NAME "GridTracker"
!define COMPANY "Gridtracker.org"
!define VERSION <versionplaceholder>
!define URL "http://gridtracker.org"
!define HELPURL "https://gitlab.com/gridtracker.org/gridtracker/-/wikis/Home"
!define REGPATH_UNINSTSUBKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}"
!define SMPATH "$SMPROGRAMS\${NAME}"
!define /date CPYEAR "%Y"
!define BUILDPATH "<buildplaceholder>"
Name "${NAME} ${VERSION} Installer"
Icon "${BUILDPATH}/dist/GridTracker-${VERSION}-win-x86/gridview.ico"
OutFile "${BUILDPATH}/dist/GridTracker-Installer.${VERSION}.exe"
VIProductVersion ${VERSION}.0
VIAddVersionKey ProductName "${NAME}"
VIAddVersionKey ProductVersion "${VERSION}"
VIAddVersionKey CompanyName "${COMPANY}"
VIAddVersionKey CompanyWebsite "${URL}"
VIAddVersionKey FileVersion "${VERSION}"
VIAddVersionKey FileDescription "An Amateur Radio Community"
VIAddVersionKey LegalCopyright "${CPYEAR} Gridtracker.org"
# Add registry reading plugin early on as we need to see if we are installed already
# Set Default install dir then look at uninstall key to find if previously installed #
InstallDir "$ProgramFiles\${NAME}"
## For 32 bit installs on 64 bit OS this is located in the WOW6432Node [HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall] ##
InstallDirRegKey HKLM "${REGPATH_UNINSTSUBKEY}" "InstallPath"
# Pages displayed
#Page license
Page directory
Page components
Page instfiles
# Display license file to user #
#LicenseData "LICENSE"
Function .onInit
nsProcess::_FindProcess "GridTracker.exe"
Pop $R0
${If} $R0 = 0
MessageBox MB_OK|MB_ICONEXCLAMATION "GridTracker is still running. Please close GridTracker and run the installer again."
Abort
${EndIf}
call checkMSVC
FunctionEnd
Function checkMSVC
ClearErrors
ReadRegStr $0 HKCR "Installer\Dependencies\VC,redist.x86,x86,14.30,bundle" ""
IfErrors 0 +15
ClearErrors
ReadRegStr $0 HKCR "Installer\Dependencies\Microsoft.VS.VC_RuntimeMinimumVSU_x86,v14" ""
IfErrors 0 +12
ClearErrors
ReadRegStr $0 HKCR "Installer\Dependencies\Microsoft.VS.VC_RuntimeAdditionalVSU_x86,v14" ""
IfErrors 0 +9
ClearErrors
ReadRegStr $0 HKCR "Installer\Products\679E80FBE29B63345BF612177149674C" "PackageCode"
IfErrors 0 +6
MessageBox MB_YESNO|MB_ICONQUESTION "GridTracker requires MSVC Runtime Libraries. Do you want to install them now?" IDYES InstallNow IDNO Next
InstallNow:
Call InstallMSVC
Goto Next
Next:
FunctionEnd
Function InstallMSVC
NSISdl::download "https://aka.ms/vs/17/release/vc_redist.x86.exe" "$TEMP\vc_redist.x86.exe" $0
StrCmp $0 success fail
success:
ExecWait '"$TEMP\vc_redist.x86.exe" /PASSIVE /NORESTART' $1
Goto is_reboot_requested
fail:
MessageBox MB_OK|MB_ICONEXCLAMATION "Unable to download MSVC Runtime files. Please see GridTracker.org for details on download"
is_reboot_requested:
${If} $1 = 1641
${OrIf} $1 = 3010
SetRebootFlag true
${EndIf}
FunctionEnd
InstType "Full"
InstType "Minimal"
Section "Program Files (Required)"
SectionIn 1 2 RO
SetOverwrite ifdiff
SetOutPath $InstDir
File /r "${BUILDPATH}/dist/GridTracker-${VERSION}-win-x86/*"
CreateDirectory "${SMPATH}"
CreateShortcut "${SMPATH}\${NAME}.lnk" "$InstDir\${NAME}.exe"
CreateShortcut "${SMPATH}\Help Wiki.lnk" "${HELPURL}" "" "$InstDir\gridview.ico"
CreateShortcut "${SMPATH}\Uninstall.lnk" $INSTDIR\uninstall.exe
WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "DisplayName" "${NAME}"
WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "DisplayVersion" "${VERSION}"
WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "Publisher" "${COMPANY}"
WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "URLInfoAbout" "${URL}"
WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "DisplayIcon" "$InstDir\gridview.ico"
WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "UninstallString" '"$InstDir\uninstall.exe"'
WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "QuietUninstallString" '"$InstDir\uninstall.exe" /S'
WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "InstallPath" $InstDir
WriteRegDWORD HKLM "${REGPATH_UNINSTSUBKEY}" "NoModify" 1
WriteRegDWORD HKLM "${REGPATH_UNINSTSUBKEY}" "NoRepair" 1
WriteUninstaller "$InstDir\uninstall.exe"
SectionEnd
# Section for PDF when we have it #
/*
Section "Offline Help Docs"
SectionIn 1
SectionEnd
*/
# Section for Locales when we have it #
/*
SectionGroup "Locales"
SetOutPath $INSTDIR\locales
Section "de"
SectionEnd
Section "es"
SectionEnd
SectionGroupEnd
*/
# Give User Option for Desktop Shortcut #
Section "Desktop Shortcut"
SectionIn 1
CreateShortcut /NoWorkingDir "$DESKTOP\${NAME}.lnk" "$InstDir\${NAME}.exe"
SectionEnd
# Uninstall stuffs #
Section -un.Main
RmDir /r /REBOOTOK $INSTDIR
RmDir /r /REBOOTOK "${SMPATH}"
Delete /REBOOTOK "$DESKTOP\${NAME}.lnk"
DeleteRegKey HKLM "${REGPATH_UNINSTSUBKEY}"
Delete "$InstDir\uninstall.exe"
SectionEnd