Compare commits

..

No commits in common. "master" and "v1.2.0" have entirely different histories.

42 changed files with 525 additions and 4431 deletions

View File

@ -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.3.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"> <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">
<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,5 +32,7 @@
<allow-intent href="itms:*" /> <allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" /> <allow-intent href="itms-apps:*" />
</platform> </platform>
<hook src="scripts/npm_prepare.sh" type="before_prepare" /> <hook src="scripts/www_npm_install.sh" type="before_prepare" />
<hook src="scripts/generate_credits.sh" type="before_prepare" />
<hook src="scripts/remove_bloat.sh" type="before_prepare" />
</widget> </widget>

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
{ {
"name": "com.netsyms.packagehelper", "name": "com.netsyms.packagehelper",
"displayName": "PackageHelper", "displayName": "PackageHelper",
"version": "1.3.0", "version": "1.2.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,8 +18,7 @@
"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",
@ -29,7 +28,6 @@
"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"

View File

@ -1,4 +1,3 @@
#!/bin/bash
cd www cd www
yarn licenses generate-disclaimer > ../license-credits.md yarn licenses generate-disclaimer > ../license-credits.md
cd .. cd ..

View File

@ -1,5 +0,0 @@
#!/bin/sh
./scripts/www_npm_install.sh
./scripts/generate_credits.sh
./scripts/remove_bloat.sh

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/sh
# 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,80 +7,60 @@ echo "Removing bloat in node_modules..."
pwd pwd
cd www/node_modules cd www/node_modules
rm -rf {ansicolors,buffer-from,cardinal,concat-stream,core-util-is,csscolorparser} rm -rf dom7
rm -rf {dom7,earcut,esprima,geojson-vt,gl-matrix,grid-index,ieee754,inherits,isarray} rm -rf path-to-regexp
rm -rf {kdbush,leaflet-geometryutil,@mapbox,minimist,murmurhash-js} rm -rf ssr-window
rm -rf {path-to-regexp,pbf,potpack,process-nextick-args} rm -rf template7
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,less,metadata,scss,sprites,svgs} rm -rf js
find css -type f -not -name 'all.min.css' -delete rm -rf less
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
# Remove everything except the icon font and license, but also exclude the rm -rf action
# current and parent folder (. , ..) so rm won't complain about refusing rm -rf alert
# to delete the whole filesystem rm -rf av
find . -maxdepth 1 -not -name '.' -not -name 'LICENSE' -not -name 'iconfont' -exec rm -rf {} \; rm -rf bower.json
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"

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/sh
cd www cd www
npm install npm install

View File

@ -18,32 +18,3 @@ Framework7 and FontAwesome both have a .fab class
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;
}

View File

@ -1,60 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -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, q); byNumber = searchAutofillByNumber(number);
} }
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, q) { function searchAutofillByNumber(number) {
if (typeof autofillDB[number] == 'undefined') { if (typeof autofillDB[number] == 'undefined') {
return []; return [];
} }
@ -96,18 +96,10 @@ function searchAutofillByNumber(number, q) {
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++) {
// if there's no search query OR if the query matches the current item streets.push(sorted[i][0]);
if (!query || (query && sorted[i][0].toLowerCase().includes(q))) {
streets.push(sorted[i][0]);
}
} }
return streets; return streets;
@ -120,12 +112,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]);
} }

View File

@ -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("Info", "Deleting package", $(this).data("packageid")); console.log("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) {

View File

@ -45,10 +45,14 @@ 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) {
@ -85,7 +89,7 @@ if ("geolocation" in navigator) {
} }
} else { } else {
if (map != null) { if (map != null) {
map.startLocateControl(); map.locateControl.start();
mapLocationControlStarted = true; mapLocationControlStarted = true;
} }
} }
@ -100,7 +104,7 @@ if ("geolocation" in navigator) {
}); });
} else { } else {
geoerrorcount++; geoerrorcount++;
console.log("Warn", "Geolocation error #" + geoerrorcount + ": ", error); console.log("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({

View File

@ -63,7 +63,10 @@ router.on("pageInit", function (pagedata) {
}); });
router.on("routeChange", function (newRoute) { router.on("routeChange", function (newRoute) {
console.log("Info", "Navigating to ", newRoute.path); console.log(newRoute);
if (newRoute == "home") {
router.refreshPage();
}
}); });
// Set alert radius to 100 meters by default // Set alert radius to 100 meters by default

View File

@ -43,26 +43,21 @@ $("#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( addPackageByAddress(address, $("input[name=citystate]").val().toUpperCase(), $("input[name=itemtype]:checked").val(), function (ids) {
$("input[name=number]").val().toUpperCase(), var packageObj = getPackage(ids.packageID);
$("input[name=street]").val().toUpperCase(), // Reset item type to default
$("input[name=citystate]").val().toUpperCase(), $("input[name=itemtype][data-default=1]").prop("checked", true);
$("input[name=itemtype]:checked").val(), $("#historylist").prepend('<li class="history-list-item item-content" data-package="' + ids.packageID + '">'
function (ids) { + ' <div class="item-media">'
var packageObj = getPackage(ids.packageID); + ' <i class="icon ' + getIconForType(packageObj.type) + '"></i>'
// Reset item type to default + ' </div>'
$("input[name=itemtype][data-default=1]").prop("checked", true); + ' <div class="item-inner">'
$("#historylist").prepend('<li class="history-list-item item-content" data-package="' + ids.packageID + '">' + ' <div class="item-title">'
+ ' <div class="item-media">' + ' ' + packageObj.address
+ ' <i class="icon ' + getIconForType(packageObj.type) + '"></i>' + ' </div>'
+ ' </div>' + ' </div>'
+ ' <div class="item-inner">' + '</li>');
+ ' <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,
@ -71,9 +66,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("Info", "Asking to delete ", $(this).data("package")); console.log("Asking to delete ", $(this).data("package"));
confirmDeletePackage(getPackage($(this).data("package")), function (id) { confirmDeletePackage(getPackage($(this).data("package")), function (id) {
console.log("Info", "Removing history item", id); console.log("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");

View File

@ -6,24 +6,8 @@
var map = null; var map = null;
var maptype = "mapbox";
function createMap() { function createMap() {
if (localStorage.getItem("maptype") == null) { map = leafletMap();
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);
} }
@ -36,37 +20,16 @@ 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();
if (document.getElementById("mapbox") != null) { map.setView(mapcenter, mapzoom);
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);
} }
} }
@ -85,12 +48,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("");

View File

@ -14,8 +14,6 @@ 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");
} }
@ -32,7 +30,7 @@ function leafletMap() {
showPopup: false, showPopup: false,
locateOptions: { locateOptions: {
enableHighAccuracy: true, enableHighAccuracy: true,
maxZoom: localStorage.getItem("trackzoom") == null ? 16 : localStorage.getItem("trackzoom") * 1 maxZoom: 16
}, },
setView: "untilPanOrZoom", setView: "untilPanOrZoom",
icon: "far fa-compass", icon: "far fa-compass",
@ -45,14 +43,6 @@ 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) {
} }
@ -67,7 +57,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
@ -75,7 +65,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",

View File

@ -1,134 +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/.
*/
// 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;
}

View File

@ -11,14 +11,14 @@ if (localStorage.getItem("packages") != null) {
} }
/** /**
* Count how many items are still undelivered for a location. * Count how many items are still undelivered for an address.
* @param {type} location An item in the packages array. * @param {type} address An item in the packages array.
* @returns {Number} * @returns {Number}
*/ */
function getUndeliveredCount(location) { function getUndeliveredCount(address) {
var undelivered = 0; var undelivered = 0;
for (var i = 0; i < location.items.length; i++) { for (var i = 0; i < address.items.length; i++) {
if (!location.items[i].delivered) { if (!address.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,31 +82,22 @@ function getMapIconForItems(items) {
return icon; return icon;
} }
function addPackage(address, latitude, longitude, type, callback, deadline) { function addPackage(address, latitude, longitude, type, callback) {
var added = false; var added = false;
if (typeof type == 'undefined') { if (typeof type == 'undefined') {
type = SETTINGS.itemtypes[0].id; type = "package";
} }
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) { if (packages[i].coords[0] == latitude && packages[i].coords[1] == longitude && packages[i].address == address) {
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;
@ -127,7 +118,6 @@ function addPackage(address, latitude, longitude, type, callback, deadline) {
address: address, address: address,
delivered: false, delivered: false,
type: type, type: type,
deadline: deadline,
id: packageID id: packageID
} }
] ]
@ -138,7 +128,7 @@ function addPackage(address, latitude, longitude, type, callback, deadline) {
playSound("ok"); playSound("ok");
app.toast.show({ app.toast.show({
text: SETTINGS.itemtypes[type].name + ' Added!<br><span style="font-size: 80%;">' + address + "</span>", text: 'Package Added!<br><span style="font-size: 80%;">' + address + "</span>",
position: "bottom", position: "bottom",
destroyOnClose: true, destroyOnClose: true,
closeTimeout: 1000 * 3 closeTimeout: 1000 * 3
@ -158,51 +148,6 @@ function addPackage(address, latitude, longitude, type, callback, deadline) {
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++) {
@ -228,7 +173,7 @@ function markDelivered(id, delivered) {
function confirmDeletePackage(package, callback) { function confirmDeletePackage(package, callback) {
app.dialog.confirm( app.dialog.confirm(
"Delete " + SETTINGS.itemtypes[package.type].name.toLowerCase() + " at " + package.address + "?", "Delete item at " + package.address + "?",
"Confirm", "Confirm",
function () { function () {
// delete // delete
@ -284,184 +229,60 @@ function countPackages() {
return count; return count;
} }
function addPackageByAddress(number, street, citystate, type, callback) { function addPackageByAddress(address, citystate, type, callback) {
var requestfinished = false; var requestfinished = false;
var searchingdialogopen = false; var searchingdialogopen = false;
var deadline = false; $.ajax({
url: SETTINGS.geocodeapi,
var ajaxlookup = function () { dataType: 'json',
var geocodecache = localStorage.getItem("geocode_cache"); data: {
if (geocodecache == null) { address: address + " " + citystate
geocodecache = "{}"; },
localStorage.setItem("geocode_cache", "{}"); timeout: 15 * 1000,
} success: function (resp) {
if (searchingdialogopen) {
geocodecache = JSON.parse(geocodecache); app.dialog.close();
var cachekey = number + " || " + street + " || " + citystate; searchingdialogopen = false;
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") {
$.ajax({ if (resp.accuracy.ok) {
url: SETTINGS.geocodeapi, addPackage(resp.address.street, resp.coords[0], resp.coords[1], type, callback);
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.alert(resp.message, "Error"); app.dialog.confirm(
} "The address \"" + address + "\" couldn't be reliably located. Add it anyways?",
}, "Accuracy Warning",
error: function (jqXHR, status, errorThrown) { function (ok) {
if (searchingdialogopen) { if (resp.address.street == "") {
app.dialog.close(); addPackage(address, resp.coords[0], resp.coords[1], type, callback);
searchingdialogopen = false; } else {
} 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");
} }
} });
}
setInterval(checkDeadlines, 15 * 1000); // 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);
}

View File

@ -64,76 +64,30 @@ 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) {
// Close map sheet if it's open router.back({force: true, ignoreCache: true});
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("Info", 'Wakelock acquired'); console.log('Wakelock acquired');
}, function () { }, function () {
console.log("Warn", 'Failed to acquire wakelock'); console.log('Failed to acquire wakelock');
}); });
} else { } else {
window.powerManagement.release(function () { window.powerManagement.release(function () {
console.log("Info", 'Wakelock released'); console.log('Wakelock released');
}, function () { }, function () {
console.log("Warn", 'Failed to release wakelock'); console.log('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');
} }
@ -142,37 +96,34 @@ function initCordova() {
window.open(url, '_system', ''); window.open(url, '_system', '');
} }
if (typeof device != "undefined" && device.platform != "browser") { scanBarcode = function (success, error) {
scanBarcode = function (success, error) { cordova.plugins.barcodeScanner.scan(
cordova.plugins.barcodeScanner.scan( function (result) {
function (result) { if (!result.cancelled) {
if (!result.cancelled) { success(result.text);
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) {
} else { if (typeof error == "function") {
setupHTML5BarcodeScanner(); 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 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
@ -205,22 +156,57 @@ 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>');
setupHTML5BarcodeScanner(); 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('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() {

View File

@ -7,6 +7,7 @@
$('.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") {
@ -16,35 +17,27 @@ $('.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("Info", 'Wakelock acquired'); console.log('Wakelock acquired');
}, function () { }, function () {
console.log("Warn", 'Failed to acquire wakelock'); console.log('Failed to acquire wakelock');
}); });
} else { } else {
window.powerManagement.release(function () { window.powerManagement.release(function () {
console.log("Info", 'Wakelock released'); console.log('Wakelock released');
}, function () { }, function () {
console.log("Warn", 'Failed to release wakelock'); console.log('Failed to release wakelock');
}); });
} }
} else { } else {
@ -76,16 +69,7 @@ $('.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();
}); });

View File

@ -1,271 +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/.
*/
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();
}
});

View File

@ -1,23 +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/.
*/
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
}
);
}

View File

@ -1,101 +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/.
*/
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");
});
}

View File

@ -86,21 +86,7 @@ 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", {
@ -150,7 +136,7 @@ function scanTrackingBarcode() {
} }
}, function (error) { }, function (error) {
app.dialog.alert(error, "Error"); app.dialog.alert(error, "Error");
}); })
} }
$("#trackbtn").click(function () { $("#trackbtn").click(function () {
@ -162,9 +148,3 @@ $("#trackbtn").click(function () {
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();
}
});

View File

@ -12,7 +12,6 @@
<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" />
@ -37,7 +36,6 @@
<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>
@ -52,7 +50,6 @@
<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>

View File

@ -1,19 +1,18 @@
{ {
"name": "PackageHelper", "name": "PackageHelper",
"version": "1.3.0", "version": "1.2.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.1.3", "framework7": "^5.0.2",
"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": {}

View File

@ -0,0 +1,90 @@
<!-- 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

View File

@ -1,58 +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="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>

View File

@ -1,77 +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="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>

View File

@ -24,12 +24,6 @@
<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">

View File

@ -15,11 +15,9 @@
</div> </div>
<div class="title">Map</div> <div class="title">Map</div>
<div class="right"> <div class="right">
{{#if show_help}} <a class="link" onclick="reloadMap()">
<a class="link" href="/help/map"> <i class="material-icons">refresh</i>
<i class="icon material-icons">help</i>
</a> </a>
{{/if}}
</div> </div>
</div> </div>
</div> </div>

View File

@ -12,13 +12,13 @@
<i class="icon icon-back"></i> <i class="icon icon-back"></i>
</a> </a>
</div> </div>
<div class="title">{{page_title}}</div> <div class="title">Settings</div>
</div> </div>
</div> </div>
<div class="page-content"> <div class="page-content">
<div class="list media-list no-hairlines no-margin-top tablet-inset"> <div class="list media-list no-hairlines tablet-inset" style="margin-top: 0;">
<ul> <ul>
{{#each settings}} {{#each settings}}
<li> <li>

View File

@ -19,14 +19,6 @@
<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>
@ -43,14 +35,14 @@
</div> </div>
</a> </a>
</li> </li>
<li> <!--<li>
<a href="/toolbox/sharelist" class="item-link item-content"> <a href="/toolbox/scanner" class="item-link item-content">
<div class="item-media"><i class="icon fas fa-share-alt"></i></div> <div class="item-media"><i class="icon fas fa-barcode"></i></div>
<div class="item-inner"> <div class="item-inner">
<div class="item-title">Share Item List</div> <div class="item-title">Scan for Delivery</div>
</div> </div>
</a> </a>
</li> </li>-->
</ul> </ul>
</div> </div>
</div> </div>

View File

@ -1,50 +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">
<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>

View File

@ -1,60 +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="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>

View File

@ -1,107 +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="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>

View File

@ -1,68 +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="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>

View File

@ -40,32 +40,9 @@
</ul> </ul>
</div> </div>
<div class="block text-align-center"> <div class="block">
<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>

View File

@ -52,7 +52,12 @@
</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" id="trackingbarcode"></svg> <svg class="barcode"
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>
@ -79,11 +84,6 @@
</div> </div>
<script> <script>
JsBarcode("#trackingbarcode", "{{#if barcode}}{{escape barcode}}{{else}}{{escape code}}{{/if}}", { JsBarcode(".barcode").init();
format: "code128",
ean128: true,
width: 2,
height: 40
});
</script> </script>
</div> </div>

View File

@ -4,10 +4,6 @@
* 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',
@ -31,14 +27,13 @@ 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({
@ -61,13 +56,8 @@ var routes = [
}, },
{ {
path: '/list', path: '/list',
name: 'list',
templateUrl: './pages/list.html', templateUrl: './pages/list.html',
options: { name: 'list',
context: {
show_help: show_help
}
},
on: { on: {
pageAfterIn: function () { pageAfterIn: function () {
loadPackageList(); loadPackageList();
@ -84,17 +74,14 @@ var routes = [
} }
}); });
} }
} },
keepAlive: true
}, },
{ {
path: '/map', path: '/map',
templateUrl: './pages/map.html', url: './pages/map.html',
name: 'map', name: 'map',
options: { keepAlive: true,
context: {
show_help: show_help
}
},
on: { on: {
pageAfterIn: function () { pageAfterIn: function () {
reloadMap(); reloadMap();
@ -104,114 +91,27 @@ var routes = [
{ {
path: '/toolbox', path: '/toolbox',
url: './pages/toolbox.html', url: './pages/toolbox.html',
name: 'toolbox', name: 'toolbox'
routes: [
{
path: '/scanner',
templateUrl: './pages/toolbox/scanner.html',
routes: [
{
path: '/scanner',
templateUrl: './pages/toolbox/scanner/scanner.html',
name: 'scanner'
},
{
path: '/entries',
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: '/help', path: '/toolbox/track',
routes: [ url: './pages/toolbox/track.html',
{ name: 'track'
path: '/list', },
panel: { {
url: './pages/help/list.html' path: '/toolbox/weather',
} url: './pages/toolbox/weather.html',
}, name: 'weather',
{ on: {
path: '/map', pageAfterIn: function () {
panel: { loadWeather();
url: './pages/help/map.html'
}
} }
] }
},
{
path: '/toolbox/track/info',
templateUrl: './pages/toolbox/trackinginfo.html',
name: 'trackinginfo'
}, },
{ {
path: '/credits', path: '/credits',
@ -222,6 +122,17 @@ 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",
@ -229,13 +140,6 @@ 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
} }
]; ];
@ -260,17 +164,33 @@ var routes = [
onclick: "" onclick: ""
}, },
{ {
setting: "showhelp", setting: "units",
title: "Show help", title: "Measurement units",
text: "Show the <span class=material-icons-intext><i class=material-icons>help</i></span> icons", select: true,
toggle: true, options: [
checked: localStorage.getItem("show_help") != "false", {
onclick: "" value: "metric",
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 &copy; 2019-2020 Netsyms Technologies. Licensed under the Mozilla Public License 2.0.", text: "Copyright &copy; 2019 Netsyms Technologies. Licensed under the Mozilla Public License 2.0.",
onclick: "" onclick: ""
}, },
{ {
@ -284,7 +204,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=PackageHelperApp')", onclick: "openBrowser('https://netsyms.com/legal?pk_campaign=PackageHelpterApp')",
link: true link: true
}); });
@ -292,156 +212,68 @@ var routes = [
templateUrl: './pages/settings.html' templateUrl: './pages/settings.html'
}, { }, {
context: { context: {
page_title: "Settings",
settings: settings settings: settings
} }
}); });
}, }
routes: [ },
{ {
path: '/alerts', path: '/settings/alerts',
name: 'settings', name: 'alertsettings',
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
}
});
}
},
]; ];

View File

@ -8,27 +8,18 @@ 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: {
@ -81,14 +72,14 @@ var SETTINGS = {
}, },
signature: { signature: {
id: "signature", id: "signature",
name: "Signature Item", name: "Signature",
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 Item", name: "Express",
icon: "fas fa-shipping-fast fa-fw", icon: "fas fa-shipping-fast fa-fw",
mapicon: "express", mapicon: "express",
pluralmapicon: "multiple-items" pluralmapicon: "multiple-items"
@ -103,208 +94,8 @@ 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"
} }