forked from Netsyms/PackageHelper
Compare commits
43 Commits
Author | SHA1 | Date | |
---|---|---|---|
424c6b3987 | |||
4d9b4abd19 | |||
771fd271c2 | |||
e1ded04c9b | |||
261b797a85 | |||
bbdf21f8a2 | |||
7c25b8c3b3 | |||
acd0c86447 | |||
5f28ee8a7e | |||
d5e6d7eaee | |||
7d39c12fce | |||
a0cbb0dbe5 | |||
91e31c449e | |||
b50524903d | |||
1f942ecafe | |||
5306f25a97 | |||
78f9c5f31f | |||
c69b8933ab | |||
00600ffee9 | |||
1796e45f92 | |||
5d9944a9c4 | |||
b25a292f34 | |||
13021af8ca | |||
1c8c7cc2e7 | |||
90aeb804ae | |||
31dee00cb1 | |||
8514582bcb | |||
403708572e | |||
09b51d95f0 | |||
faa13a1588 | |||
f3f3653d2c | |||
976f44a4f8 | |||
008ab56ce8 | |||
4c24d8fba8 | |||
9f5caa2593 | |||
c4900d2505 | |||
efd39a2349 | |||
df06534d72 | |||
c1f74e43fe | |||
384dac7b85 | |||
d0c3988566 | |||
70fa409015 | |||
3602f77343 |
@ -1,5 +1,5 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<widget id="com.netsyms.PackageHelper" version="1.2.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
|
<widget id="com.netsyms.PackageHelper" version="1.3.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
|
||||||
<name>PackageHelper</name>
|
<name>PackageHelper</name>
|
||||||
<description>
|
<description>
|
||||||
Assistant app for door-to-door package delivery.
|
Assistant app for door-to-door package delivery.
|
||||||
@ -32,7 +32,5 @@
|
|||||||
<allow-intent href="itms:*" />
|
<allow-intent href="itms:*" />
|
||||||
<allow-intent href="itms-apps:*" />
|
<allow-intent href="itms-apps:*" />
|
||||||
</platform>
|
</platform>
|
||||||
<hook src="scripts/www_npm_install.sh" type="before_prepare" />
|
<hook src="scripts/npm_prepare.sh" type="before_prepare" />
|
||||||
<hook src="scripts/generate_credits.sh" type="before_prepare" />
|
|
||||||
<hook src="scripts/remove_bloat.sh" type="before_prepare" />
|
|
||||||
</widget>
|
</widget>
|
||||||
|
1179
license-credits.md
1179
license-credits.md
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "com.netsyms.packagehelper",
|
"name": "com.netsyms.packagehelper",
|
||||||
"displayName": "PackageHelper",
|
"displayName": "PackageHelper",
|
||||||
"version": "1.2.0",
|
"version": "1.3.0",
|
||||||
"description": "Assistant app for door-to-door package delivery.",
|
"description": "Assistant app for door-to-door package delivery.",
|
||||||
"main": "www/index.html",
|
"main": "www/index.html",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -18,7 +18,8 @@
|
|||||||
"cordova-plugin-inappbrowser": {},
|
"cordova-plugin-inappbrowser": {},
|
||||||
"cordova-plugin-powermanagement-netsyms": {},
|
"cordova-plugin-powermanagement-netsyms": {},
|
||||||
"cordova-plugin-whitelist": {},
|
"cordova-plugin-whitelist": {},
|
||||||
"phonegap-plugin-barcodescanner": {}
|
"phonegap-plugin-barcodescanner": {},
|
||||||
|
"cordova-plugin-device": {}
|
||||||
},
|
},
|
||||||
"platforms": [
|
"platforms": [
|
||||||
"android",
|
"android",
|
||||||
@ -28,6 +29,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cordova-android": "^8.1.0",
|
"cordova-android": "^8.1.0",
|
||||||
"cordova-browser": "^6.0.0",
|
"cordova-browser": "^6.0.0",
|
||||||
|
"cordova-plugin-device": "^2.0.3",
|
||||||
"cordova-plugin-inappbrowser": "^3.1.0",
|
"cordova-plugin-inappbrowser": "^3.1.0",
|
||||||
"cordova-plugin-powermanagement-netsyms": "git+https://source.netsyms.com/Netsyms/cordova-plugin-powermanagement",
|
"cordova-plugin-powermanagement-netsyms": "git+https://source.netsyms.com/Netsyms/cordova-plugin-powermanagement",
|
||||||
"cordova-plugin-whitelist": "^1.3.4"
|
"cordova-plugin-whitelist": "^1.3.4"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
cd www
|
cd www
|
||||||
yarn licenses generate-disclaimer > ../license-credits.md
|
yarn licenses generate-disclaimer > ../license-credits.md
|
||||||
cd ..
|
cd ..
|
||||||
|
5
scripts/npm_prepare.sh
Executable file
5
scripts/npm_prepare.sh
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
./scripts/www_npm_install.sh
|
||||||
|
./scripts/generate_credits.sh
|
||||||
|
./scripts/remove_bloat.sh
|
@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
# This script removes some stuff in `www/node_modules` that the app doesn't need to run.
|
# This script removes some stuff in `www/node_modules` that the app doesn't need to run.
|
||||||
# It removes about 6MB from the build size.
|
# It removes about 6MB from the build size.
|
||||||
|
|
||||||
@ -7,60 +7,80 @@ echo "Removing bloat in node_modules..."
|
|||||||
pwd
|
pwd
|
||||||
|
|
||||||
cd www/node_modules
|
cd www/node_modules
|
||||||
rm -rf dom7
|
rm -rf {ansicolors,buffer-from,cardinal,concat-stream,core-util-is,csscolorparser}
|
||||||
rm -rf path-to-regexp
|
rm -rf {dom7,earcut,esprima,geojson-vt,gl-matrix,grid-index,ieee754,inherits,isarray}
|
||||||
rm -rf ssr-window
|
rm -rf {kdbush,leaflet-geometryutil,@mapbox,minimist,murmurhash-js}
|
||||||
rm -rf template7
|
rm -rf {path-to-regexp,pbf,potpack,process-nextick-args}
|
||||||
|
rm -rf {protocol-buffers-schema,quickselect,readable-stream,redeyed,resolve-protobuf-schema}
|
||||||
|
rm -rf {rw,safe-buffer,sharkdown,split,ssr-window,string_decoder,supercluster}
|
||||||
|
rm -rf {template7,text-encoding,through,tinyqueue,ts-custom-error,typedarray}
|
||||||
|
rm -rf {util-deprecate,vt-pbf,wgs84}
|
||||||
|
|
||||||
|
# Make npm stop complaining that these don't exist by actually removing them
|
||||||
|
rm -rf .bin/*
|
||||||
|
|
||||||
|
|
||||||
cd @fortawesome/fontawesome-free
|
cd @fortawesome/fontawesome-free
|
||||||
rm -rf js
|
rm -rf {js,less,metadata,scss,sprites,svgs}
|
||||||
rm -rf less
|
find css -type f -not -name 'all.min.css' -delete
|
||||||
rm -rf scss
|
|
||||||
rm -rf sprites
|
|
||||||
rm -rf svgs
|
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|
||||||
cd jquery
|
|
||||||
rm -rf src
|
|
||||||
rm -rf external
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
cd jsbarcode
|
|
||||||
rm -rf .dockerignore .eslintignore .eslintrcautomation bower.json CONTRIBUTING.md docker-compose.yml Dockerfile example gulpfile.js jsbarcode.d.ts README.md src test .travis.yml
|
|
||||||
rm -rf dist/barcodes
|
|
||||||
rm -rf dist/JsBarcode.all.js
|
|
||||||
|
|
||||||
cd framework7
|
cd framework7
|
||||||
rm -rf components
|
rm -rf components
|
||||||
rm -rf lazy-components
|
rm -rf lazy-components
|
||||||
rm -rf less
|
rm -rf less
|
||||||
rm -rf modules
|
rm -rf modules
|
||||||
rm -rf utils
|
rm -rf utils
|
||||||
|
rm -f framework7.*
|
||||||
|
rm -f framework7-lite.*
|
||||||
|
find css -type f -not -name 'framework7.bundle.min.css' -delete
|
||||||
|
find js -type f -not -name 'framework7.bundle.min.js' -delete
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd jquery
|
||||||
|
rm -rf src
|
||||||
|
rm -rf external
|
||||||
|
find dist -type f -not -name 'jquery.min.js' -delete
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
cd jsbarcode
|
||||||
|
rm -rf .dockerignore .eslintignore .eslintrcautomation bower.json CONTRIBUTING.md docker-compose.yml Dockerfile example gulpfile.js jsbarcode.d.ts README.md src test .travis.yml
|
||||||
|
rm -rf {automation,bin}
|
||||||
|
rm -rf dist/barcodes
|
||||||
|
rm -rf dist/JsBarcode.all.js
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd leaflet
|
||||||
|
rm -rf {CHANGELOG.md,src}
|
||||||
|
find dist -type f -not -name 'leaflet.css' -not -name 'leaflet.js' -delete
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd leaflet.locatecontrol
|
||||||
|
rm -rf {CHANGELOG.md,README.md,src}
|
||||||
|
find dist -type f -not -name 'L.Control.Locate.min.css' -not -name 'L.Control.Locate.min.js' -delete
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd leaflet.markercluster
|
||||||
|
rm -rf {build,example,spec,src,CHANGELOG.md}
|
||||||
|
find dist -type f -not -name 'leaflet.markercluster.js' -not -name 'MarkerCluster.css' -not -name 'MarkerCluster.Default.css' -delete
|
||||||
|
cd ..
|
||||||
|
|
||||||
cd material-design-icons
|
cd material-design-icons
|
||||||
rm -rf action
|
# Remove everything except the icon font and license, but also exclude the
|
||||||
rm -rf alert
|
# current and parent folder (. , ..) so rm won't complain about refusing
|
||||||
rm -rf av
|
# to delete the whole filesystem
|
||||||
rm -rf bower.json
|
find . -maxdepth 1 -not -name '.' -not -name 'LICENSE' -not -name 'iconfont' -exec rm -rf {} \;
|
||||||
rm -rf communication
|
|
||||||
rm -rf content
|
|
||||||
rm -rf device
|
|
||||||
rm -rf editor
|
|
||||||
rm -rf file
|
|
||||||
rm -rf gulpfile.babel.js
|
|
||||||
rm -rf hardware
|
|
||||||
rm -rf image
|
|
||||||
rm -rf index.js
|
|
||||||
rm -rf maps
|
|
||||||
rm -rf navigation
|
|
||||||
rm -rf notification
|
|
||||||
rm -rf package.json
|
|
||||||
rm -rf places
|
|
||||||
rm -rf README.md
|
|
||||||
rm -rf social
|
|
||||||
rm -rf sprites
|
|
||||||
rm -rf toggle
|
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
cd mapbox-gl
|
||||||
|
rm -rf {build,flow-typed,src}
|
||||||
|
find dist -type f -not -name 'mapbox-gl.css' -not -name 'mapbox-gl.js' -delete
|
||||||
|
rm -rf dist/style-spec
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd @zxing/library
|
||||||
|
rm -rf {esm,esm5}
|
||||||
|
rm -f umd/index.min.js.map
|
||||||
|
cd ../..
|
||||||
|
|
||||||
echo "Cleanup finished"
|
echo "Cleanup finished"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
|
|
||||||
cd www
|
cd www
|
||||||
npm install
|
npm install
|
||||||
|
@ -17,4 +17,33 @@ Framework7 and FontAwesome both have a .fab class
|
|||||||
font-family: var(--f7-font-family);
|
font-family: var(--f7-font-family);
|
||||||
font-size: var(--f7-font-size);
|
font-size: var(--f7-font-size);
|
||||||
line-height: var(--f7-line-height);
|
line-height: var(--f7-line-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Material icons are too big and disrupt the flow of text
|
||||||
|
*/
|
||||||
|
.block .material-icons {
|
||||||
|
font-size: var(--f7-block-font-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-icons.material-icons-24px {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-icons-intext .material-icons {
|
||||||
|
font-size: var(--f7-block-font-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#mapbox .package-marker {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
background-image: url(../images/box.png);
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allow tapping/clicking on package markers
|
||||||
|
* when the location dot is overlapping them
|
||||||
|
*/
|
||||||
|
#mapbox .mapboxgl-user-location-dot {
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
60
www/assets/images/barcode-dashed.svg
Normal file
60
www/assets/images/barcode-dashed.svg
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
class="svg-inline--fa fa-history fa-w-16"
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="history"
|
||||||
|
data-prefix="far"
|
||||||
|
focusable="false"
|
||||||
|
role="img"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
id="svg877"
|
||||||
|
sodipodi:docname="barcode-dashed.svg"
|
||||||
|
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||||
|
<metadata
|
||||||
|
id="metadata883">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs881" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1015"
|
||||||
|
id="namedview879"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.4980469"
|
||||||
|
inkscape:cx="256"
|
||||||
|
inkscape:cy="256"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg877" />
|
||||||
|
<path
|
||||||
|
id="path952"
|
||||||
|
d="M 25.36636,428.97523 V 83.02477 h 16.216428 v 345.95046 z m 24.195811,-0.24595 V 83.02477 h 8.237044 v 345.70451 z m 24.453472,0 V 83.02477 h 7.979383 v 345.70451 z m 40.412237,0 V 83.02477 h 7.97938 v 345.70451 z m 32.43286,0 V 83.02477 h 15.95876 v 345.70451 z m 40.41224,0 V 83.02477 h 7.97938 v 345.70451 z m 16.21642,0 V 83.02477 h 7.97939 v 345.70451 z m 16.21643,0 V 83.02477 h 7.97938 v 345.70451 z m 32.1761,0 V 83.02477 h 16.21642 v 345.70451 z m 40.41224,0 V 83.02477 h 16.21642 v 345.70451 z m 32.43195,0 V 83.02477 h 16.21733 v 345.70451 z m 32.43376,0 V 83.02477 h 16.21732 v 345.70451 z m 24.19581,0 V 83.02477 h 16.21642 v 345.70451 z m 40.6699,0 V 83.02477 h 24.19581 v 345.70451 z m 32.17519,0 V 83.02477 h 8.23705 v 345.70451 z m 16.21643,0.24595 V 83.02477 h 16.21643 v 345.95046 z"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:#9e9e9e;fill-opacity:1;stroke:none;stroke-width:10.00063038;stroke-miterlimit:4;stroke-dasharray:5.00031521, 5.00031521;stroke-dashoffset:0;stroke-opacity:1" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
@ -76,7 +76,7 @@ function addAutofillEntry(address) {
|
|||||||
function searchAutofill(q, number) {
|
function searchAutofill(q, number) {
|
||||||
var byNumber = [];
|
var byNumber = [];
|
||||||
if (typeof number != 'undefined') {
|
if (typeof number != 'undefined') {
|
||||||
byNumber = searchAutofillByNumber(number);
|
byNumber = searchAutofillByNumber(number, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
var byStreet = [];
|
var byStreet = [];
|
||||||
@ -87,7 +87,7 @@ function searchAutofill(q, number) {
|
|||||||
return byNumber.concat(byStreet.filter((item) => byNumber.indexOf(item) < 0));
|
return byNumber.concat(byStreet.filter((item) => byNumber.indexOf(item) < 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
function searchAutofillByNumber(number) {
|
function searchAutofillByNumber(number, q) {
|
||||||
if (typeof autofillDB[number] == 'undefined') {
|
if (typeof autofillDB[number] == 'undefined') {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@ -96,10 +96,18 @@ function searchAutofillByNumber(number) {
|
|||||||
return b[1] - a[1];
|
return b[1] - a[1];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var query = false;
|
||||||
|
if (typeof q != 'undefined' && q != "") {
|
||||||
|
query = true;
|
||||||
|
}
|
||||||
|
|
||||||
var streets = [];
|
var streets = [];
|
||||||
|
|
||||||
for (var i = 0; i < sorted.length; i++) {
|
for (var i = 0; i < sorted.length; i++) {
|
||||||
streets.push(sorted[i][0]);
|
// if there's no search query OR if the query matches the current item
|
||||||
|
if (!query || (query && sorted[i][0].toLowerCase().includes(q))) {
|
||||||
|
streets.push(sorted[i][0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return streets;
|
return streets;
|
||||||
@ -112,12 +120,12 @@ function searchAutofillByStreet(q) {
|
|||||||
return b[1] - a[1];
|
return b[1] - a[1];
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(sortedDB);
|
//console.log(sortedDB);
|
||||||
|
|
||||||
q = q.toLowerCase();
|
q = q.toLowerCase();
|
||||||
|
|
||||||
for (var i = 0; i < sortedDB.length; i++) {
|
for (var i = 0; i < sortedDB.length; i++) {
|
||||||
console.log(sortedDB[i][0].toLowerCase().indexOf(q));
|
//console.log(sortedDB[i][0].toLowerCase().indexOf(q));
|
||||||
if (sortedDB[i][0].toLowerCase().includes(q)) {
|
if (sortedDB[i][0].toLowerCase().includes(q)) {
|
||||||
streets.push(sortedDB[i][0]);
|
streets.push(sortedDB[i][0]);
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ $(".view-main").on("click", "#addresslist .package-list-item .directions-btn", f
|
|||||||
});
|
});
|
||||||
|
|
||||||
$(".view-main").on("swipeout:delete", "#addresslist .package-list-item", function () {
|
$(".view-main").on("swipeout:delete", "#addresslist .package-list-item", function () {
|
||||||
console.log("Deleting package", $(this).data("packageid"));
|
console.log("Info", "Deleting package", $(this).data("packageid"));
|
||||||
deletePackage($(this).data("packageid"));
|
deletePackage($(this).data("packageid"));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -62,8 +62,8 @@ function loadPackageList(sortType) {
|
|||||||
var anum = parseInt(a.value.address.split(" ", 1)[0], 10);
|
var anum = parseInt(a.value.address.split(" ", 1)[0], 10);
|
||||||
var bnum = parseInt(b.value.address.split(" ", 1)[0], 10);
|
var bnum = parseInt(b.value.address.split(" ", 1)[0], 10);
|
||||||
|
|
||||||
console.log("aalpha", aalpha);
|
//console.log("aalpha", aalpha);
|
||||||
console.log("balpha", balpha);
|
//console.log("balpha", balpha);
|
||||||
switch (sortType) {
|
switch (sortType) {
|
||||||
case "alpha_desc":
|
case "alpha_desc":
|
||||||
if (aalpha > balpha) {
|
if (aalpha > balpha) {
|
||||||
|
@ -45,14 +45,10 @@ if ("geolocation" in navigator) {
|
|||||||
localStorage.setItem("user_latitude", userPosition.coords.latitude);
|
localStorage.setItem("user_latitude", userPosition.coords.latitude);
|
||||||
localStorage.setItem("user_longitude", userPosition.coords.longitude);
|
localStorage.setItem("user_longitude", userPosition.coords.longitude);
|
||||||
if (mapLocationControlStarted) {
|
if (mapLocationControlStarted) {
|
||||||
//setMapLocation(position.coords.latitude, position.coords.longitude);
|
|
||||||
// Don't refresh at an interval less than ten seconds
|
// Don't refresh at an interval less than ten seconds
|
||||||
var currentTimestamp = Math.floor(Date.now() / 1000);
|
var currentTimestamp = Math.floor(Date.now() / 1000);
|
||||||
if (lastGpsUpdateTimestamp < (currentTimestamp - 10)) {
|
if (lastGpsUpdateTimestamp < (currentTimestamp - 10)) {
|
||||||
updateDistances(position.coords.latitude, position.coords.longitude);
|
updateDistances(position.coords.latitude, position.coords.longitude);
|
||||||
if (map != null) {
|
|
||||||
//map.updatePackageLayer(packages);
|
|
||||||
}
|
|
||||||
|
|
||||||
var alertinterval = localStorage.getItem("alertinterval");
|
var alertinterval = localStorage.getItem("alertinterval");
|
||||||
if (alertinterval == null) {
|
if (alertinterval == null) {
|
||||||
@ -89,7 +85,7 @@ if ("geolocation" in navigator) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (map != null) {
|
if (map != null) {
|
||||||
map.locateControl.start();
|
map.startLocateControl();
|
||||||
mapLocationControlStarted = true;
|
mapLocationControlStarted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,7 +100,7 @@ if ("geolocation" in navigator) {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
geoerrorcount++;
|
geoerrorcount++;
|
||||||
console.log("Geolocation error #" + geoerrorcount + ": ", error);
|
console.log("Warn", "Geolocation error #" + geoerrorcount + ": ", error);
|
||||||
// Stop showing error toasts if they're happening a lot
|
// Stop showing error toasts if they're happening a lot
|
||||||
if (geoerrorcount <= 3) {
|
if (geoerrorcount <= 3) {
|
||||||
app.toast.show({
|
app.toast.show({
|
||||||
@ -176,7 +172,7 @@ function getDistance(lat1, lon1, lat2, lon2) {
|
|||||||
* Respects user "units" setting ("metric" or "imperial").
|
* Respects user "units" setting ("metric" or "imperial").
|
||||||
* @param number meters
|
* @param number meters
|
||||||
* @param bool space Add a space between number and units. Default true.
|
* @param bool space Add a space between number and units. Default true.
|
||||||
* @returns string "1000 ft", "2 mi", "3 km",
|
* @returns string "1000 ft", "2 mi", "3 km",
|
||||||
*/
|
*/
|
||||||
function getDisplayDistance(meters, space) {
|
function getDisplayDistance(meters, space) {
|
||||||
if (typeof space == 'undefined') {
|
if (typeof space == 'undefined') {
|
||||||
|
@ -63,10 +63,7 @@ router.on("pageInit", function (pagedata) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.on("routeChange", function (newRoute) {
|
router.on("routeChange", function (newRoute) {
|
||||||
console.log(newRoute);
|
console.log("Info", "Navigating to ", newRoute.path);
|
||||||
if (newRoute == "home") {
|
|
||||||
router.refreshPage();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set alert radius to 100 meters by default
|
// Set alert radius to 100 meters by default
|
||||||
|
@ -43,21 +43,26 @@ $("#addpackagebtn").click(function () {
|
|||||||
|
|
||||||
var address = ($("input[name=number]").val() + " " + $("input[name=street]").val()).toUpperCase();
|
var address = ($("input[name=number]").val() + " " + $("input[name=street]").val()).toUpperCase();
|
||||||
$("#no-history").addClass("display-none");
|
$("#no-history").addClass("display-none");
|
||||||
addPackageByAddress(address, $("input[name=citystate]").val().toUpperCase(), $("input[name=itemtype]:checked").val(), function (ids) {
|
addPackageByAddress(
|
||||||
var packageObj = getPackage(ids.packageID);
|
$("input[name=number]").val().toUpperCase(),
|
||||||
// Reset item type to default
|
$("input[name=street]").val().toUpperCase(),
|
||||||
$("input[name=itemtype][data-default=1]").prop("checked", true);
|
$("input[name=citystate]").val().toUpperCase(),
|
||||||
$("#historylist").prepend('<li class="history-list-item item-content" data-package="' + ids.packageID + '">'
|
$("input[name=itemtype]:checked").val(),
|
||||||
+ ' <div class="item-media">'
|
function (ids) {
|
||||||
+ ' <i class="icon ' + getIconForType(packageObj.type) + '"></i>'
|
var packageObj = getPackage(ids.packageID);
|
||||||
+ ' </div>'
|
// Reset item type to default
|
||||||
+ ' <div class="item-inner">'
|
$("input[name=itemtype][data-default=1]").prop("checked", true);
|
||||||
+ ' <div class="item-title">'
|
$("#historylist").prepend('<li class="history-list-item item-content" data-package="' + ids.packageID + '">'
|
||||||
+ ' ' + packageObj.address
|
+ ' <div class="item-media">'
|
||||||
+ ' </div>'
|
+ ' <i class="icon ' + getIconForType(packageObj.type) + '"></i>'
|
||||||
+ ' </div>'
|
+ ' </div>'
|
||||||
+ '</li>');
|
+ ' <div class="item-inner">'
|
||||||
});
|
+ ' <div class="item-title">'
|
||||||
|
+ ' ' + packageObj.address
|
||||||
|
+ ' </div>'
|
||||||
|
+ ' </div>'
|
||||||
|
+ '</li>');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove any pre-existing click handlers from the history list,
|
// Remove any pre-existing click handlers from the history list,
|
||||||
@ -66,9 +71,9 @@ $("#addpackagebtn").click(function () {
|
|||||||
$(".view-main").off("click", "#historylist .history-list-item");
|
$(".view-main").off("click", "#historylist .history-list-item");
|
||||||
|
|
||||||
$(".view-main").on("click", "#historylist .history-list-item", function () {
|
$(".view-main").on("click", "#historylist .history-list-item", function () {
|
||||||
console.log("Asking to delete ", $(this).data("package"));
|
console.log("Info", "Asking to delete ", $(this).data("package"));
|
||||||
confirmDeletePackage(getPackage($(this).data("package")), function (id) {
|
confirmDeletePackage(getPackage($(this).data("package")), function (id) {
|
||||||
console.log("Removing history item", id);
|
console.log("Info", "Removing history item", id);
|
||||||
$('#historylist .history-list-item[data-package="' + id + '"]').remove();
|
$('#historylist .history-list-item[data-package="' + id + '"]').remove();
|
||||||
if ($('#historylist .history-list-item').length == 0) {
|
if ($('#historylist .history-list-item').length == 0) {
|
||||||
$("#no-history").removeClass("display-none");
|
$("#no-history").removeClass("display-none");
|
||||||
|
@ -6,8 +6,24 @@
|
|||||||
|
|
||||||
var map = null;
|
var map = null;
|
||||||
|
|
||||||
|
var maptype = "mapbox";
|
||||||
|
|
||||||
function createMap() {
|
function createMap() {
|
||||||
map = leafletMap();
|
if (localStorage.getItem("maptype") == null) {
|
||||||
|
localStorage.setItem("maptype", "mapbox");
|
||||||
|
}
|
||||||
|
maptype = localStorage.getItem("maptype");
|
||||||
|
if (maptype == "mapbox") {
|
||||||
|
if (mapboxgl.supported()) {
|
||||||
|
map = mapboxMap();
|
||||||
|
} else {
|
||||||
|
console.log("Warn", "mapbox-gl not supported, falling back to Leaflet");
|
||||||
|
maptype = "leaflet";
|
||||||
|
map = leafletMap();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
map = leafletMap();
|
||||||
|
}
|
||||||
map.updatePackageLayer(packages);
|
map.updatePackageLayer(packages);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,16 +36,37 @@ function reloadMap() {
|
|||||||
if (map != null && typeof map != 'undefined') {
|
if (map != null && typeof map != 'undefined') {
|
||||||
var mapcenter = map.getCenter();
|
var mapcenter = map.getCenter();
|
||||||
var mapzoom = map.getZoom();
|
var mapzoom = map.getZoom();
|
||||||
|
if (map.maptype == "mapbox") {
|
||||||
|
var mapbearing = map.getBearing();
|
||||||
|
var mappitch = map.getPitch();
|
||||||
|
}
|
||||||
|
|
||||||
map.off();
|
map.off();
|
||||||
map.remove();
|
map.remove();
|
||||||
map = null;
|
map = null;
|
||||||
createMap();
|
|
||||||
map.setView(mapcenter, mapzoom);
|
if (document.getElementById("mapbox") != null) {
|
||||||
|
createMap();
|
||||||
|
|
||||||
|
if (map.maptype == "mapbox") {
|
||||||
|
map.jumpTo({
|
||||||
|
center: mapcenter,
|
||||||
|
zoom: mapzoom,
|
||||||
|
bearing: mapbearing,
|
||||||
|
pitch: mappitch
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
map.setView(mapcenter, mapzoom);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("Info", "Not re-creating map because #mapbox is not in DOM. Creation will be automatically triggered when map page is loaded.");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
createMap();
|
createMap();
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
// oh well ¯\(°_o)/¯
|
// oh well ¯\(°_o)/¯
|
||||||
|
console.log(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,12 +85,12 @@ function openPackageInfoSheet(coordid, refreshOnly) {
|
|||||||
refreshOnly = false;
|
refreshOnly = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Packages array: ", packages);
|
//console.log("Packages array: ", packages);
|
||||||
|
|
||||||
for (var i = 0; i < packages.length; i++) {
|
for (var i = 0; i < packages.length; i++) {
|
||||||
if (packages[i].id == coordid) {
|
if (packages[i].id == coordid) {
|
||||||
package = packages[i];
|
package = packages[i];
|
||||||
console.log("Single Address:", package);
|
//console.log("Single Address:", package);
|
||||||
|
|
||||||
$("#package-info-get-directions").attr("href", "geo:" + package.coords[0] + "," + package.coords[1]);
|
$("#package-info-get-directions").attr("href", "geo:" + package.coords[0] + "," + package.coords[1]);
|
||||||
$("#package-info-sheet-inner .list ul").html("");
|
$("#package-info-sheet-inner .list ul").html("");
|
||||||
|
@ -14,6 +14,8 @@ function leafletMap() {
|
|||||||
attributionControl: false
|
attributionControl: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
map.maptype = "leaflet";
|
||||||
|
|
||||||
if (localStorage.getItem("mapsource") == null) {
|
if (localStorage.getItem("mapsource") == null) {
|
||||||
localStorage.setItem("mapsource", "liberty");
|
localStorage.setItem("mapsource", "liberty");
|
||||||
}
|
}
|
||||||
@ -30,7 +32,7 @@ function leafletMap() {
|
|||||||
showPopup: false,
|
showPopup: false,
|
||||||
locateOptions: {
|
locateOptions: {
|
||||||
enableHighAccuracy: true,
|
enableHighAccuracy: true,
|
||||||
maxZoom: 16
|
maxZoom: localStorage.getItem("trackzoom") == null ? 16 : localStorage.getItem("trackzoom") * 1
|
||||||
},
|
},
|
||||||
setView: "untilPanOrZoom",
|
setView: "untilPanOrZoom",
|
||||||
icon: "far fa-compass",
|
icon: "far fa-compass",
|
||||||
@ -43,6 +45,14 @@ function leafletMap() {
|
|||||||
|
|
||||||
map.setView({lat: userPosition.coords.latitude, lng: userPosition.coords.longitude}, 2);
|
map.setView({lat: userPosition.coords.latitude, lng: userPosition.coords.longitude}, 2);
|
||||||
|
|
||||||
|
map.startLocateControl = function () {
|
||||||
|
map.locateControl.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
map.stopLocateControl = function () {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
map.setMapHeading = function (heading) {
|
map.setMapHeading = function (heading) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -57,7 +67,7 @@ function leafletMap() {
|
|||||||
map.updatePackageLayer = function (data) {
|
map.updatePackageLayer = function (data) {
|
||||||
map.packagelayer.clearLayers();
|
map.packagelayer.clearLayers();
|
||||||
|
|
||||||
console.log(data);
|
//console.log(data);
|
||||||
|
|
||||||
for (var i = 0; i < data.length; i++) {
|
for (var i = 0; i < data.length; i++) {
|
||||||
// JavaScript variable scope and anonymous functions are dumb
|
// JavaScript variable scope and anonymous functions are dumb
|
||||||
@ -65,7 +75,7 @@ function leafletMap() {
|
|||||||
// of the loop, or something like that
|
// of the loop, or something like that
|
||||||
(function (datai) {
|
(function (datai) {
|
||||||
var iconName = getMapIconForItems(datai.items);
|
var iconName = getMapIconForItems(datai.items);
|
||||||
console.log(iconName);
|
//console.log(iconName);
|
||||||
|
|
||||||
var icon = L.icon({
|
var icon = L.icon({
|
||||||
iconUrl: "assets/images/" + iconName + ".png",
|
iconUrl: "assets/images/" + iconName + ".png",
|
||||||
|
134
www/assets/js/map_mapbox.js
Normal file
134
www/assets/js/map_mapbox.js
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// If true, we'll do a fancy zoom/pan in
|
||||||
|
// Otherwise we'll just jump to the correct location
|
||||||
|
var firstload = true;
|
||||||
|
|
||||||
|
function mapboxMap() {
|
||||||
|
|
||||||
|
if (localStorage.getItem("mapsource") == null) {
|
||||||
|
localStorage.setItem("mapsource", "liberty");
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#mapbox").css("background-color", SETTINGS.maptileurls[localStorage.getItem("mapsource")].bgcolor);
|
||||||
|
|
||||||
|
mapboxgl.accessToken = '';
|
||||||
|
var map = new mapboxgl.Map({
|
||||||
|
container: 'mapbox',
|
||||||
|
style: SETTINGS.maptileurls[localStorage.getItem("mapsource")].json,
|
||||||
|
attributionControl: false,
|
||||||
|
dragPan: true,
|
||||||
|
pitch: 0,
|
||||||
|
zoom: 2,
|
||||||
|
maxZoom: 19
|
||||||
|
});
|
||||||
|
|
||||||
|
map.maptype = "mapbox";
|
||||||
|
|
||||||
|
map.addControl(new mapboxgl.NavigationControl({
|
||||||
|
visualizePitch: true
|
||||||
|
}), 'top-left');
|
||||||
|
|
||||||
|
map.addControl(
|
||||||
|
new mapboxgl.GeolocateControl({
|
||||||
|
positionOptions: {
|
||||||
|
enableHighAccuracy: true,
|
||||||
|
timeout: 10 * 1000
|
||||||
|
},
|
||||||
|
fitBoundsOptions: {
|
||||||
|
maxZoom: localStorage.getItem("trackzoom") == null ? 16 : localStorage.getItem("trackzoom") * 1
|
||||||
|
},
|
||||||
|
trackUserLocation: true
|
||||||
|
}), 'top-left'
|
||||||
|
);
|
||||||
|
|
||||||
|
map.startLocateControl = function () {
|
||||||
|
// stub
|
||||||
|
}
|
||||||
|
|
||||||
|
map.stopLocateControl = function () {
|
||||||
|
// stub
|
||||||
|
}
|
||||||
|
|
||||||
|
map.mapEasing = function (t) {
|
||||||
|
return t * (2 - t);
|
||||||
|
}
|
||||||
|
|
||||||
|
map.setMapHeading = function (heading) {
|
||||||
|
if (typeof heading == 'number') {
|
||||||
|
map.easeTo({
|
||||||
|
bearing: heading,
|
||||||
|
easing: map.mapEasing
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
map.setMapLocation = function (latitude, longitude) {
|
||||||
|
map.easeTo({
|
||||||
|
center: [
|
||||||
|
longitude,
|
||||||
|
latitude
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
map.updatePackageLayer = function (data) {
|
||||||
|
var oldmarkers = document.getElementsByClassName("package-marker");
|
||||||
|
if (oldmarkers.length > 0) {
|
||||||
|
markerparent = oldmarkers[0].parentNode;
|
||||||
|
while (oldmarkers.length > 0) {
|
||||||
|
markerparent.removeChild(oldmarkers[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
// JavaScript variable scope and anonymous functions are dumb
|
||||||
|
// This is necessary, otherwise all the on(click)s will fire for the last iteration
|
||||||
|
// of the loop, or something like that
|
||||||
|
(function (datai) {
|
||||||
|
var iconName = getMapIconForItems(datai.items);
|
||||||
|
//console.log(iconName);
|
||||||
|
|
||||||
|
var el = document.createElement("div");
|
||||||
|
el.className = "package-marker";
|
||||||
|
|
||||||
|
el.style = "background-image: url(assets/images/" + iconName + ".png);";
|
||||||
|
|
||||||
|
el.addEventListener('click', function () {
|
||||||
|
openPackageInfoSheet(datai.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
new mapboxgl.Marker(el)
|
||||||
|
.setLngLat([datai.coords[1], datai.coords[0]])
|
||||||
|
.addTo(map);
|
||||||
|
})(data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
map.animateMapIn = function (latitude, longitude, zoom, heading) {
|
||||||
|
if (typeof zoom == 'undefined') {
|
||||||
|
zoom = 16;
|
||||||
|
}
|
||||||
|
if (typeof heading == 'undefined') {
|
||||||
|
heading = 0;
|
||||||
|
}
|
||||||
|
map.flyTo({
|
||||||
|
center: [
|
||||||
|
longitude,
|
||||||
|
latitude
|
||||||
|
],
|
||||||
|
speed: 1,
|
||||||
|
zoom: zoom,
|
||||||
|
heading: heading,
|
||||||
|
pitch: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
map.animateMapIn(userPosition.coords.latitude, userPosition.coords.longitude, 12);
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
@ -11,14 +11,14 @@ if (localStorage.getItem("packages") != null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count how many items are still undelivered for an address.
|
* Count how many items are still undelivered for a location.
|
||||||
* @param {type} address An item in the packages array.
|
* @param {type} location An item in the packages array.
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
*/
|
*/
|
||||||
function getUndeliveredCount(address) {
|
function getUndeliveredCount(location) {
|
||||||
var undelivered = 0;
|
var undelivered = 0;
|
||||||
for (var i = 0; i < address.items.length; i++) {
|
for (var i = 0; i < location.items.length; i++) {
|
||||||
if (!address.items[i].delivered) {
|
if (!location.items[i].delivered) {
|
||||||
undelivered++;
|
undelivered++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,16 +65,16 @@ function getMapIconForItems(items) {
|
|||||||
// Count how many types we have, and set/overwrite the icon assuming we
|
// Count how many types we have, and set/overwrite the icon assuming we
|
||||||
// only have that type. If we end up with multiple types, we return that
|
// only have that type. If we end up with multiple types, we return that
|
||||||
// icon instead of a specific one.
|
// icon instead of a specific one.
|
||||||
console.log(types);
|
//console.log(types);
|
||||||
for (var type in types) {
|
for (var type in types) {
|
||||||
console.log(type);
|
//console.log(type);
|
||||||
item_types++;
|
item_types++;
|
||||||
if (types[type] == 1) {
|
if (types[type] == 1) {
|
||||||
icon = SETTINGS.itemtypes[type].mapicon;
|
icon = SETTINGS.itemtypes[type].mapicon;
|
||||||
} else {
|
} else {
|
||||||
icon = SETTINGS.itemtypes[type].pluralmapicon;
|
icon = SETTINGS.itemtypes[type].pluralmapicon;
|
||||||
}
|
}
|
||||||
console.log(icon);
|
//console.log(icon);
|
||||||
}
|
}
|
||||||
if (item_types > 1) {
|
if (item_types > 1) {
|
||||||
return "multiple-items";
|
return "multiple-items";
|
||||||
@ -82,22 +82,31 @@ function getMapIconForItems(items) {
|
|||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPackage(address, latitude, longitude, type, callback) {
|
function addPackage(address, latitude, longitude, type, callback, deadline) {
|
||||||
var added = false;
|
var added = false;
|
||||||
if (typeof type == 'undefined') {
|
if (typeof type == 'undefined') {
|
||||||
type = "package";
|
type = SETTINGS.itemtypes[0].id;
|
||||||
}
|
}
|
||||||
|
if (typeof deadline == 'undefined') {
|
||||||
|
deadline = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extra precision makes the map stupider,
|
||||||
|
// and doesn't really increase accuracy since four decimal places ~= 11m
|
||||||
|
latitude = +(parseFloat("" + latitude).toFixed(4));
|
||||||
|
longitude = +(parseFloat("" + longitude).toFixed(4));
|
||||||
|
|
||||||
var packageID = uuidv4();
|
var packageID = uuidv4();
|
||||||
var coordsID = "";
|
var coordsID = "";
|
||||||
|
|
||||||
for (var i = 0; i < packages.length; i++) {
|
for (var i = 0; i < packages.length; i++) {
|
||||||
if (packages[i].coords[0] == latitude && packages[i].coords[1] == longitude && packages[i].address == address) {
|
if (packages[i].coords[0] == latitude && packages[i].coords[1] == longitude) {
|
||||||
coordsID = packages[i].id;
|
coordsID = packages[i].id;
|
||||||
packages[i].items.push({
|
packages[i].items.push({
|
||||||
address: address,
|
address: address,
|
||||||
delivered: false,
|
delivered: false,
|
||||||
type: type,
|
type: type,
|
||||||
|
deadline: deadline,
|
||||||
id: packageID
|
id: packageID
|
||||||
});
|
});
|
||||||
added = true;
|
added = true;
|
||||||
@ -118,6 +127,7 @@ function addPackage(address, latitude, longitude, type, callback) {
|
|||||||
address: address,
|
address: address,
|
||||||
delivered: false,
|
delivered: false,
|
||||||
type: type,
|
type: type,
|
||||||
|
deadline: deadline,
|
||||||
id: packageID
|
id: packageID
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -128,7 +138,7 @@ function addPackage(address, latitude, longitude, type, callback) {
|
|||||||
playSound("ok");
|
playSound("ok");
|
||||||
|
|
||||||
app.toast.show({
|
app.toast.show({
|
||||||
text: 'Package Added!<br><span style="font-size: 80%;">' + address + "</span>",
|
text: SETTINGS.itemtypes[type].name + ' Added!<br><span style="font-size: 80%;">' + address + "</span>",
|
||||||
position: "bottom",
|
position: "bottom",
|
||||||
destroyOnClose: true,
|
destroyOnClose: true,
|
||||||
closeTimeout: 1000 * 3
|
closeTimeout: 1000 * 3
|
||||||
@ -148,6 +158,51 @@ function addPackage(address, latitude, longitude, type, callback) {
|
|||||||
addAutofillEntry(address);
|
addAutofillEntry(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import a second package list and merge it with the existing one.
|
||||||
|
* @param {type} newlist
|
||||||
|
* @return {number} The number of packages that were skipped because they already exist locally.
|
||||||
|
*/
|
||||||
|
function importPackageList(newlist) {
|
||||||
|
skipped = 0;
|
||||||
|
for (latlng in newlist) {
|
||||||
|
var latitude = newlist[latlng].coords[0];
|
||||||
|
var longitude = newlist[latlng].coords[1];
|
||||||
|
|
||||||
|
latitude = +(parseFloat("" + latitude).toFixed(4));
|
||||||
|
longitude = +(parseFloat("" + longitude).toFixed(4));
|
||||||
|
|
||||||
|
for (pkg in newlist[latlng].items) {
|
||||||
|
var added = false;
|
||||||
|
for (var i = 0; i < packages.length; i++) {
|
||||||
|
if (+(parseFloat("" + packages[i].coords[0]).toFixed(4)) == latitude && +(parseFloat("" + packages[i].coords[1]).toFixed(4)) == longitude) {
|
||||||
|
var newpackage = newlist[latlng].items[pkg];
|
||||||
|
for (var j in packages[i].items) {
|
||||||
|
if (packages[i].items[j].id == newpackage.id) {
|
||||||
|
// This package already exists in the local database.
|
||||||
|
added = true;
|
||||||
|
skipped++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!added) {
|
||||||
|
packages[i].items.push(package);
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!added) {
|
||||||
|
packages.push(newlist[latlng]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
localStorage.setItem("packages", JSON.stringify(packages));
|
||||||
|
if (map != null) {
|
||||||
|
reloadMap();
|
||||||
|
}
|
||||||
|
return skipped;
|
||||||
|
}
|
||||||
|
|
||||||
function markDelivered(id, delivered) {
|
function markDelivered(id, delivered) {
|
||||||
for (var i = 0; i < packages.length; i++) {
|
for (var i = 0; i < packages.length; i++) {
|
||||||
for (var j = 0; j < packages[i].items.length; j++) {
|
for (var j = 0; j < packages[i].items.length; j++) {
|
||||||
@ -173,7 +228,7 @@ function markDelivered(id, delivered) {
|
|||||||
|
|
||||||
function confirmDeletePackage(package, callback) {
|
function confirmDeletePackage(package, callback) {
|
||||||
app.dialog.confirm(
|
app.dialog.confirm(
|
||||||
"Delete item at " + package.address + "?",
|
"Delete " + SETTINGS.itemtypes[package.type].name.toLowerCase() + " at " + package.address + "?",
|
||||||
"Confirm",
|
"Confirm",
|
||||||
function () {
|
function () {
|
||||||
// delete
|
// delete
|
||||||
@ -229,60 +284,184 @@ function countPackages() {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPackageByAddress(address, citystate, type, callback) {
|
function addPackageByAddress(number, street, citystate, type, callback) {
|
||||||
var requestfinished = false;
|
var requestfinished = false;
|
||||||
var searchingdialogopen = false;
|
var searchingdialogopen = false;
|
||||||
$.ajax({
|
var deadline = false;
|
||||||
url: SETTINGS.geocodeapi,
|
|
||||||
dataType: 'json',
|
var ajaxlookup = function () {
|
||||||
data: {
|
var geocodecache = localStorage.getItem("geocode_cache");
|
||||||
address: address + " " + citystate
|
if (geocodecache == null) {
|
||||||
},
|
geocodecache = "{}";
|
||||||
timeout: 15 * 1000,
|
localStorage.setItem("geocode_cache", "{}");
|
||||||
success: function (resp) {
|
}
|
||||||
if (searchingdialogopen) {
|
|
||||||
app.dialog.close();
|
geocodecache = JSON.parse(geocodecache);
|
||||||
searchingdialogopen = false;
|
var cachekey = number + " || " + street + " || " + citystate;
|
||||||
|
var cacheitem = geocodecache[cachekey];
|
||||||
|
var timestamp = Math.floor(Date.now() / 1000);
|
||||||
|
if (typeof cacheitem != 'undefined') {
|
||||||
|
if (cacheitem.added + SETTINGS.geocodecacheexpiry < timestamp) {
|
||||||
|
console.log("Info", "Removing expired geocode cache item " + cachekey);
|
||||||
|
delete geocodecache[cachekey];
|
||||||
|
localStorage.setItem("geocode_cache", JSON.stringify(geocodecache));
|
||||||
|
} else {
|
||||||
|
console.log("Info", "Using cached geocode result", cacheitem);
|
||||||
|
addPackage(cacheitem.address, cacheitem.latitude, cacheitem.longitude, type, callback, deadline);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
requestfinished = true;
|
}
|
||||||
if (resp.status == "OK") {
|
|
||||||
if (resp.accuracy.ok) {
|
$.ajax({
|
||||||
addPackage(resp.address.street, resp.coords[0], resp.coords[1], type, callback);
|
url: SETTINGS.geocodeapi,
|
||||||
|
dataType: 'json',
|
||||||
|
data: {
|
||||||
|
number: number,
|
||||||
|
street: street,
|
||||||
|
citystate: citystate
|
||||||
|
},
|
||||||
|
timeout: 15 * 1000,
|
||||||
|
success: function (resp) {
|
||||||
|
if (searchingdialogopen) {
|
||||||
|
app.dialog.close();
|
||||||
|
searchingdialogopen = false;
|
||||||
|
}
|
||||||
|
requestfinished = true;
|
||||||
|
if (resp.status == "OK") {
|
||||||
|
if (resp.accuracy.ok) {
|
||||||
|
addPackage(resp.address.street, resp.coords[0], resp.coords[1], type, callback, deadline);
|
||||||
|
geocodecache[cachekey] = {
|
||||||
|
address: resp.address.street,
|
||||||
|
latitude: resp.coords[0],
|
||||||
|
longitude: resp.coords[1],
|
||||||
|
added: Math.floor(Date.now() / 1000)
|
||||||
|
};
|
||||||
|
localStorage.setItem("geocode_cache", JSON.stringify(geocodecache));
|
||||||
|
} else {
|
||||||
|
playSound("error");
|
||||||
|
app.dialog.confirm(
|
||||||
|
"The address \"" + address + "\" couldn't be reliably located. Add it anyways?",
|
||||||
|
"Accuracy Warning",
|
||||||
|
function (ok) {
|
||||||
|
if (resp.address.street == "") {
|
||||||
|
addPackage(address, resp.coords[0], resp.coords[1], type, callback, deadline);
|
||||||
|
} else {
|
||||||
|
addPackage(resp.address.street, resp.coords[0], resp.coords[1], type, callback, deadline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
playSound("error");
|
playSound("error");
|
||||||
app.dialog.confirm(
|
app.dialog.alert(resp.message, "Error");
|
||||||
"The address \"" + address + "\" couldn't be reliably located. Add it anyways?",
|
}
|
||||||
"Accuracy Warning",
|
},
|
||||||
function (ok) {
|
error: function (jqXHR, status, errorThrown) {
|
||||||
if (resp.address.street == "") {
|
if (searchingdialogopen) {
|
||||||
addPackage(address, resp.coords[0], resp.coords[1], type, callback);
|
app.dialog.close();
|
||||||
} else {
|
searchingdialogopen = false;
|
||||||
addPackage(resp.address.street, resp.coords[0], resp.coords[1], type, callback);
|
}
|
||||||
}
|
requestfinished = true;
|
||||||
|
playSound("error");
|
||||||
|
app.dialog.alert("There was a network issue while finding the address. Please try adding the item again.", "Error");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Open a loading message if there's a delay finding the address
|
||||||
|
setTimeout(function () {
|
||||||
|
if (!requestfinished) {
|
||||||
|
app.dialog.preloader("Searching for address...");
|
||||||
|
searchingdialogopen = true;
|
||||||
|
}
|
||||||
|
}, 750);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == "express") {
|
||||||
|
if (localStorage.getItem("deadlinealarm_minutes") == null) {
|
||||||
|
localStorage.setItem("deadlinealarm_minutes", 20);
|
||||||
|
}
|
||||||
|
var minutes = localStorage.getItem("deadlinealarm_minutes");
|
||||||
|
app.dialog.create({
|
||||||
|
title: 'Express Item',
|
||||||
|
text: 'Set a reminder for ' + minutes + ' minutes before:',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: '10:30 AM',
|
||||||
|
close: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '12:00 PM',
|
||||||
|
close: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '3:00 PM',
|
||||||
|
close: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "No reminder",
|
||||||
|
color: "red",
|
||||||
|
close: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
verticalButtons: true,
|
||||||
|
onClick: function (dialog, index) {
|
||||||
|
deadline = new Date();
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
deadline.setMinutes(30);
|
||||||
|
deadline.setHours(10);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
deadline.setMinutes(00);
|
||||||
|
deadline.setHours(12);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
deadline.setMinutes(00);
|
||||||
|
deadline.setHours(12 + 3);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
default:
|
||||||
|
deadline = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deadline != false) {
|
||||||
|
deadline = deadline.getTime() / 1000;
|
||||||
|
}
|
||||||
|
ajaxlookup();
|
||||||
|
}
|
||||||
|
}).open();
|
||||||
|
} else {
|
||||||
|
ajaxlookup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkDeadlines() {
|
||||||
|
if (localStorage.getItem("deadlinealarm_minutes") == null) {
|
||||||
|
localStorage.setItem("deadlinealarm_minutes", 20);
|
||||||
|
}
|
||||||
|
var minutes = localStorage.getItem("deadlinealarm_minutes");
|
||||||
|
var currentTime = new Date().getTime() / 1000;
|
||||||
|
var deadlineTime = currentTime + (minutes * 60);
|
||||||
|
for (i in packages) {
|
||||||
|
for (j in packages[i].items) {
|
||||||
|
var item = packages[i].items[j];
|
||||||
|
if (typeof item.deadline != 'undefined' && item.deadline != false && item.delivered != true) {
|
||||||
|
if ((typeof item.deadlinealarmed == 'undefined' || item.deadlinealarmed != true) && item.deadline <= deadlineTime) {
|
||||||
|
playSound("alert");
|
||||||
|
app.dialog.alert(
|
||||||
|
"Item at " + item.address + " needs to be delivered by " + timestampToTimeString(item.deadline) + " (" + Math.floor((item.deadline - currentTime) / 60) + " minutes from now).",
|
||||||
|
"Delivery Alarm",
|
||||||
|
function () {
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
packages[i].items[j].deadlinealarmed = true;
|
||||||
|
localStorage.setItem("packages", JSON.stringify(packages));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
playSound("error");
|
|
||||||
app.dialog.alert(resp.message, "Error");
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
error: function (jqXHR, status, errorThrown) {
|
|
||||||
if (searchingdialogopen) {
|
|
||||||
app.dialog.close();
|
|
||||||
searchingdialogopen = false;
|
|
||||||
}
|
|
||||||
requestfinished = true;
|
|
||||||
playSound("error");
|
|
||||||
app.dialog.alert("There was a network issue while finding the address. Please try adding the item again.", "Error");
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Open a loading message if there's a delay finding the address
|
setInterval(checkDeadlines, 15 * 1000);
|
||||||
setTimeout(function () {
|
|
||||||
if (!requestfinished) {
|
|
||||||
app.dialog.preloader("Searching for address...");
|
|
||||||
searchingdialogopen = true;
|
|
||||||
}
|
|
||||||
}, 750);
|
|
||||||
}
|
|
@ -64,30 +64,76 @@ var watchLocation = function (success, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupHTML5BarcodeScanner() {
|
||||||
|
$("body").append('<script src="node_modules/@zxing/library/umd/index.min.js"></script>');
|
||||||
|
|
||||||
|
scanBarcode = function (success, error) {
|
||||||
|
$("#web-barcode-ui").removeClass("hidden");
|
||||||
|
// Stolen from https://zxing-js.github.io/library/examples/multi-camera/
|
||||||
|
const codeReader = new ZXing.BrowserMultiFormatReader();
|
||||||
|
console.log("Info", 'ZXing code reader initialized');
|
||||||
|
codeReader.getVideoInputDevices()
|
||||||
|
.then((videoInputDevices) => {
|
||||||
|
if (videoInputDevices.length == 0) {
|
||||||
|
codeReader.reset();
|
||||||
|
$("#web-barcode-ui").addClass("hidden");
|
||||||
|
error("A camera is required to scan barcodes.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selectedDeviceId = videoInputDevices[0].deviceId;
|
||||||
|
|
||||||
|
codeReader.decodeFromInputVideoDeviceContinuously(selectedDeviceId, 'barcode-viewer', (result, err) => {
|
||||||
|
if (result) {
|
||||||
|
codeReader.reset();
|
||||||
|
$("#web-barcode-ui").addClass("hidden");
|
||||||
|
success(result.text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (err && !(err instanceof ZXing.NotFoundException)) {
|
||||||
|
console.error(err);
|
||||||
|
codeReader.reset();
|
||||||
|
$("#web-barcode-ui").addClass("hidden");
|
||||||
|
error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
$("#web-barcode-ui").on("click", function () {
|
||||||
|
codeReader.reset();
|
||||||
|
$("#web-barcode-ui").addClass("hidden");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function initCordova() {
|
function initCordova() {
|
||||||
platform_type = "cordova";
|
platform_type = "cordova";
|
||||||
|
|
||||||
// Handle back button to close things
|
// Handle back button to close things
|
||||||
document.addEventListener("backbutton", function (event) {
|
document.addEventListener("backbutton", function (event) {
|
||||||
router.back({force: true, ignoreCache: true});
|
// Close map sheet if it's open
|
||||||
|
if ($(".sheet-modal").hasClass("modal-in")) {
|
||||||
|
app.sheet.close();
|
||||||
|
} else {
|
||||||
|
router.back({force: true, ignoreCache: true});
|
||||||
|
}
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
document.addEventListener("deviceready", function () {
|
document.addEventListener("deviceready", function () {
|
||||||
if (localStorage.getItem("wakelock") == "true") {
|
if (localStorage.getItem("wakelock") == "true") {
|
||||||
window.powerManagement.acquire(function () {
|
window.powerManagement.acquire(function () {
|
||||||
console.log('Wakelock acquired');
|
console.log("Info", 'Wakelock acquired');
|
||||||
}, function () {
|
}, function () {
|
||||||
console.log('Failed to acquire wakelock');
|
console.log("Warn", 'Failed to acquire wakelock');
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
window.powerManagement.release(function () {
|
window.powerManagement.release(function () {
|
||||||
console.log('Wakelock released');
|
console.log("Info", 'Wakelock released');
|
||||||
}, function () {
|
}, function () {
|
||||||
console.log('Failed to release wakelock');
|
console.log("Warn", 'Failed to release wakelock');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
openBrowser = function (url) {
|
openBrowser = function (url) {
|
||||||
cordova.InAppBrowser.open(url, '_blank', 'location=yes');
|
cordova.InAppBrowser.open(url, '_blank', 'location=yes');
|
||||||
}
|
}
|
||||||
@ -96,34 +142,37 @@ function initCordova() {
|
|||||||
window.open(url, '_system', '');
|
window.open(url, '_system', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
scanBarcode = function (success, error) {
|
if (typeof device != "undefined" && device.platform != "browser") {
|
||||||
cordova.plugins.barcodeScanner.scan(
|
scanBarcode = function (success, error) {
|
||||||
function (result) {
|
cordova.plugins.barcodeScanner.scan(
|
||||||
if (!result.cancelled) {
|
function (result) {
|
||||||
success(result.text);
|
if (!result.cancelled) {
|
||||||
|
success(result.text);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function (err) {
|
||||||
|
if (typeof error == "function") {
|
||||||
|
error(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
showTorchButton: true,
|
||||||
|
showFlipCameraButton: true,
|
||||||
|
prompt: "Scan barcode",
|
||||||
|
resultDisplayDuration: 0,
|
||||||
|
disableSuccessBeep: true,
|
||||||
|
formats: "QR_CODE,DATA_MATRIX,CODE_39,CODE_93,CODE_128,CODABAR,PDF_417,AZTEC,MAXICODE"
|
||||||
}
|
}
|
||||||
},
|
);
|
||||||
function (err) {
|
};
|
||||||
if (typeof error == "function") {
|
} else {
|
||||||
error(err);
|
setupHTML5BarcodeScanner();
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
showTorchButton: true,
|
|
||||||
showFlipCameraButton : true,
|
|
||||||
prompt: "Scan barcode",
|
|
||||||
resultDisplayDuration: 0,
|
|
||||||
disableSuccessBeep: true,
|
|
||||||
formats: "QR_CODE,DATA_MATRIX,CODE_39,CODE_93,CODE_128,CODABAR,PDF_417,AZTEC,MAXICODE"
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function initNW() {
|
function initNW() {
|
||||||
platform_type = "nw";
|
platform_type = "nw";
|
||||||
platform_theme = "md";
|
platform_theme = "md";
|
||||||
|
|
||||||
openBrowser = function (url) {
|
openBrowser = function (url) {
|
||||||
nw.Window.open(url, {
|
nw.Window.open(url, {
|
||||||
id: url
|
id: url
|
||||||
@ -156,57 +205,22 @@ function initNW() {
|
|||||||
require('nw.gui').Shell.openExternal(url);
|
require('nw.gui').Shell.openExternal(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
$("body").append('<script src="node_modules/@zxing/library/umd/index.min.js"></script>');
|
|
||||||
|
|
||||||
scanBarcode = function (success, error) {
|
setupHTML5BarcodeScanner();
|
||||||
$("#web-barcode-ui").removeClass("hidden");
|
|
||||||
// Stolen from https://zxing-js.github.io/library/examples/multi-camera/
|
|
||||||
const codeReader = new ZXing.BrowserMultiFormatReader();
|
|
||||||
console.log('ZXing code reader initialized');
|
|
||||||
codeReader.getVideoInputDevices()
|
|
||||||
.then((videoInputDevices) => {
|
|
||||||
if (videoInputDevices.length == 0) {
|
|
||||||
codeReader.reset();
|
|
||||||
$("#web-barcode-ui").addClass("hidden");
|
|
||||||
error("A camera is required to scan barcodes.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
selectedDeviceId = videoInputDevices[0].deviceId;
|
|
||||||
|
|
||||||
codeReader.decodeFromInputVideoDeviceContinuously(selectedDeviceId, 'barcode-viewer', (result, err) => {
|
|
||||||
if (result) {
|
|
||||||
console.log(result);
|
|
||||||
codeReader.reset();
|
|
||||||
$("#web-barcode-ui").addClass("hidden");
|
|
||||||
success(result.text);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (err && !(err instanceof ZXing.NotFoundException)) {
|
|
||||||
console.error(err);
|
|
||||||
codeReader.reset();
|
|
||||||
$("#web-barcode-ui").addClass("hidden");
|
|
||||||
error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
$("#web-barcode-ui").on("click", function () {
|
|
||||||
codeReader.reset();
|
|
||||||
$("#web-barcode-ui").addClass("hidden");
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initBrowser() {
|
function initBrowser() {
|
||||||
platform_type = "browser";
|
platform_type = "browser";
|
||||||
platform_theme = "md";
|
platform_theme = "md";
|
||||||
|
|
||||||
openBrowser = function (url) {
|
openBrowser = function (url) {
|
||||||
window.open(url);
|
window.open(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openExternalBrowser = function (url) {
|
||||||
|
window.open(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
setupHTML5BarcodeScanner();
|
||||||
}
|
}
|
||||||
|
|
||||||
function initPlatform() {
|
function initPlatform() {
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
$('.item-content[data-setting=darktheme] .toggle input').on("change", function () {
|
$('.item-content[data-setting=darktheme] .toggle input').on("change", function () {
|
||||||
var checked = $(this).prop('checked');
|
var checked = $(this).prop('checked');
|
||||||
console.log(checked);
|
|
||||||
localStorage.setItem("darktheme", checked);
|
localStorage.setItem("darktheme", checked);
|
||||||
|
|
||||||
if (localStorage.getItem("darktheme") == "true") {
|
if (localStorage.getItem("darktheme") == "true") {
|
||||||
@ -17,27 +16,35 @@ $('.item-content[data-setting=darktheme] .toggle input').on("change", function (
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('.item-content[data-setting=showhelp] .toggle input').on("change", function () {
|
||||||
|
var checked = $(this).prop('checked');
|
||||||
|
localStorage.setItem("show_help", checked);
|
||||||
|
});
|
||||||
|
|
||||||
$('.item-link[data-setting=units] select').on("change", function () {
|
$('.item-link[data-setting=units] select').on("change", function () {
|
||||||
localStorage.setItem("units", $('.item-link[data-setting=units] select').val());
|
localStorage.setItem("units", $('.item-link[data-setting=units] select').val());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('.item-link[data-setting=trackzoom] select').on("change", function () {
|
||||||
|
localStorage.setItem("trackzoom", $('.item-link[data-setting=trackzoom] select').val());
|
||||||
|
});
|
||||||
|
|
||||||
$('.item-content[data-setting=wakelock] .toggle input').on("change", function () {
|
$('.item-content[data-setting=wakelock] .toggle input').on("change", function () {
|
||||||
var checked = $(this).prop('checked');
|
var checked = $(this).prop('checked');
|
||||||
console.log(checked);
|
|
||||||
localStorage.setItem("wakelock", checked);
|
localStorage.setItem("wakelock", checked);
|
||||||
|
|
||||||
if (platform_type == "cordova") {
|
if (platform_type == "cordova") {
|
||||||
if (localStorage.getItem("wakelock") == "true") {
|
if (localStorage.getItem("wakelock") == "true") {
|
||||||
window.powerManagement.acquire(function () {
|
window.powerManagement.acquire(function () {
|
||||||
console.log('Wakelock acquired');
|
console.log("Info", 'Wakelock acquired');
|
||||||
}, function () {
|
}, function () {
|
||||||
console.log('Failed to acquire wakelock');
|
console.log("Warn", 'Failed to acquire wakelock');
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
window.powerManagement.release(function () {
|
window.powerManagement.release(function () {
|
||||||
console.log('Wakelock released');
|
console.log("Info", 'Wakelock released');
|
||||||
}, function () {
|
}, function () {
|
||||||
console.log('Failed to release wakelock');
|
console.log("Warn", 'Failed to release wakelock');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -69,7 +76,16 @@ $('.item-content[data-setting=alertinterval] .range-slider').on('range:changed',
|
|||||||
|
|
||||||
$('.item-link[data-setting=mapsource] select').on("change", function () {
|
$('.item-link[data-setting=mapsource] select').on("change", function () {
|
||||||
localStorage.setItem("mapsource", $('.item-link[data-setting=mapsource] select').val());
|
localStorage.setItem("mapsource", $('.item-link[data-setting=mapsource] select').val());
|
||||||
// Re-init map to load new style
|
|
||||||
|
reloadMap();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.item-content[data-setting=maptype] .toggle input').on("change", function () {
|
||||||
|
var checked = $(this).prop('checked');
|
||||||
|
localStorage.setItem("maptype", checked ? "leaflet" : "mapbox");
|
||||||
|
|
||||||
|
maptype = checked ? "leaflet" : "mapbox";
|
||||||
|
|
||||||
reloadMap();
|
reloadMap();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
271
www/assets/js/toolbox_scanner.js
Normal file
271
www/assets/js/toolbox_scanner.js
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var scannerCodes = [];
|
||||||
|
|
||||||
|
function resetScanner() {
|
||||||
|
scannerCodes = [];
|
||||||
|
app.popup.close("#scanEventTypePopup");
|
||||||
|
app.popup.close("#scanEventPopup");
|
||||||
|
router.refreshPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
function brokenScannerEsc() {
|
||||||
|
app.dialog.confirm(
|
||||||
|
"Clear list?",
|
||||||
|
"Confirm",
|
||||||
|
function () {
|
||||||
|
resetScanner();
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
// cancel
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function brokenScannerScan() {
|
||||||
|
scanBarcode(function (code) {
|
||||||
|
playSound("scan");
|
||||||
|
if (code != "" && code.length > 5 && code.match(/^[0-9A-Z]+$/i)) {
|
||||||
|
addCodeToScannerList(code);
|
||||||
|
} else {
|
||||||
|
app.dialog.alert("That's not a valid tracking code.", "Error");
|
||||||
|
}
|
||||||
|
}, function (error) {
|
||||||
|
app.dialog.alert(error, "Error");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function brokenScannerAddTextEntry() {
|
||||||
|
var code = $("#brokenscannerinput").val();
|
||||||
|
if (code != "" && code.length > 5 && code.match(/^[0-9A-Z]+$/i)) {
|
||||||
|
addCodeToScannerList(code);
|
||||||
|
$("#brokenscannerinput").val("");
|
||||||
|
} else {
|
||||||
|
app.dialog.alert("That's not a valid tracking code.", "Error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addCodeToScannerList(code) {
|
||||||
|
code = code.toUpperCase();
|
||||||
|
|
||||||
|
var signatureregexes = [
|
||||||
|
/^E[A-Z][0-9]{9}US$/, // Priority Mail Express
|
||||||
|
/^[RV][A-Z][0-9]{9}[A-Z]{2}$/, // Registered mail
|
||||||
|
/^(420[0-9]{5})?7[0-9]{19}$/ // Certified Mail
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regex of IMpb codes that don't need anything special
|
||||||
|
* @type {RegExp}
|
||||||
|
*/
|
||||||
|
var stcregex = /^(420[0-9]{5})?[0-9]{2}(001|023|055|056|112|113|134|135|138|140|141|142|164|209|211|259|265|269|346|361|389|390|419|431|490|502|551|563|612|624|671|701|702|703|704|723|746|748|790|791|793|794|905|906|907|909|971|972)[0-9]+$/;
|
||||||
|
|
||||||
|
var signatureRequired = false;
|
||||||
|
for (var i = 0; i < signatureregexes.length; i++) {
|
||||||
|
if (code.match(signatureregexes[i])) {
|
||||||
|
signatureRequired = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!code.match(stcregex)) {
|
||||||
|
signatureRequired = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var codeEntryTemplate = Template7.compile('<li class="codelist-entry" data-code="{{code}}">'
|
||||||
|
+ ' <div class="item-content">'
|
||||||
|
+ ' <div class="item-inner">'
|
||||||
|
+ ' <div class="item-title">{{code}}</div>'
|
||||||
|
+ ' </div>'
|
||||||
|
+ ' </div>'
|
||||||
|
+ '</li>');
|
||||||
|
|
||||||
|
if (signatureRequired) {
|
||||||
|
if (code.match(/^E[A-Z][0-9]{9}US$/)) {
|
||||||
|
app.dialog.confirm(
|
||||||
|
"Does this item contain a waiver of signature endorsement?",
|
||||||
|
"Express Item",
|
||||||
|
function () {
|
||||||
|
$("#codelist").append(codeEntryTemplate({
|
||||||
|
code: code
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
// cancel
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
app.dialog.confirm(
|
||||||
|
"It looks like this item might require a signature or other special procedures. Add it anyways?",
|
||||||
|
"Signature Item",
|
||||||
|
function () {
|
||||||
|
$("#codelist").append(codeEntryTemplate({
|
||||||
|
code: code
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
// cancel
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$("#codelist").append(codeEntryTemplate({
|
||||||
|
code: code
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function chooseScanEvent() {
|
||||||
|
if ($("#codelist li.codelist-entry").length <= 0) {
|
||||||
|
app.dialog.alert("Nothing was entered!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#codelist li.codelist-entry").each(function () {
|
||||||
|
scannerCodes.push($(this).data("code"));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
openEventPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
function openEventPopup() {
|
||||||
|
var eventItemTemplate = Template7.compile('<li data-button="{{button}}" data-title="{{title}}" class="eventbutton" onclick=\'openEventTypePopup("{{title}}");\'>'
|
||||||
|
+ ' <div class="item-link item-content">'
|
||||||
|
+ ' <div class="item-media">{{button}}</div>'
|
||||||
|
+ ' <div class="item-inner">'
|
||||||
|
+ ' <div class="item-title">{{title}}</div>'
|
||||||
|
+ ' </div>'
|
||||||
|
+ ' </div>'
|
||||||
|
+ '</li>');
|
||||||
|
|
||||||
|
$("#scanEventPopup ul.eventlist").html("");
|
||||||
|
for (i in SETTINGS.scannerevents) {
|
||||||
|
var event = SETTINGS.scannerevents[i];
|
||||||
|
$("#scanEventPopup ul.eventlist").append(eventItemTemplate({
|
||||||
|
button: event.button,
|
||||||
|
title: event.title
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
app.popup.open("#scanEventPopup");
|
||||||
|
}
|
||||||
|
|
||||||
|
function openEventTypePopup(eventname) {
|
||||||
|
var eventItemTemplate = Template7.compile('<li data-button="{{button}}" data-title="{{title}}" data-parenttitle="{{parenttitle}}" data-form3849="{{form3849}}" class="eventbutton eventtypebutton">'
|
||||||
|
+ ' <div class="item-link item-content">'
|
||||||
|
+ ' <div class="item-media">{{button}}</div>'
|
||||||
|
+ ' <div class="item-inner">'
|
||||||
|
+ ' <div class="item-title">{{title}}</div>'
|
||||||
|
+ ' </div>'
|
||||||
|
+ ' </div>'
|
||||||
|
+ '</li>');
|
||||||
|
|
||||||
|
var eventafter = false;
|
||||||
|
for (i in SETTINGS.scannerevents) {
|
||||||
|
var event = SETTINGS.scannerevents[i];
|
||||||
|
if (event.title == eventname) {
|
||||||
|
eventafter = event.after;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#scanEventTypePopup ul.eventlist").html("");
|
||||||
|
for (i in eventafter) {
|
||||||
|
var event = eventafter[i];
|
||||||
|
$("#scanEventTypePopup ul.eventlist").append(eventItemTemplate({
|
||||||
|
button: event.button,
|
||||||
|
title: event.title,
|
||||||
|
parenttitle: eventname,
|
||||||
|
form3849: event.after == "3849" ? "1" : "0"
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
app.popup.open("#scanEventTypePopup");
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveScanCode(code) {
|
||||||
|
if (localStorage.getItem("scanevents") == null) {
|
||||||
|
localStorage.setItem("scanevents", "[]");
|
||||||
|
}
|
||||||
|
var events = JSON.parse(localStorage.getItem("scanevents"));
|
||||||
|
events.push(code);
|
||||||
|
localStorage.setItem("scanevents", JSON.stringify(events));
|
||||||
|
}
|
||||||
|
|
||||||
|
$(".view-main").off("click", "#codelist li.codelist-entry");
|
||||||
|
|
||||||
|
$(".view-main").on("click", "#codelist li.codelist-entry", function () {
|
||||||
|
var entry = $(this);
|
||||||
|
var code = entry.data("code");
|
||||||
|
app.dialog.confirm(
|
||||||
|
"Remove " + code + " from list?",
|
||||||
|
"Confirm",
|
||||||
|
function () {
|
||||||
|
// delete
|
||||||
|
entry.remove();
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
// cancel
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#app").off("click", "ul li.eventtypebutton");
|
||||||
|
$("#app").on("click", "ul li.eventtypebutton", function () {
|
||||||
|
var eventname = $(this).data("parenttitle");
|
||||||
|
var eventtypename = $(this).data("title");
|
||||||
|
|
||||||
|
var scanEvent = [];
|
||||||
|
scanEvent.push(eventname);
|
||||||
|
scanEvent.push(eventtypename);
|
||||||
|
|
||||||
|
if ($(this).data("form3849") == "1") {
|
||||||
|
// TODO: make this not a hack
|
||||||
|
app.dialog.prompt("Key in 3849 form", "3849 Form", function (formcode) {
|
||||||
|
for (i in scannerCodes) {
|
||||||
|
saveScanCode({
|
||||||
|
code: scannerCodes[i],
|
||||||
|
event: scanEvent,
|
||||||
|
form3849: formcode,
|
||||||
|
date: timestampToDateTimeString((new Date).getTime() / 1000)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
app.toast.show({
|
||||||
|
text: 'Information recorded successfully!',
|
||||||
|
position: "center",
|
||||||
|
destroyOnClose: true,
|
||||||
|
closeTimeout: 1000 * 3
|
||||||
|
});
|
||||||
|
resetScanner();
|
||||||
|
}, function () {
|
||||||
|
|
||||||
|
}, "");
|
||||||
|
} else {
|
||||||
|
for (i in scannerCodes) {
|
||||||
|
saveScanCode({
|
||||||
|
code: scannerCodes[i],
|
||||||
|
event: scanEvent,
|
||||||
|
form3849: "",
|
||||||
|
date: timestampToDateTimeString((new Date).getTime() / 1000)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
app.toast.show({
|
||||||
|
text: 'Information recorded successfully!',
|
||||||
|
position: "center",
|
||||||
|
destroyOnClose: true,
|
||||||
|
closeTimeout: 1000 * 3
|
||||||
|
});
|
||||||
|
resetScanner();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#brokenscannerinput").on('keypress', function (e) {
|
||||||
|
if (event.key === "Enter") {
|
||||||
|
brokenScannerAddTextEntry();
|
||||||
|
}
|
||||||
|
});
|
23
www/assets/js/toolbox_scannerentries.js
Normal file
23
www/assets/js/toolbox_scannerentries.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
function confirmDeleteScanEntries() {
|
||||||
|
app.dialog.confirm(
|
||||||
|
"Really delete all entries from scan list?",
|
||||||
|
"Clear Entries",
|
||||||
|
function () {
|
||||||
|
// clear
|
||||||
|
localStorage.setItem("scanevents", "[]");
|
||||||
|
router.navigate("/toolbox/scanner/entries", {
|
||||||
|
reloadCurrent: true
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
// cancel
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
101
www/assets/js/toolbox_sharelist.js
Normal file
101
www/assets/js/toolbox_sharelist.js
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
function uploadList() {
|
||||||
|
if (packages.length == 0) {
|
||||||
|
app.dialog.alert("Your list doesn't have anything to send.", "Empty List");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
app.dialog.preloader("Uploading...");
|
||||||
|
var uploadlistdialogopen = true;
|
||||||
|
$.ajax({
|
||||||
|
url: SETTINGS.sharelistapi,
|
||||||
|
dataType: 'json',
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
packages: JSON.stringify(packages)
|
||||||
|
},
|
||||||
|
timeout: 15 * 1000,
|
||||||
|
success: function (resp) {
|
||||||
|
if (uploadlistdialogopen) {
|
||||||
|
app.dialog.close();
|
||||||
|
uploadlistdialogopen = false;
|
||||||
|
}
|
||||||
|
if (resp.status == "OK") {
|
||||||
|
JsBarcode("#listidbarcode", resp.uuid, {
|
||||||
|
format: "code128",
|
||||||
|
ean128: false,
|
||||||
|
width: 2,
|
||||||
|
height: 40
|
||||||
|
});
|
||||||
|
$("#listidbarcodeli").css("display", "");
|
||||||
|
} else {
|
||||||
|
app.dialog.alert(resp.message, "Error");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function (jqXHR, status, errorThrown) {
|
||||||
|
if (uploadlistdialogopen) {
|
||||||
|
app.dialog.close();
|
||||||
|
uploadlistdialogopen = false;
|
||||||
|
}
|
||||||
|
app.dialog.alert("There was a network or server issue while uploading the list. Please try again.", "Error");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadItemList(code) {
|
||||||
|
if (typeof code == "undefined") {
|
||||||
|
code = $("#getlistidbox").val();
|
||||||
|
}
|
||||||
|
if (code.match(/^[a-f0-9]{10}$/i)) {
|
||||||
|
app.dialog.preloader("Downloading...");
|
||||||
|
var downloadlistdialogopen = true;
|
||||||
|
$.ajax({
|
||||||
|
url: SETTINGS.sharelistapi,
|
||||||
|
dataType: 'json',
|
||||||
|
method: 'get',
|
||||||
|
data: {
|
||||||
|
uuid: code
|
||||||
|
},
|
||||||
|
timeout: 15 * 1000,
|
||||||
|
success: function (resp) {
|
||||||
|
if (downloadlistdialogopen) {
|
||||||
|
app.dialog.close();
|
||||||
|
downloadlistdialogopen = false;
|
||||||
|
}
|
||||||
|
if (resp.status == "OK") {
|
||||||
|
var skipped = importPackageList(resp.packages);
|
||||||
|
if (skipped > 0) {
|
||||||
|
app.dialog.alert("List imported and merged with the existing one. " + skipped + " items already existed locally and were skipped. Verify their delivery status manually.", "Import Complete");
|
||||||
|
} else {
|
||||||
|
app.dialog.alert("List imported and merged with the existing one.", "Import Complete");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
app.dialog.alert(resp.message, "Error");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function (jqXHR, status, errorThrown) {
|
||||||
|
if (downloadlistdialogopen) {
|
||||||
|
app.dialog.close();
|
||||||
|
downloadlistdialogopen = false;
|
||||||
|
}
|
||||||
|
app.dialog.alert("There was a network or server issue while downloading the list. Please try again.", "Error");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
app.dialog.alert("That's not a valid list ID.", "Error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function scanListIDBarcode() {
|
||||||
|
scanBarcode(function (code) {
|
||||||
|
playSound("scan");
|
||||||
|
downloadItemList(code);
|
||||||
|
}, function (error) {
|
||||||
|
app.dialog.alert(error, "Error");
|
||||||
|
});
|
||||||
|
}
|
@ -86,7 +86,21 @@ function openTrackingHistory(code) {
|
|||||||
infocontext.history[i].date = timestampToDateTimeString(infocontext.history[i].date);
|
infocontext.history[i].date = timestampToDateTimeString(infocontext.history[i].date);
|
||||||
infocontext.history[i].status = trackingStatusToNiceString(infocontext.history[i].status, true);
|
infocontext.history[i].status = trackingStatusToNiceString(infocontext.history[i].status, true);
|
||||||
}
|
}
|
||||||
// TODO: format timestamps as local time
|
|
||||||
|
// Keep last five tracking codes in history
|
||||||
|
var history = localStorage.getItem("trackingcodehistory");
|
||||||
|
if (history == null) {
|
||||||
|
history = [];
|
||||||
|
} else {
|
||||||
|
history = JSON.parse(history);
|
||||||
|
}
|
||||||
|
if (infocontext.code != "" && !history.includes(infocontext.code)) {
|
||||||
|
history.push(infocontext.code);
|
||||||
|
}
|
||||||
|
while (history.length > 5) {
|
||||||
|
history.shift();
|
||||||
|
}
|
||||||
|
localStorage.setItem("trackingcodehistory", JSON.stringify(history));
|
||||||
|
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
router.navigate("/toolbox/track/info", {
|
router.navigate("/toolbox/track/info", {
|
||||||
@ -136,7 +150,7 @@ function scanTrackingBarcode() {
|
|||||||
}
|
}
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
app.dialog.alert(error, "Error");
|
app.dialog.alert(error, "Error");
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#trackbtn").click(function () {
|
$("#trackbtn").click(function () {
|
||||||
@ -147,4 +161,10 @@ $("#trackbtn").click(function () {
|
|||||||
} else {
|
} else {
|
||||||
app.dialog.alert("That's not a valid tracking code.", "Error");
|
app.dialog.alert("That's not a valid tracking code.", "Error");
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("input[name=trackingcode]").on('keypress', function (e) {
|
||||||
|
if (event.key === "Enter") {
|
||||||
|
$("#trackbtn").click();
|
||||||
|
}
|
||||||
});
|
});
|
@ -12,6 +12,7 @@
|
|||||||
<link rel="stylesheet" href="node_modules/leaflet.markercluster/dist/MarkerCluster.css" />
|
<link rel="stylesheet" href="node_modules/leaflet.markercluster/dist/MarkerCluster.css" />
|
||||||
<link rel="stylesheet" href="node_modules/leaflet.markercluster/dist/MarkerCluster.Default.css" />
|
<link rel="stylesheet" href="node_modules/leaflet.markercluster/dist/MarkerCluster.Default.css" />
|
||||||
<link rel="stylesheet" href="node_modules/leaflet.locatecontrol/dist/L.Control.Locate.min.css" />
|
<link rel="stylesheet" href="node_modules/leaflet.locatecontrol/dist/L.Control.Locate.min.css" />
|
||||||
|
<link rel="stylesheet" href="node_modules/mapbox-gl/dist/mapbox-gl.css">
|
||||||
<link rel="stylesheet" href="assets/css/app.css" />
|
<link rel="stylesheet" href="assets/css/app.css" />
|
||||||
<link rel="stylesheet" href="assets/css/backdrop.css" />
|
<link rel="stylesheet" href="assets/css/backdrop.css" />
|
||||||
<link rel="stylesheet" href="assets/css/oled.css" />
|
<link rel="stylesheet" href="assets/css/oled.css" />
|
||||||
@ -36,6 +37,7 @@
|
|||||||
<script src="node_modules/jquery/dist/jquery.min.js"></script>
|
<script src="node_modules/jquery/dist/jquery.min.js"></script>
|
||||||
<script src="node_modules/leaflet/dist/leaflet.js"></script>
|
<script src="node_modules/leaflet/dist/leaflet.js"></script>
|
||||||
<script src="node_modules/leaflet.markercluster/dist/leaflet.markercluster.js"></script>
|
<script src="node_modules/leaflet.markercluster/dist/leaflet.markercluster.js"></script>
|
||||||
|
<script src="node_modules/mapbox-gl/dist/mapbox-gl.js"></script>
|
||||||
<script src="node_modules/jsbarcode/dist/JsBarcode.all.min.js"></script>
|
<script src="node_modules/jsbarcode/dist/JsBarcode.all.min.js"></script>
|
||||||
<script src="node_modules/leaflet.locatecontrol/dist/L.Control.Locate.min.js"></script>
|
<script src="node_modules/leaflet.locatecontrol/dist/L.Control.Locate.min.js"></script>
|
||||||
|
|
||||||
@ -50,6 +52,7 @@
|
|||||||
<script src="assets/js/location.js"></script>
|
<script src="assets/js/location.js"></script>
|
||||||
<script src="assets/js/list.js"></script>
|
<script src="assets/js/list.js"></script>
|
||||||
<script src="assets/js/map_leaflet.js"></script>
|
<script src="assets/js/map_leaflet.js"></script>
|
||||||
|
<script src="assets/js/map_mapbox.js"></script>
|
||||||
<script src="assets/js/map.js"></script>
|
<script src="assets/js/map.js"></script>
|
||||||
<script src="assets/js/manage.js"></script>
|
<script src="assets/js/manage.js"></script>
|
||||||
|
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "PackageHelper",
|
"name": "PackageHelper",
|
||||||
"version": "1.2.0",
|
"version": "1.3.0",
|
||||||
"main": "index.html",
|
"main": "index.html",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^5.10.2",
|
"@fortawesome/fontawesome-free": "^5.10.2",
|
||||||
"@zxing/library": "^0.15.2",
|
"@zxing/library": "^0.15.2",
|
||||||
"framework7": "^5.0.2",
|
"framework7": "^5.1.3",
|
||||||
"jquery": "^3.4.1",
|
"jquery": "^3.4.1",
|
||||||
"jsbarcode": "^3.11.0",
|
"jsbarcode": "^3.11.0",
|
||||||
"leaflet": "^1.5.1",
|
"leaflet": "^1.5.1",
|
||||||
"leaflet-geometryutil": "^0.9.1",
|
"leaflet-geometryutil": "^0.9.1",
|
||||||
"leaflet.locatecontrol": "^0.67.0",
|
"leaflet.locatecontrol": "^0.67.0",
|
||||||
"leaflet.markercluster": "^1.4.1",
|
"leaflet.markercluster": "^1.4.1",
|
||||||
|
"mapbox-gl": "^1.6.1",
|
||||||
"material-design-icons": "^3.0.1"
|
"material-design-icons": "^3.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {}
|
"devDependencies": {}
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
|
||||||
|
|
||||||
<div class="page" data-name="alertsettings">
|
|
||||||
|
|
||||||
<div class="navbar">
|
|
||||||
<div class="navbar-bg"></div>
|
|
||||||
<div class="navbar-inner">
|
|
||||||
<div class="left">
|
|
||||||
<a href="#" class="link icon-only back">
|
|
||||||
<i class="icon icon-back"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="title">Alert Settings</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="page-content">
|
|
||||||
<div class="list media-list no-hairlines tablet-inset" style="margin-top: 0;">
|
|
||||||
<ul>
|
|
||||||
{{#each settings}}
|
|
||||||
<li>
|
|
||||||
{{#if toggle}}
|
|
||||||
<div class="item-content" data-setting="{{setting}}">
|
|
||||||
<div class="item-inner">
|
|
||||||
<div style="display: flex; justify-content: between;">
|
|
||||||
<div class="item-title">
|
|
||||||
{{title}}
|
|
||||||
</div>
|
|
||||||
<div class="item-after" onclick="{{onclick}}">
|
|
||||||
<label class="toggle toggle-init">
|
|
||||||
<input type="checkbox" {{#if checked}}checked{{/if}}>
|
|
||||||
<span class="toggle-icon"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="item-text">{{text}}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{else}}
|
|
||||||
{{#if slider}}
|
|
||||||
<div class="item-content" data-setting="{{setting}}">
|
|
||||||
<div class="item-inner">
|
|
||||||
<div class="item-title" style="background-color: rgba(0,0,0,0);">
|
|
||||||
{{title}}
|
|
||||||
</div>
|
|
||||||
<div class="item-subtitle padding-horizontal padding-top">
|
|
||||||
<div class="range-slider range-slider-init padding-top margin-top" data-label="true">
|
|
||||||
<input type="range" min="{{min}}" max="{{max}}" step="{{step}}" value="{{value}}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{else}}
|
|
||||||
{{#if select}}
|
|
||||||
<a class="item-link smart-select smart-select-init" data-open-in="popover" data-setting="{{setting}}">
|
|
||||||
<select>
|
|
||||||
{{#each options}}
|
|
||||||
<option value="{{value}}"{{#if selected}} selected{{/if}}>{{label}}</option>
|
|
||||||
{{/each}}
|
|
||||||
</select>
|
|
||||||
<div class="item-content">
|
|
||||||
<div class="item-inner">
|
|
||||||
<div class="item-title">{{title}}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
{{else}}
|
|
||||||
<div class="item-content" data-setting="{{setting}}" onclick="{{onclick}}">
|
|
||||||
<div class="item-inner">
|
|
||||||
<div class="item-title-row">
|
|
||||||
<div class="item-title">{{title}}</div>
|
|
||||||
</div>
|
|
||||||
<div class="item-text">{{text}}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
</li>
|
|
||||||
{{/each}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="assets/js/settings.js"></script>
|
|
||||||
|
|
||||||
</div>
|
|
File diff suppressed because it is too large
Load Diff
58
www/pages/help/list.html
Normal file
58
www/pages/help/list.html
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
|
<div class="panel panel-right panel-cover">
|
||||||
|
<div class="view">
|
||||||
|
<div class="page">
|
||||||
|
|
||||||
|
<div class="navbar">
|
||||||
|
<div class="navbar-bg"></div>
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<div class="title">Help</div>
|
||||||
|
<div class="right">
|
||||||
|
<a class="link panel-close">
|
||||||
|
<span>Close</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="block-title">Manage Items</div>
|
||||||
|
<div class="block">
|
||||||
|
Swipe <i class="fas fa-arrow-right"></i> left-to-right on a list entry
|
||||||
|
to show the actions you can take.
|
||||||
|
These actions are marking the item as delivered/undelivered, or
|
||||||
|
navigating to its location with your device's default maps app.
|
||||||
|
<br />
|
||||||
|
Swipe <i class="fas fa-arrow-left"></i> right-to-left on a list entry
|
||||||
|
and tap
|
||||||
|
<span class="button button-small display-inline button-fill color-red text-color-white"><i class="material-icons">delete</i> Delete</span> to remove it.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block-title">Clear the List</div>
|
||||||
|
<div class="block">
|
||||||
|
Tap the <span class="color-red text-color-primary"><i class="material-icons">delete</i></span>
|
||||||
|
button to remove all items from the list. This cannot be undone, so it's
|
||||||
|
a good idea to do it at the end of the day or in the morning before you start.
|
||||||
|
Note that clearing the list does not affect the address autofill.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block-title">Search</div>
|
||||||
|
<div class="block">
|
||||||
|
Tap the <i class="material-icons text-color-primary">search</i> button to open a search
|
||||||
|
box. Type in this box to hide any list entries that don't contain your
|
||||||
|
search query.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block-title">Sort Items</div>
|
||||||
|
<div class="block">
|
||||||
|
Tap the <i class="material-icons text-color-primary">sort</i> button to sort
|
||||||
|
the list. You can sort by distance from your current
|
||||||
|
location, alphabetically by street name, and numerically by
|
||||||
|
address number.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
77
www/pages/help/map.html
Normal file
77
www/pages/help/map.html
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
|
<div class="panel panel-right panel-cover">
|
||||||
|
<div class="view">
|
||||||
|
<div class="page">
|
||||||
|
|
||||||
|
<div class="navbar">
|
||||||
|
<div class="navbar-bg"></div>
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<div class="title">Help</div>
|
||||||
|
<div class="right">
|
||||||
|
<a class="link panel-close">
|
||||||
|
<span>Close</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="block-title">Manage Items</div>
|
||||||
|
<div class="block">
|
||||||
|
Tap on an icon to see the item(s) at that location.
|
||||||
|
Tap on an item to toggle it between delivered and
|
||||||
|
undelivered. If two or more addresses are very close
|
||||||
|
together, their items will be grouped under one icon.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block-title">Move the Map</div>
|
||||||
|
<div class="block">
|
||||||
|
Pinch with two fingers or scroll with a mouse to zoom
|
||||||
|
in and out. You can also double-tap to zoom in.
|
||||||
|
Drag with one finger or a mouse to move (pan) the map.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
If you prefer, tap or click
|
||||||
|
<span class="button button-small display-inline button-fill color-white text-color-black"><i class="fas fa-plus"></i></span>
|
||||||
|
and
|
||||||
|
<span class="button button-small display-inline button-fill color-white text-color-black"><i class="fas fa-minus"></i></span>
|
||||||
|
to zoom in and out.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
Drag on
|
||||||
|
<span class="button button-small display-inline button-fill color-white text-color-black"><i class="fas fa-sort"></i></span>
|
||||||
|
to rotate and tilt the map. Dragging left and right rotates, up and down tilts.
|
||||||
|
You can also rotate with two fingers by twisting them around each other,
|
||||||
|
or with a keyboard by holding Ctrl and dragging the mouse.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block-title">Follow Location</div>
|
||||||
|
<div class="block">
|
||||||
|
Tap
|
||||||
|
<span class="button button-small display-inline button-fill color-white text-color-black"><i class='material-icons'>my_location</i></span>
|
||||||
|
or
|
||||||
|
<span class="button button-small display-inline button-fill color-white text-color-black"><i class='far fa-compass'></i></span>
|
||||||
|
to show your current
|
||||||
|
location on the map as a blue dot. The map will follow
|
||||||
|
the dot until you zoom or move the map. If the dot goes
|
||||||
|
off the edge of the map, press the button again to
|
||||||
|
re-center the map. Pressing the button when the dot is
|
||||||
|
visible will hide the dot and stop the map from
|
||||||
|
following your location.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block-title">Get Directions</div>
|
||||||
|
<div class="block">
|
||||||
|
<span class="text-color-primary"><i class="material-icons">directions</i></span> will open your
|
||||||
|
default map/navigation app with the item location set as
|
||||||
|
the destination. This is useful if you're having
|
||||||
|
trouble finding the location.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -24,6 +24,12 @@
|
|||||||
<a class="link text-color-red" onclick="confirmDeleteAllPackages()">
|
<a class="link text-color-red" onclick="confirmDeleteAllPackages()">
|
||||||
<i class="icon material-icons">delete</i>
|
<i class="icon material-icons">delete</i>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
{{#if show_help}}
|
||||||
|
<a class="link" href="/help/list">
|
||||||
|
<i class="icon material-icons">help</i>
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<form class="searchbar searchbar-expandable package-list-searchbar">
|
<form class="searchbar searchbar-expandable package-list-searchbar">
|
||||||
<div class="searchbar-inner">
|
<div class="searchbar-inner">
|
||||||
|
@ -15,9 +15,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="title">Map</div>
|
<div class="title">Map</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<a class="link" onclick="reloadMap()">
|
{{#if show_help}}
|
||||||
<i class="material-icons">refresh</i>
|
<a class="link" href="/help/map">
|
||||||
|
<i class="icon material-icons">help</i>
|
||||||
</a>
|
</a>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,13 +12,13 @@
|
|||||||
<i class="icon icon-back"></i>
|
<i class="icon icon-back"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="title">Settings</div>
|
<div class="title">{{page_title}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="page-content">
|
<div class="page-content">
|
||||||
<div class="list media-list no-hairlines tablet-inset" style="margin-top: 0;">
|
<div class="list media-list no-hairlines no-margin-top tablet-inset">
|
||||||
<ul>
|
<ul>
|
||||||
{{#each settings}}
|
{{#each settings}}
|
||||||
<li>
|
<li>
|
||||||
|
@ -19,6 +19,14 @@
|
|||||||
<div class="page-content">
|
<div class="page-content">
|
||||||
<div class="list no-hairlines tablet-inset" style="margin-top: 0;">
|
<div class="list no-hairlines tablet-inset" style="margin-top: 0;">
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/toolbox/scanner" class="item-link item-content">
|
||||||
|
<div class="item-media"><i class="icon fas fa-barcode"></i></div>
|
||||||
|
<div class="item-inner">
|
||||||
|
<div class="item-title">Broken Scanner</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="/toolbox/track" class="item-link item-content">
|
<a href="/toolbox/track" class="item-link item-content">
|
||||||
<div class="item-media"><i class="icon fas fa-search-location"></i></div>
|
<div class="item-media"><i class="icon fas fa-search-location"></i></div>
|
||||||
@ -35,14 +43,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<!--<li>
|
<li>
|
||||||
<a href="/toolbox/scanner" class="item-link item-content">
|
<a href="/toolbox/sharelist" class="item-link item-content">
|
||||||
<div class="item-media"><i class="icon fas fa-barcode"></i></div>
|
<div class="item-media"><i class="icon fas fa-share-alt"></i></div>
|
||||||
<div class="item-inner">
|
<div class="item-inner">
|
||||||
<div class="item-title">Scan for Delivery</div>
|
<div class="item-title">Share Item List</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</li>-->
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
50
www/pages/toolbox/scanner.html
Normal file
50
www/pages/toolbox/scanner.html
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
|
|
||||||
|
<div class="page">
|
||||||
|
|
||||||
|
<div class="navbar">
|
||||||
|
<div class="navbar-bg"></div>
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<div class="left">
|
||||||
|
<a href="#" class="link icon-only back">
|
||||||
|
<i class="icon icon-back"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="title">Broken Scanner</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="list no-hairlines tablet-inset" style="margin-top: 0;">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/toolbox/scanner/scanner" class="item-link item-content">
|
||||||
|
<div class="item-media">1</div>
|
||||||
|
<div class="item-inner">
|
||||||
|
<div class="item-title">Scan Barcode</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="/toolbox/scanner/entries" class="item-link item-content">
|
||||||
|
<div class="item-media">2</div>
|
||||||
|
<div class="item-inner">
|
||||||
|
<div class="item-title">Review Entries</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block text-align-center">
|
||||||
|
<i class="material-icons material-icons-24px">info</i>
|
||||||
|
<br />
|
||||||
|
Scan barcodes while your postal scanner is crashed or restarting.
|
||||||
|
When the scanner is working again, you can scan all the saved
|
||||||
|
barcodes from your phone screen using the scanner's Manual Input or
|
||||||
|
Scan Barcode feature.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
60
www/pages/toolbox/scanner/entries.html
Normal file
60
www/pages/toolbox/scanner/entries.html
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
|
|
||||||
|
<div class="page" data-name="scanner">
|
||||||
|
|
||||||
|
<div class="navbar">
|
||||||
|
<div class="navbar-bg"></div>
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<div class="left">
|
||||||
|
<a href="#" class="link icon-only back">
|
||||||
|
<i class="icon icon-back"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="title">Review Entries</div>
|
||||||
|
<div class="right">
|
||||||
|
<a class="link text-color-red" onclick="confirmDeleteScanEntries()">
|
||||||
|
<i class="icon material-icons">delete</i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
{{#if entries}}
|
||||||
|
<div class="list media-list no-margin-top no-hairlines">
|
||||||
|
<ul>
|
||||||
|
{{#each entries}}
|
||||||
|
<li style="padding-top: 2rem; padding-bottom: 2rem;">
|
||||||
|
<div class="item-content">
|
||||||
|
<div class="item-inner">
|
||||||
|
<div style="background-color: white; display: flex; justify-content: center; padding-left: 1rem; padding-right: 1rem;">
|
||||||
|
<svg class="barcode_entry" id="barcode_{{code}}" data-barcode="{{code}}"></svg>
|
||||||
|
</div>
|
||||||
|
<div class="item-text text-align-center">{{event}}</div>
|
||||||
|
<div class="item-text text-align-center">{{date}}</div>
|
||||||
|
{{#if form3849}}
|
||||||
|
<h2 class="item-text text-align-center">Form 3849:</h2>
|
||||||
|
<div style="background-color: white; display: flex; justify-content: center; padding-left: 1rem; padding-right: 1rem;">
|
||||||
|
<svg class="barcode_entry" id="barcode_{{form3849}}" data-barcode="{{form3849}}"></svg>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="block text-align-center">
|
||||||
|
<img style="width: 60%; max-width: 300px; max-height: 40vh;" src="assets/images/barcode-dashed.svg" class="margin-vertical" />
|
||||||
|
<h2 class="margin-top">
|
||||||
|
No scan entries.
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="assets/js/toolbox_scannerentries.js"></script>
|
||||||
|
</div>
|
107
www/pages/toolbox/scanner/scanner.html
Normal file
107
www/pages/toolbox/scanner/scanner.html
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
|
|
||||||
|
<div class="page" data-name="scanner">
|
||||||
|
|
||||||
|
<div class="navbar">
|
||||||
|
<div class="navbar-bg"></div>
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<div class="left">
|
||||||
|
<a href="#" class="link icon-only back">
|
||||||
|
<i class="icon icon-back"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="title">Scan Barcode</div>
|
||||||
|
<div class="subnavbar" style="background-color: var(--f7-searchbar-bg-color,var(--f7-bars-bg-color));">
|
||||||
|
<div class="subnavbar-inner">
|
||||||
|
<div class="searchbar">
|
||||||
|
<div class="searchbar-inner">
|
||||||
|
<div class="searchbar-input-wrap">
|
||||||
|
<input type="text" id="brokenscannerinput" placeholder="Enter Code" autocomplete="off" autocorrect="off" autocapitalize="off" style="padding-left: 1em; padding-right: 1em;" />
|
||||||
|
</div>
|
||||||
|
<a id="brokenscannercodeadd" onclick="brokenScannerAddTextEntry()" style="padding-right: 0.5em; padding-top: 0.3em;">
|
||||||
|
<i class="material-icons">keyboard_return</i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fab fab-extended fab-left-bottom">
|
||||||
|
<a href="#" onclick="brokenScannerEsc()">
|
||||||
|
<div class="fab-text">ESC</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fab fab-extended fab-center-bottom">
|
||||||
|
<a href="#" onclick="brokenScannerScan()">
|
||||||
|
<div class="fab-text">Scan</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fab fab-extended fab-right-bottom">
|
||||||
|
<a href="#" onclick="chooseScanEvent()">
|
||||||
|
<div class="fab-text">Enter</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="popup" id="scanEventPopup" style="background-color: var(--f7-page-bg-color);">
|
||||||
|
<div class="navbar">
|
||||||
|
<div class="navbar-bg"></div>
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<div class="title">Select Event</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block no-margin-top padding-bottom" style="height: calc(100% - var(--f7-navbar-height)); overflow-y: auto;">
|
||||||
|
<div class="list tablet-inset no-hairlines no-margin-top">
|
||||||
|
<ul class="eventlist">
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fab fab-extended fab-left-bottom">
|
||||||
|
<a href="#" onclick="app.popup.close('#scanEventPopup');">
|
||||||
|
<div class="fab-text">ESC</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="popup" id="scanEventTypePopup" style="background-color: var(--f7-page-bg-color);">
|
||||||
|
<div class="navbar">
|
||||||
|
<div class="navbar-bg"></div>
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<div class="title">Event Type</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block no-margin-top padding-bottom" style="height: calc(100% - var(--f7-navbar-height)); overflow-y: auto;">
|
||||||
|
<div class="list tablet-inset no-hairlines no-margin-top">
|
||||||
|
<ul class="eventlist">
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fab fab-extended fab-left-bottom">
|
||||||
|
<a href="#" onclick="app.popup.close('#scanEventTypePopup');">
|
||||||
|
<div class="fab-text">ESC</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="list no-hairlines tablet-inset">
|
||||||
|
<ul id="codelist">
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div style="height: 3rem;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="assets/js/toolbox_scanner.js"></script>
|
||||||
|
|
||||||
|
</div>
|
68
www/pages/toolbox/sharelist.html
Normal file
68
www/pages/toolbox/sharelist.html
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
|
|
||||||
|
<div class="page" data-name="sharelist">
|
||||||
|
|
||||||
|
<div class="navbar">
|
||||||
|
<div class="navbar-bg"></div>
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<div class="left">
|
||||||
|
<a href="#" class="link icon-only back">
|
||||||
|
<i class="icon icon-back"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="title">Share Item List</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="list media-list no-hairlines tablet-inset no-margin-top">
|
||||||
|
<ul>
|
||||||
|
<li class="item-divider">Send List</li>
|
||||||
|
<li>
|
||||||
|
<div class="item-content">
|
||||||
|
<a class="button button-fill" id="sendlistbtn" onclick="uploadList();"><i class="fas fa-upload"></i> Upload List</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li style="display: none;" id="listidbarcodeli">
|
||||||
|
<div class="item-content" style="background-color: white; display: flex; justify-content: center; padding-left: 1rem; padding-right: 1rem;">
|
||||||
|
<svg class="barcode" id="listidbarcode"></svg>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li class="item-divider">Receive List</li>
|
||||||
|
<li>
|
||||||
|
<div class="item-content">
|
||||||
|
<div class="item-inner">
|
||||||
|
<div class="item-title item-label">List ID</div>
|
||||||
|
<div class="item-input-wrap">
|
||||||
|
<input type="text" id="getlistidbox" placeholder="" autocomplete="off" autocorrect="off" autocapitalize="off" />
|
||||||
|
<span class="input-clear-button"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="item-content">
|
||||||
|
<a class="button button-fill" onclick="downloadItemList();"><i class="fas fa-download"></i> Download List</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="item-content">
|
||||||
|
<a class="button button-fill" id="scanlistbarcodebtn" onclick="scanListIDBarcode();"><i class="fas fa-barcode"></i> Scan List Barcode</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block text-align-center">
|
||||||
|
<i class="material-icons material-icons-24px">info</i>
|
||||||
|
<br />
|
||||||
|
Share your delivery list to another device. The sender uploads the list,
|
||||||
|
and the receiver(s) either scan the barcode on the sender's device, or
|
||||||
|
type in the code beneath the barcode.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="assets/js/toolbox_sharelist.js"></script>
|
||||||
|
</div>
|
@ -40,9 +40,32 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="block">
|
<div class="block text-align-center">
|
||||||
|
<i class="material-icons material-icons-24px">info</i>
|
||||||
|
<br />
|
||||||
Compatible with USPS, UPS, FedEx, and DHL tracking codes.
|
Compatible with USPS, UPS, FedEx, and DHL tracking codes.
|
||||||
|
Can extract full delivery point address (and sometimes customer phone number)
|
||||||
|
from 2D FedEx and UPS Mail Innovations barcodes.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{#if trackingcodehistory}}
|
||||||
|
<div class="list no-hairlines tablet-inset">
|
||||||
|
<ul>
|
||||||
|
<li class="item-divider">
|
||||||
|
History
|
||||||
|
</li>
|
||||||
|
{{#each trackingcodehistory}}
|
||||||
|
<li>
|
||||||
|
<div class="item-link item-content" onclick="openTrackingHistory('{{this}}')">
|
||||||
|
<div class="item-inner">
|
||||||
|
<div class="item-title">{{this}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="assets/js/toolbox_track.js"></script>
|
<script src="assets/js/toolbox_track.js"></script>
|
||||||
|
@ -52,12 +52,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div class="item-content" style="background-color: white; display: flex; justify-content: center; padding-left: 1rem; padding-right: 1rem;">
|
<div class="item-content" style="background-color: white; display: flex; justify-content: center; padding-left: 1rem; padding-right: 1rem;">
|
||||||
<svg class="barcode"
|
<svg class="barcode" id="trackingbarcode"></svg>
|
||||||
jsbarcode-format="code128"
|
|
||||||
jsbarcode-value="{{#if barcode}}{{barcode}}{{else}}{{code}}{{/if}}"
|
|
||||||
jsbarcode-height="40"
|
|
||||||
jsbarcode-width="2">
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="item-divider">History</li>
|
<li class="item-divider">History</li>
|
||||||
@ -84,6 +79,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
JsBarcode(".barcode").init();
|
JsBarcode("#trackingbarcode", "{{#if barcode}}{{escape barcode}}{{else}}{{escape code}}{{/if}}", {
|
||||||
|
format: "code128",
|
||||||
|
ean128: true,
|
||||||
|
width: 2,
|
||||||
|
height: 40
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
402
www/routes.js
402
www/routes.js
@ -4,6 +4,10 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var show_help = function () {
|
||||||
|
return localStorage.getItem("show_help") != "false";
|
||||||
|
}
|
||||||
|
|
||||||
var routes = [
|
var routes = [
|
||||||
{
|
{
|
||||||
path: '/home',
|
path: '/home',
|
||||||
@ -27,13 +31,14 @@ var routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/manage',
|
path: '/manage',
|
||||||
|
name: 'manage',
|
||||||
templateUrl: './pages/manage.html',
|
templateUrl: './pages/manage.html',
|
||||||
options: {
|
options: {
|
||||||
context: {
|
context: {
|
||||||
|
show_help: show_help,
|
||||||
itemtypes: SETTINGS.itemtypes
|
itemtypes: SETTINGS.itemtypes
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
name: 'manage',
|
|
||||||
on: {
|
on: {
|
||||||
pageAfterIn: function () {
|
pageAfterIn: function () {
|
||||||
app.autocomplete.create({
|
app.autocomplete.create({
|
||||||
@ -56,8 +61,13 @@ var routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/list',
|
path: '/list',
|
||||||
templateUrl: './pages/list.html',
|
|
||||||
name: 'list',
|
name: 'list',
|
||||||
|
templateUrl: './pages/list.html',
|
||||||
|
options: {
|
||||||
|
context: {
|
||||||
|
show_help: show_help
|
||||||
|
}
|
||||||
|
},
|
||||||
on: {
|
on: {
|
||||||
pageAfterIn: function () {
|
pageAfterIn: function () {
|
||||||
loadPackageList();
|
loadPackageList();
|
||||||
@ -74,14 +84,17 @@ var routes = [
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
keepAlive: true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/map',
|
path: '/map',
|
||||||
url: './pages/map.html',
|
templateUrl: './pages/map.html',
|
||||||
name: 'map',
|
name: 'map',
|
||||||
keepAlive: true,
|
options: {
|
||||||
|
context: {
|
||||||
|
show_help: show_help
|
||||||
|
}
|
||||||
|
},
|
||||||
on: {
|
on: {
|
||||||
pageAfterIn: function () {
|
pageAfterIn: function () {
|
||||||
reloadMap();
|
reloadMap();
|
||||||
@ -91,27 +104,114 @@ var routes = [
|
|||||||
{
|
{
|
||||||
path: '/toolbox',
|
path: '/toolbox',
|
||||||
url: './pages/toolbox.html',
|
url: './pages/toolbox.html',
|
||||||
name: 'toolbox'
|
name: 'toolbox',
|
||||||
},
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/toolbox/track',
|
path: '/scanner',
|
||||||
url: './pages/toolbox/track.html',
|
templateUrl: './pages/toolbox/scanner.html',
|
||||||
name: 'track'
|
routes: [
|
||||||
},
|
{
|
||||||
{
|
path: '/scanner',
|
||||||
path: '/toolbox/weather',
|
templateUrl: './pages/toolbox/scanner/scanner.html',
|
||||||
url: './pages/toolbox/weather.html',
|
name: 'scanner'
|
||||||
name: 'weather',
|
},
|
||||||
on: {
|
{
|
||||||
pageAfterIn: function () {
|
path: '/entries',
|
||||||
loadWeather();
|
name: 'entries',
|
||||||
|
async: function (routeTo, routeFrom, resolve, reject) {
|
||||||
|
if (localStorage.getItem("scanevents") != null && localStorage.getItem("scanevents") != "[]") {
|
||||||
|
var entries = JSON.parse(localStorage.getItem("scanevents"));
|
||||||
|
|
||||||
|
for (i in entries) {
|
||||||
|
entries[i].event = entries[i].event.join(' <i class="fas fa-chevron-right"></i> ');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var entries = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve({
|
||||||
|
templateUrl: './pages/toolbox/scanner/entries.html'
|
||||||
|
}, {
|
||||||
|
context: {
|
||||||
|
entries: entries
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
pageAfterIn: function () {
|
||||||
|
$(".barcode_entry").each(function () {
|
||||||
|
var code = $(this).data("barcode");
|
||||||
|
JsBarcode("#barcode_" + code, code, {
|
||||||
|
format: "code128",
|
||||||
|
ean128: true,
|
||||||
|
width: 2,
|
||||||
|
height: 40
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/track',
|
||||||
|
name: 'track',
|
||||||
|
async: function (routeTo, routeFrom, resolve, reject) {
|
||||||
|
var history = localStorage.getItem("trackingcodehistory");
|
||||||
|
if (history == null) {
|
||||||
|
history = false;
|
||||||
|
} else {
|
||||||
|
history = JSON.parse(history).reverse(); // Most recent on top
|
||||||
|
}
|
||||||
|
resolve({
|
||||||
|
templateUrl: './pages/toolbox/track.html'
|
||||||
|
}, {
|
||||||
|
context: {
|
||||||
|
trackingcodehistory: history
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: '/info',
|
||||||
|
templateUrl: './pages/toolbox/trackinginfo.html',
|
||||||
|
name: 'trackinginfo'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/weather',
|
||||||
|
url: './pages/toolbox/weather.html',
|
||||||
|
name: 'weather',
|
||||||
|
on: {
|
||||||
|
pageAfterIn: function () {
|
||||||
|
loadWeather();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/sharelist',
|
||||||
|
url: './pages/toolbox/sharelist.html',
|
||||||
|
name: 'sharelist'
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/toolbox/track/info',
|
path: '/help',
|
||||||
templateUrl: './pages/toolbox/trackinginfo.html',
|
routes: [
|
||||||
name: 'trackinginfo'
|
{
|
||||||
|
path: '/list',
|
||||||
|
panel: {
|
||||||
|
url: './pages/help/list.html'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/map',
|
||||||
|
panel: {
|
||||||
|
url: './pages/help/map.html'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/credits',
|
path: '/credits',
|
||||||
@ -122,17 +222,6 @@ var routes = [
|
|||||||
path: '/settings',
|
path: '/settings',
|
||||||
name: 'settings',
|
name: 'settings',
|
||||||
async: function (routeTo, routeFrom, resolve, reject) {
|
async: function (routeTo, routeFrom, resolve, reject) {
|
||||||
var mapstyles = [];
|
|
||||||
for (var id in SETTINGS.maptileurls) {
|
|
||||||
if (SETTINGS.maptileurls.hasOwnProperty(id)) {
|
|
||||||
mapstyles.push({
|
|
||||||
value: id,
|
|
||||||
label: SETTINGS.maptileurls[id].name,
|
|
||||||
selected: localStorage.getItem("mapsource") == id
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var settings = [
|
var settings = [
|
||||||
{
|
{
|
||||||
setting: "alerts",
|
setting: "alerts",
|
||||||
@ -140,6 +229,13 @@ var routes = [
|
|||||||
text: "Change the alert sound, volume, and distance.",
|
text: "Change the alert sound, volume, and distance.",
|
||||||
onclick: "router.navigate('/settings/alerts')",
|
onclick: "router.navigate('/settings/alerts')",
|
||||||
link: true
|
link: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
setting: "maps",
|
||||||
|
title: "Map and Navigation",
|
||||||
|
text: "Change map settings and units.",
|
||||||
|
onclick: "router.navigate('/settings/maps')",
|
||||||
|
link: true
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -164,33 +260,17 @@ var routes = [
|
|||||||
onclick: ""
|
onclick: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
setting: "units",
|
setting: "showhelp",
|
||||||
title: "Measurement units",
|
title: "Show help",
|
||||||
select: true,
|
text: "Show the <span class=material-icons-intext><i class=material-icons>help</i></span> icons",
|
||||||
options: [
|
toggle: true,
|
||||||
{
|
checked: localStorage.getItem("show_help") != "false",
|
||||||
value: "metric",
|
onclick: ""
|
||||||
label: "Meters/Kilometers",
|
|
||||||
selected: localStorage.getItem("units") == "metric"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "imperial",
|
|
||||||
label: "Feet/Miles",
|
|
||||||
selected: localStorage.getItem("units") == "imperial"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
setting: "mapsource",
|
|
||||||
title: "Map style",
|
|
||||||
select: true,
|
|
||||||
options: mapstyles,
|
|
||||||
text: "Choose which map style to use."
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
setting: "versions",
|
setting: "versions",
|
||||||
title: "PackageHelper app v" + app_version,
|
title: "PackageHelper app v" + app_version,
|
||||||
text: "Copyright © 2019 Netsyms Technologies. Licensed under the Mozilla Public License 2.0.",
|
text: "Copyright © 2019-2020 Netsyms Technologies. Licensed under the Mozilla Public License 2.0.",
|
||||||
onclick: ""
|
onclick: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -204,7 +284,7 @@ var routes = [
|
|||||||
setting: "privacy",
|
setting: "privacy",
|
||||||
title: "Privacy policy and legal",
|
title: "Privacy policy and legal",
|
||||||
text: "",
|
text: "",
|
||||||
onclick: "openBrowser('https://netsyms.com/legal?pk_campaign=PackageHelpterApp')",
|
onclick: "openBrowser('https://netsyms.com/legal?pk_campaign=PackageHelperApp')",
|
||||||
link: true
|
link: true
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -212,68 +292,156 @@ var routes = [
|
|||||||
templateUrl: './pages/settings.html'
|
templateUrl: './pages/settings.html'
|
||||||
}, {
|
}, {
|
||||||
context: {
|
context: {
|
||||||
|
page_title: "Settings",
|
||||||
settings: settings
|
settings: settings
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
},
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/settings/alerts',
|
path: '/alerts',
|
||||||
name: 'alertsettings',
|
name: 'settings',
|
||||||
async: function (routeTo, routeFrom, resolve, reject) {
|
async: function (routeTo, routeFrom, resolve, reject) {
|
||||||
var alertsounds = [];
|
var alertsounds = [];
|
||||||
for (var id in SETTINGS.alertsounds) {
|
for (var id in SETTINGS.alertsounds) {
|
||||||
if (SETTINGS.alertsounds.hasOwnProperty(id)) {
|
if (SETTINGS.alertsounds.hasOwnProperty(id)) {
|
||||||
alertsounds.push({
|
alertsounds.push({
|
||||||
value: id,
|
value: id,
|
||||||
label: SETTINGS.alertsounds[id].name,
|
label: SETTINGS.alertsounds[id].name,
|
||||||
selected: localStorage.getItem("alertsound") == id
|
selected: localStorage.getItem("alertsound") == id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var settings = [
|
||||||
|
{
|
||||||
|
setting: "alertsound",
|
||||||
|
title: "Alert sound",
|
||||||
|
text: "Select which sound to play when a package is nearby.",
|
||||||
|
select: true,
|
||||||
|
options: alertsounds
|
||||||
|
},
|
||||||
|
{
|
||||||
|
setting: "alertvolume",
|
||||||
|
title: "Alert volume",
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
value: localStorage.getItem("alertvolume"),
|
||||||
|
slider: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
setting: "alertradius",
|
||||||
|
title: "Alert radius (meters)",
|
||||||
|
min: 50,
|
||||||
|
max: 500,
|
||||||
|
step: 50,
|
||||||
|
value: localStorage.getItem("alertradius"),
|
||||||
|
slider: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
setting: "alertinterval",
|
||||||
|
title: "Alert interval (seconds)",
|
||||||
|
min: 15,
|
||||||
|
max: 120,
|
||||||
|
step: 15,
|
||||||
|
value: localStorage.getItem("alertinterval") == null ? 30 : localStorage.getItem("alertinterval"),
|
||||||
|
slider: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
resolve({
|
||||||
|
templateUrl: './pages/settings.html'
|
||||||
|
}, {
|
||||||
|
context: {
|
||||||
|
page_title: "Alert Settings",
|
||||||
|
settings: settings
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/maps',
|
||||||
|
name: 'settings',
|
||||||
|
async: function (routeTo, routeFrom, resolve, reject) {
|
||||||
|
var mapstyles = [];
|
||||||
|
for (var id in SETTINGS.maptileurls) {
|
||||||
|
if (SETTINGS.maptileurls.hasOwnProperty(id)) {
|
||||||
|
mapstyles.push({
|
||||||
|
value: id,
|
||||||
|
label: SETTINGS.maptileurls[id].name,
|
||||||
|
selected: localStorage.getItem("mapsource") == id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var settings = [
|
||||||
|
{
|
||||||
|
setting: "mapsource",
|
||||||
|
title: "Map style",
|
||||||
|
select: true,
|
||||||
|
options: mapstyles,
|
||||||
|
text: "Choose which map style to use."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
setting: "units",
|
||||||
|
title: "Measurement units",
|
||||||
|
select: true,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: "metric",
|
||||||
|
label: "Meters/Kilometers",
|
||||||
|
selected: localStorage.getItem("units") == "metric"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "imperial",
|
||||||
|
label: "Feet/Miles",
|
||||||
|
selected: localStorage.getItem("units") == "imperial"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
setting: "trackzoom",
|
||||||
|
title: "Zoom when tracking location",
|
||||||
|
select: true,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: 15,
|
||||||
|
label: "Low",
|
||||||
|
selected: localStorage.getItem("trackzoom") == 15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 16,
|
||||||
|
label: "Normal",
|
||||||
|
selected: localStorage.getItem("trackzoom") == null || localStorage.getItem("trackzoom") == 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 17,
|
||||||
|
label: "High",
|
||||||
|
selected: localStorage.getItem("trackzoom") == 17
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
setting: "maptype",
|
||||||
|
title: "Alternative map",
|
||||||
|
text: "Turn this on if you have problems with the map.",
|
||||||
|
toggle: true,
|
||||||
|
checked: localStorage.getItem("maptype") == "leaflet",
|
||||||
|
onclick: ""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
resolve({
|
||||||
|
templateUrl: './pages/settings.html'
|
||||||
|
}, {
|
||||||
|
context: {
|
||||||
|
page_title: "Map Settings",
|
||||||
|
settings: settings
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
]
|
||||||
var settings = [{
|
}
|
||||||
setting: "alertsound",
|
|
||||||
title: "Alert sound",
|
|
||||||
text: "Select which sound to play when a package is nearby.",
|
|
||||||
select: true,
|
|
||||||
options: alertsounds
|
|
||||||
},
|
|
||||||
{
|
|
||||||
setting: "alertvolume",
|
|
||||||
title: "Alert volume",
|
|
||||||
min: 0,
|
|
||||||
max: 100,
|
|
||||||
step: 1,
|
|
||||||
value: localStorage.getItem("alertvolume"),
|
|
||||||
slider: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
setting: "alertradius",
|
|
||||||
title: "Alert radius (meters)",
|
|
||||||
min: 50,
|
|
||||||
max: 500,
|
|
||||||
step: 50,
|
|
||||||
value: localStorage.getItem("alertradius"),
|
|
||||||
slider: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
setting: "alertinterval",
|
|
||||||
title: "Alert interval (seconds)",
|
|
||||||
min: 15,
|
|
||||||
max: 120,
|
|
||||||
step: 15,
|
|
||||||
value: localStorage.getItem("alertinterval") == null ? 30 : localStorage.getItem("alertinterval"),
|
|
||||||
slider: true
|
|
||||||
}];
|
|
||||||
|
|
||||||
resolve({
|
|
||||||
templateUrl: './pages/alertsettings.html'
|
|
||||||
}, {
|
|
||||||
context: {
|
|
||||||
settings: settings
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
215
www/settings.js
215
www/settings.js
@ -8,18 +8,27 @@ var SETTINGS = {
|
|||||||
maptileurls: {
|
maptileurls: {
|
||||||
liberty: {
|
liberty: {
|
||||||
url: "https://maps.netsyms.net/styles/osm-liberty/{z}/{x}/{y}.png",
|
url: "https://maps.netsyms.net/styles/osm-liberty/{z}/{x}/{y}.png",
|
||||||
|
json: "https://maps.netsyms.net/styles/osm-liberty/style.json",
|
||||||
name: "Liberty",
|
name: "Liberty",
|
||||||
bgcolor: "#EFEFEF"
|
bgcolor: "#EFEFEF"
|
||||||
},
|
},
|
||||||
terrain: {
|
terrain: {
|
||||||
url: "https://maps.netsyms.net/styles/klokantech-terrain/{z}/{x}/{y}.png",
|
url: "https://maps.netsyms.net/styles/klokantech-terrain/{z}/{x}/{y}.png",
|
||||||
|
json: "https://maps.netsyms.net/styles/klokantech-terrain/style.json",
|
||||||
name: "Terrain",
|
name: "Terrain",
|
||||||
bgcolor: "#EDF5F3"
|
bgcolor: "#EDF5F3"
|
||||||
},
|
},
|
||||||
fiord: {
|
fiord: {
|
||||||
url: "https://maps.netsyms.net/styles/fiord-color/{z}/{x}/{y}.png",
|
url: "https://maps.netsyms.net/styles/fiord-color/{z}/{x}/{y}.png",
|
||||||
|
json: "https://maps.netsyms.net/styles/fiord-color/style.json",
|
||||||
name: "Dark Fiord",
|
name: "Dark Fiord",
|
||||||
bgcolor: "#45516E"
|
bgcolor: "#45516E"
|
||||||
|
},
|
||||||
|
oledblack: {
|
||||||
|
url: "https://maps.netsyms.net/styles/oled-black/{z}/{x}/{y}.png",
|
||||||
|
json: "https://maps.netsyms.net/styles/oled-black/style.json",
|
||||||
|
name: "OLED Black",
|
||||||
|
bgcolor: "#000000"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
alertsounds: {
|
alertsounds: {
|
||||||
@ -72,14 +81,14 @@ var SETTINGS = {
|
|||||||
},
|
},
|
||||||
signature: {
|
signature: {
|
||||||
id: "signature",
|
id: "signature",
|
||||||
name: "Signature",
|
name: "Signature Item",
|
||||||
icon: "fas fa-file-signature fa-fw",
|
icon: "fas fa-file-signature fa-fw",
|
||||||
mapicon: "signature",
|
mapicon: "signature",
|
||||||
pluralmapicon: "signatures"
|
pluralmapicon: "signatures"
|
||||||
},
|
},
|
||||||
express: {
|
express: {
|
||||||
id: "express",
|
id: "express",
|
||||||
name: "Express",
|
name: "Express Item",
|
||||||
icon: "fas fa-shipping-fast fa-fw",
|
icon: "fas fa-shipping-fast fa-fw",
|
||||||
mapicon: "express",
|
mapicon: "express",
|
||||||
pluralmapicon: "multiple-items"
|
pluralmapicon: "multiple-items"
|
||||||
@ -94,8 +103,208 @@ var SETTINGS = {
|
|||||||
"windy",
|
"windy",
|
||||||
"none"
|
"none"
|
||||||
],
|
],
|
||||||
|
scannerevents: [
|
||||||
|
{
|
||||||
|
button: 1,
|
||||||
|
title: "Delivered",
|
||||||
|
type: "event",
|
||||||
|
after: [
|
||||||
|
{
|
||||||
|
button: 1,
|
||||||
|
title: "In/At Mailbox",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 2,
|
||||||
|
title: "Front Door/Porch",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 3,
|
||||||
|
title: "Left with Individual at Address",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 4,
|
||||||
|
title: "Front Desk/Reception/Mail Room",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 5,
|
||||||
|
title: "Parcel Locker",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 6,
|
||||||
|
title: "Garage or Other Location at Address",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 7,
|
||||||
|
title: "Left with Neighbor",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 'G',
|
||||||
|
title: "Authorized Agent",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 'U',
|
||||||
|
title: "Tendered to Authorized Agent",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 2,
|
||||||
|
title: "Attempted",
|
||||||
|
type: "event",
|
||||||
|
after: [
|
||||||
|
{
|
||||||
|
button: 2,
|
||||||
|
title: "No Secure Location Available",
|
||||||
|
type: "type",
|
||||||
|
after: "3849"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 3,
|
||||||
|
title: "No Access or Business Closed",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 4,
|
||||||
|
title: "Receptacle Full/Item Oversized",
|
||||||
|
type: "type",
|
||||||
|
after: "3849"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 5,
|
||||||
|
title: "Customer Hold",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 6,
|
||||||
|
title: "Animal Interference",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 3,
|
||||||
|
title: "Return to Sender or Forward",
|
||||||
|
type: "event",
|
||||||
|
after: [
|
||||||
|
{
|
||||||
|
button: 1,
|
||||||
|
title: "Forwarded",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 2,
|
||||||
|
title: "Insufficient Address",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 3,
|
||||||
|
title: "No Such Number",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 4,
|
||||||
|
title: "Addressee Unknown",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 5,
|
||||||
|
title: "Vacant",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 6,
|
||||||
|
title: "Unable to Forward / Forward Order Expired",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 7,
|
||||||
|
title: "Deceased",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 8,
|
||||||
|
title: "Refused",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 9,
|
||||||
|
title: "Returned for Other Reason",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 4,
|
||||||
|
title: "Other",
|
||||||
|
type: "event",
|
||||||
|
after: [
|
||||||
|
{
|
||||||
|
button: 'X',
|
||||||
|
title: "Dispatch to Military/Diplomatic PO",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 1,
|
||||||
|
title: "Return to Post Office Not Attempted / Delivery Delay",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 2,
|
||||||
|
title: "Local Weather Delay",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 3,
|
||||||
|
title: "Visible Damage",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
button: 4,
|
||||||
|
title: "Out for Delivery",
|
||||||
|
type: "type",
|
||||||
|
after: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
geocodecacheexpiry: 604800, // One week
|
||||||
geocodeapi: "https://apis.netsyms.net/packagehelper/geocode.php",
|
geocodeapi: "https://apis.netsyms.net/packagehelper/geocode.php",
|
||||||
trackingapi: "https://apis.netsyms.net/packagehelper/track.php",
|
trackingapi: "https://apis.netsyms.net/packagehelper/track.php",
|
||||||
weatherapi: "https://apis.netsyms.net/packagehelper/weather.php",
|
weatherapi: "https://apis.netsyms.net/packagehelper/weather.php",
|
||||||
geoipapi: "https://apis.netsyms.net/packagehelper/geoip.php"
|
geoipapi: "https://apis.netsyms.net/packagehelper/geoip.php",
|
||||||
|
sharelistapi: "https://apis.netsyms.net/packagehelper/sharepackagelist.php"
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user