kopia lustrzana https://gitlab.com/gridtracker.org/gridtracker
Merge branch 'master' into cbayer-i18n
commit
670001a6db
|
@ -11,3 +11,4 @@ debian/tmp
|
||||||
node_modules
|
node_modules
|
||||||
package-lock.json
|
package-lock.json
|
||||||
.vscode
|
.vscode
|
||||||
|
desktop.ini
|
||||||
|
|
|
@ -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
|
||||||
|
|
18
README.md
18
README.md
|
@ -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.
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 © 2021 GridTracker.org</p>
|
<p>Copyright © 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>
|
||||||
|
|
|
@ -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"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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>
|
||||||
|
|
|
@ -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>";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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"
|
||||||
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 " +
|
|
||||||
window.opener.userDayString(
|
|
||||||
window.opener.g_lotwCallsigns[thisCall] * 86400000
|
|
||||||
) +
|
|
||||||
"'>✔</td>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
worker +=
|
|
||||||
"<td style='color:#0F0' align='center' title=' Last Upload " +
|
|
||||||
window.opener.userDayString(
|
|
||||||
window.opener.g_lotwCallsigns[thisCall] * 86400000
|
|
||||||
) +
|
|
||||||
"'>✔</td>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else worker += "<td></td>";
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
window.opener.g_callsignLookups.eqslUseEnable == true &&
|
|
||||||
g_rosterSettings.columns.eQSL
|
|
||||||
)
|
|
||||||
{
|
|
||||||
worker +=
|
|
||||||
"<td style='color:#0F0;' align='center'>" +
|
|
||||||
(thisCall in window.opener.g_eqslCallsigns ? "✔" : "") +
|
|
||||||
"</td>";
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
window.opener.g_callsignLookups.oqrsUseEnable == true &&
|
|
||||||
g_rosterSettings.columns.OQRS
|
|
||||||
)
|
|
||||||
{
|
|
||||||
worker +=
|
|
||||||
"<td style='color:#0F0;' align='center'>" +
|
|
||||||
(thisCall in window.opener.g_oqrsCallsigns ? "✔" : "") +
|
|
||||||
"</td>";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_rosterSettings.columns.Spot)
|
|
||||||
{
|
|
||||||
worker +=
|
|
||||||
"<td style='color:#EEE;' class='spotCol' id='sp" +
|
|
||||||
thisCall +
|
|
||||||
callObj.band +
|
|
||||||
callObj.mode +
|
|
||||||
"'>" +
|
|
||||||
spotString +
|
|
||||||
"</td>";
|
|
||||||
}
|
|
||||||
if (g_rosterSettings.columns.Life)
|
|
||||||
{
|
|
||||||
worker +=
|
|
||||||
"<td style='color:#EEE;' class='lifeCol' id='lm" +
|
|
||||||
thisCall +
|
|
||||||
callObj.band +
|
|
||||||
callObj.mode +
|
|
||||||
"'>" +
|
|
||||||
(timeNowSec() - callObj.life).toDHMS() +
|
|
||||||
"</td>";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_rosterSettings.columns.OAMS)
|
|
||||||
{
|
|
||||||
if (callObj.style.gt != 0)
|
|
||||||
{
|
|
||||||
if (callObj.reason.includes("oams"))
|
|
||||||
{
|
|
||||||
worker +=
|
|
||||||
"<td align='center' style='margin:0;padding:0;cursor:pointer;background-clip:content-box;box-shadow: 0 0 4px 4px inset #2222FFFF;' onClick='openChatToCid(\"" +
|
|
||||||
callObj.style.gt +
|
|
||||||
"\")'><img height='16px' style='' src='./img/gt_chat.png'></td>";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
worker +=
|
|
||||||
"<td align='center' style='margin:0;padding:0;cursor:pointer;' onClick='openChatToCid(\"" +
|
|
||||||
callObj.style.gt +
|
|
||||||
"\")'><img height='16px' style='' src='./img/gt_chat.png'></td>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else worker += "<td></td>";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_rosterSettings.columns.Age)
|
|
||||||
{
|
|
||||||
worker +=
|
|
||||||
"<td style='color:#EEE' class='timeCol' id='tm" +
|
|
||||||
thisCall +
|
|
||||||
callObj.band +
|
|
||||||
callObj.mode +
|
|
||||||
"'>" +
|
|
||||||
(timeNowSec() - callObj.age).toDHMS() +
|
|
||||||
"</td>";
|
|
||||||
}
|
|
||||||
|
|
||||||
worker += "</tr></tbody>";
|
|
||||||
|
|
||||||
return worker;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderNormalRosterFooter()
|
function renderNormalRosterFooter()
|
||||||
{
|
{
|
||||||
return "</table>";
|
return "</tbody></table>";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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, """)}"`).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();
|
||||||
|
}
|
|
@ -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 ${
|
||||||
|
window.opener.userDayString(window.opener.g_lotwCallsigns[callObj.DEcall] * 86400000)
|
||||||
|
}`,
|
||||||
|
html: "✔"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
style: "color: #0F0;",
|
||||||
|
align: "center",
|
||||||
|
title: `Last Upload ${
|
||||||
|
window.opener.userDayString(window.opener.g_lotwCallsigns[callObj.DEcall] * 86400000)
|
||||||
|
}`,
|
||||||
|
html: "✔"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
eQSL: {
|
||||||
|
compare: false,
|
||||||
|
tableData: (callObj) => ({
|
||||||
|
style: "color: #0F0;",
|
||||||
|
align: "center",
|
||||||
|
html: (callObj.DEcall in window.opener.g_eqslCallsigns ? "✔" : "")
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
OQRS: {
|
||||||
|
compare: false,
|
||||||
|
tableData: (callObj) => ({
|
||||||
|
style: "color: #0F0;",
|
||||||
|
align: "center",
|
||||||
|
html: (callObj.DEcall in window.opener.g_oqrsCallsigns ? "✔" : "")
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -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",
|
||||||
|
|
|
@ -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
|
Ładowanie…
Reference in New Issue