2019-08-14 22:09:18 -06:00
/ *
2019-09-11 20:55:07 -06:00
* 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/.
2019-08-14 22:09:18 -06:00
* /
var packages = [ ] ;
2020-01-07 16:06:12 -07:00
if ( getStorage ( "packages" ) != null ) {
packages = JSON . parse ( getStorage ( "packages" ) ) ;
2019-08-14 22:09:18 -06:00
}
2019-09-26 10:53:38 -06:00
/ * *
2019-12-22 17:50:46 -07:00
* Count how many items are still undelivered for a location .
* @ param { type } location An item in the packages array .
2019-09-26 10:53:38 -06:00
* @ returns { Number }
* /
2019-12-22 17:50:46 -07:00
function getUndeliveredCount ( location ) {
2019-09-26 10:53:38 -06:00
var undelivered = 0 ;
2019-12-22 17:50:46 -07:00
for ( var i = 0 ; i < location . items . length ; i ++ ) {
if ( ! location . items [ i ] . delivered ) {
2019-09-26 10:53:38 -06:00
undelivered ++ ;
2019-09-21 22:35:10 -06:00
}
}
2019-09-26 10:53:38 -06:00
return undelivered ;
}
2019-09-28 20:00:30 -06:00
function getPackage ( packageid ) {
for ( var i = 0 ; i < packages . length ; i ++ ) {
for ( var j = 0 ; j < packages [ i ] . items . length ; j ++ ) {
if ( packages [ i ] . items [ j ] . id == packageid ) {
return packages [ i ] . items [ j ] ;
}
}
}
}
2019-11-12 21:36:28 -07:00
function getIconForType ( type ) {
return SETTINGS . itemtypes [ type ] . icon ;
2019-09-26 20:58:13 -06:00
}
function getMapIconForItems ( items ) {
2019-11-12 21:36:28 -07:00
var types = { } ;
2019-09-26 20:58:13 -06:00
var deliveredcount = 0 ;
var type = "package" ;
for ( var i = 0 ; i < items . length ; i ++ ) {
2019-09-26 21:14:17 -06:00
// Don't consider delivered packages when determining icon,
// only count them to check if everything is delivered
2019-09-26 20:58:13 -06:00
if ( items [ i ] . delivered ) {
deliveredcount ++ ;
2019-09-26 21:14:17 -06:00
continue ;
2019-09-26 20:58:13 -06:00
}
2019-11-12 21:36:28 -07:00
if ( isNaN ( types [ items [ i ] . type ] ) ) {
types [ items [ i ] . type ] = 0 ;
}
2019-09-26 21:14:17 -06:00
types [ items [ i ] . type ] ++ ;
2019-09-26 20:58:13 -06:00
}
2019-11-12 21:36:28 -07:00
2019-09-26 20:58:13 -06:00
if ( deliveredcount == items . length ) {
return "check" ;
}
2019-11-12 21:36:28 -07:00
item _types = 0 ;
icon = "multiple-items" ;
// 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
// icon instead of a specific one.
2019-12-29 19:10:45 -07:00
//console.log(types);
2019-11-12 21:36:28 -07:00
for ( var type in types ) {
2019-12-29 19:10:45 -07:00
//console.log(type);
2019-11-12 21:36:28 -07:00
item _types ++ ;
if ( types [ type ] == 1 ) {
icon = SETTINGS . itemtypes [ type ] . mapicon ;
} else {
icon = SETTINGS . itemtypes [ type ] . pluralmapicon ;
2019-09-26 20:58:13 -06:00
}
2019-12-29 19:10:45 -07:00
//console.log(icon);
2019-09-26 20:58:13 -06:00
}
2019-11-12 21:36:28 -07:00
if ( item _types > 1 ) {
return "multiple-items" ;
2019-09-26 20:58:13 -06:00
}
2019-11-12 21:36:28 -07:00
return icon ;
2019-09-26 20:58:13 -06:00
}
2019-11-30 16:40:44 -07:00
function addPackage ( address , latitude , longitude , type , callback , deadline ) {
2019-09-26 10:53:38 -06:00
var added = false ;
2019-09-26 20:58:13 -06:00
if ( typeof type == 'undefined' ) {
2019-11-30 16:40:44 -07:00
type = SETTINGS . itemtypes [ 0 ] . id ;
}
if ( typeof deadline == 'undefined' ) {
deadline = false ;
2019-09-26 20:58:13 -06:00
}
2019-09-28 20:00:30 -06:00
2020-01-13 18:54:46 -07:00
if ( typeof address == "object" ) {
var extendedaddress = address ;
address = extendedaddress . address ;
} else {
var extendedaddress = false ;
}
2019-12-29 16:57:10 -07:00
// Extra precision makes the map stupider,
// and doesn't really increase accuracy since four decimal places ~= 11m
2019-12-29 20:42:35 -07:00
latitude = + ( parseFloat ( "" + latitude ) . toFixed ( 4 ) ) ;
longitude = + ( parseFloat ( "" + longitude ) . toFixed ( 4 ) ) ;
2019-12-29 16:57:10 -07:00
2019-09-28 20:00:30 -06:00
var packageID = uuidv4 ( ) ;
var coordsID = "" ;
2019-09-26 10:53:38 -06:00
for ( var i = 0 ; i < packages . length ; i ++ ) {
2019-12-22 17:50:46 -07:00
if ( packages [ i ] . coords [ 0 ] == latitude && packages [ i ] . coords [ 1 ] == longitude ) {
2019-09-28 20:00:30 -06:00
coordsID = packages [ i ] . id ;
2019-09-26 10:53:38 -06:00
packages [ i ] . items . push ( {
2020-01-13 18:54:46 -07:00
extended : extendedaddress ,
2019-09-26 10:53:38 -06:00
address : address ,
delivered : false ,
2019-09-26 20:58:13 -06:00
type : type ,
2019-11-30 16:40:44 -07:00
deadline : deadline ,
2019-09-28 20:00:30 -06:00
id : packageID
2019-09-26 10:53:38 -06:00
} ) ;
added = true ;
break ;
}
}
if ( ! added ) {
2019-09-28 20:00:30 -06:00
coordsID = uuidv4 ( ) ;
2019-09-26 10:53:38 -06:00
packages . push ( {
coords : [
latitude ,
longitude
] ,
2019-09-28 20:00:30 -06:00
id : coordsID ,
2019-09-26 10:53:38 -06:00
address : address ,
items : [
{
2020-01-13 18:54:46 -07:00
extended : extendedaddress ,
2019-09-26 10:53:38 -06:00
address : address ,
delivered : false ,
2019-09-26 20:58:13 -06:00
type : type ,
2019-11-30 16:40:44 -07:00
deadline : deadline ,
2019-09-28 20:00:30 -06:00
id : packageID
2019-09-26 10:53:38 -06:00
}
]
} ) ;
2019-09-21 22:35:10 -06:00
}
2020-01-07 16:06:12 -07:00
setStorage ( "packages" , JSON . stringify ( packages ) ) ;
2019-09-26 10:53:38 -06:00
2020-04-03 17:44:52 -06:00
appendActivityLog ( "Added" , SETTINGS . itemtypes [ type ] . name , address , "fas fa-truck-loading" ) ;
2019-09-26 10:53:38 -06:00
playSound ( "ok" ) ;
app . toast . show ( {
2019-12-22 17:50:46 -07:00
text : SETTINGS . itemtypes [ type ] . name + ' Added!<br><span style="font-size: 80%;">' + address + "</span>" ,
2019-09-26 10:53:38 -06:00
position : "bottom" ,
destroyOnClose : true ,
closeTimeout : 1000 * 3
} ) ;
if ( map != null ) {
reloadMap ( ) ;
}
2019-09-28 20:00:30 -06:00
if ( typeof callback == 'function' ) {
callback ( {
coordsID : coordsID ,
packageID : packageID
} ) ;
}
2019-10-29 20:12:22 -06:00
2019-10-05 23:39:40 -06:00
addAutofillEntry ( address ) ;
2019-09-26 10:53:38 -06:00
}
2019-11-30 18:44:08 -07:00
/ * *
* 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 ;
2020-04-03 17:44:52 -06:00
let count = 0 ;
2019-11-30 18:44:08 -07:00
for ( latlng in newlist ) {
var latitude = newlist [ latlng ] . coords [ 0 ] ;
var longitude = newlist [ latlng ] . coords [ 1 ] ;
2019-12-29 20:42:35 -07:00
latitude = + ( parseFloat ( "" + latitude ) . toFixed ( 4 ) ) ;
longitude = + ( parseFloat ( "" + longitude ) . toFixed ( 4 ) ) ;
2019-12-29 19:55:43 -07:00
2019-11-30 18:44:08 -07:00
for ( pkg in newlist [ latlng ] . items ) {
var added = false ;
for ( var i = 0 ; i < packages . length ; i ++ ) {
2019-12-29 20:42:35 -07:00
if ( + ( parseFloat ( "" + packages [ i ] . coords [ 0 ] ) . toFixed ( 4 ) ) == latitude && + ( parseFloat ( "" + packages [ i ] . coords [ 1 ] ) . toFixed ( 4 ) ) == longitude ) {
2019-11-30 18:44:08 -07:00
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 ) ;
2020-04-03 17:44:52 -06:00
count ++ ;
2019-11-30 18:44:08 -07:00
added = true ;
}
break ;
}
}
if ( ! added ) {
packages . push ( newlist [ latlng ] ) ;
}
}
}
2020-01-07 16:06:12 -07:00
setStorage ( "packages" , JSON . stringify ( packages ) ) ;
2020-04-03 17:44:52 -06:00
appendActivityLog ( "Imported List" , count + " items added" , "" , "fas fa-file-download" ) ;
2019-11-30 18:44:08 -07:00
if ( map != null ) {
reloadMap ( ) ;
}
return skipped ;
}
2020-01-13 18:54:46 -07:00
function mapCalibrate ( item , packagesentry ) {
// Determine if the delivery location isn't near the map pin
if ( userPosition . coords . accuracy < 20 && timeDiff ( userPosition . updated ) < 10 ) {
// User location is accurate, check distance
var distance = getDistance ( packagesentry . coords [ 0 ] , packagesentry . coords [ 1 ] , userPosition . coords . latitude , userPosition . coords . longitude ) ;
var lat = userPosition . coords . latitude ;
var lon = userPosition . coords . longitude ;
if ( distance > 100 ) { // Over 100 meters distance
if ( typeof item . extended == "object" ) {
// we have all the info we need
2020-04-14 10:40:09 -06:00
var fixmap = function ( item , latitude , longitude , locationtype , pkgsentry ) {
2020-01-13 18:54:46 -07:00
$ . ajax ( {
type : "POST" ,
url : SETTINGS . mapfixapi ,
data : {
number : item . extended . number ,
unit : item . extended . unit ,
street : item . extended . street ,
citystate : item . extended . citystate ,
zip : item . extended . zip ,
latitude : latitude ,
longitude : longitude ,
locationtype : locationtype
} ,
success : function ( ) {
2020-04-14 10:40:09 -06:00
appendActivityLog ( "Map Calibrated" ,
item . address ,
"Thanks for improving the map accuracy!<br>"
+ "Old: <a class='geolink' href='geo:" + pkgsentry . coords [ 0 ] + "," + pkgsentry . coords [ 1 ] + "'>" + pkgsentry . coords [ 0 ] + ", " + pkgsentry . coords [ 1 ] + "</a><br>"
+ "New: <a class='geolink' href='geo:" + latitude + "," + longitude + "'>" + latitude + ", " + longitude + "</a>" ,
"fas fa-map-marked-alt"
) ;
2020-01-13 18:54:46 -07:00
} ,
error : function ( ) {
// try again in five minutes
setTimeout ( function ( ) {
2020-04-14 10:40:09 -06:00
fixmap ( item , latitude , longitude , locationtype , pkgsentry ) ;
2020-01-13 18:54:46 -07:00
} , 1000 * 60 * 5 ) ;
} ,
dataType : "json"
} ) ;
} ;
app . dialog . create ( {
title : 'Map Calibration' ,
text : "Your actual location doesn't match the map location for the " + SETTINGS . itemtypes [ item . type ] . name + " at " + item . address + ". Where are you?" ,
buttons : [
{
text : 'Address' ,
close : true
} ,
{
text : 'Mailbox/CBU' ,
close : true
} ,
{
text : 'Parcel Locker' ,
close : true
} ,
{
text : "Other/Cancel" ,
close : true
}
] ,
verticalButtons : true ,
onClick : function ( dialog , index ) {
switch ( index ) {
case 0 :
2020-04-14 10:40:09 -06:00
fixmap ( item , lat , lon , "address" , packagesentry ) ;
2020-01-13 18:54:46 -07:00
break ;
case 1 :
2020-04-14 10:40:09 -06:00
fixmap ( item , lat , lon , "mailbox" , packagesentry ) ;
2020-01-13 18:54:46 -07:00
break ;
case 2 :
2020-04-14 10:40:09 -06:00
fixmap ( item , lat , lon , "locker" , packagesentry ) ;
2020-01-13 18:54:46 -07:00
break ;
default :
return ;
}
}
} ) . open ( ) ;
}
}
}
}
2019-09-26 10:53:38 -06:00
function markDelivered ( id , delivered ) {
for ( var i = 0 ; i < packages . length ; i ++ ) {
for ( var j = 0 ; j < packages [ i ] . items . length ; j ++ ) {
if ( packages [ i ] . items [ j ] . id == id ) {
2020-01-13 18:54:46 -07:00
2019-09-26 10:53:38 -06:00
if ( typeof delivered == 'undefined' ) {
2019-09-26 20:58:13 -06:00
if ( packages [ i ] . items [ j ] . delivered == false ) {
2019-09-26 10:53:38 -06:00
delivered = true ;
} else {
delivered = false ;
}
}
packages [ i ] . items [ j ] . delivered = delivered ;
2020-04-14 10:44:14 -06:00
let gpslink = "" ;
2020-04-17 14:00:39 -06:00
if ( userPosition . coords . accuracy < 40 && timeDiff ( userPosition . updated ) < 15 ) {
var lat = parseFloat ( userPosition . coords . latitude ) . toFixed ( 5 ) ;
var lon = parseFloat ( userPosition . coords . longitude ) . toFixed ( 5 ) ;
gpslink = "<br /><a class='geolink' href='geo:" + lat + "," + lon + "'>" + lat + ", " + lon + "</a> (±" + getDisplayDistance ( userPosition . coords . accuracy , false ) + ")" ;
2020-04-14 10:44:14 -06:00
}
2019-09-26 10:53:38 -06:00
if ( delivered ) {
2020-04-03 17:44:52 -06:00
packages [ i ] . items [ j ] . deliverytimestamp = time ( ) ;
2020-04-14 10:44:14 -06:00
appendActivityLog ( "Delivered" , SETTINGS . itemtypes [ packages [ i ] . items [ j ] . type ] . name , packages [ i ] . items [ j ] . address + gpslink , "far fa-check-circle" ) ;
2020-01-13 18:54:46 -07:00
mapCalibrate ( packages [ i ] . items [ j ] , packages [ i ] ) ;
2020-04-03 17:44:52 -06:00
} else {
packages [ i ] . items [ j ] . deliverytimestamp = null ;
appendActivityLog ( "Undelivered" , SETTINGS . itemtypes [ packages [ i ] . items [ j ] . type ] . name , packages [ i ] . items [ j ] . address , "fas fa-undo" ) ;
2019-09-26 10:53:38 -06:00
}
2020-04-03 17:44:52 -06:00
setStorage ( "packages" , JSON . stringify ( packages ) ) ;
return ; // so we don't keep looping over the rest of the packages
2019-09-26 10:53:38 -06:00
}
}
}
2019-09-21 22:35:10 -06:00
}
2019-09-28 20:00:30 -06:00
function confirmDeletePackage ( package , callback ) {
2019-08-14 22:09:18 -06:00
app . dialog . confirm (
2019-12-22 17:50:46 -07:00
"Delete " + SETTINGS . itemtypes [ package . type ] . name . toLowerCase ( ) + " at " + package . address + "?" ,
2019-08-14 22:09:18 -06:00
"Confirm" ,
function ( ) {
// delete
2019-09-28 20:00:30 -06:00
deletePackage ( package . id , callback ) ;
2019-08-14 22:09:18 -06:00
} ,
function ( ) {
// cancel
}
) ;
}
2019-09-28 20:00:30 -06:00
function deletePackage ( id , callback ) {
2019-09-26 10:53:38 -06:00
for ( var i = 0 ; i < packages . length ; i ++ ) {
for ( var j = 0 ; j < packages [ i ] . items . length ; j ++ ) {
if ( packages [ i ] . items [ j ] . id == id ) {
2020-04-03 17:44:52 -06:00
appendActivityLog ( "Deleted" , SETTINGS . itemtypes [ packages [ i ] . items [ j ] . type ] . name , packages [ i ] . items [ j ] . address , "fas fa-trash" ) ;
2019-09-26 10:53:38 -06:00
packages [ i ] . items . splice ( j , 1 ) ;
if ( packages [ i ] . items . length == 0 ) {
packages . splice ( i , 1 ) ;
}
2020-01-07 16:06:12 -07:00
setStorage ( "packages" , JSON . stringify ( packages ) ) ;
2019-09-26 10:53:38 -06:00
loadPackageList ( ) ;
2019-09-28 20:00:30 -06:00
if ( typeof callback == 'function' ) {
callback ( id ) ;
}
2019-09-26 10:53:38 -06:00
return ;
}
}
}
2019-08-14 22:09:18 -06:00
}
function countRemainingPackages ( ) {
var undelivered = 0 ;
for ( var i = 0 ; i < packages . length ; i ++ ) {
2019-09-26 10:53:38 -06:00
for ( var j = 0 ; j < packages [ i ] . items . length ; j ++ ) {
if ( packages [ i ] . items [ j ] . delivered != true ) {
undelivered ++ ;
}
2019-08-14 22:09:18 -06:00
}
}
return undelivered ;
2019-09-11 20:19:33 -06:00
}
2019-09-26 20:58:13 -06:00
function countPackages ( ) {
var count = 0 ;
for ( var i = 0 ; i < packages . length ; i ++ ) {
for ( var j = 0 ; j < packages [ i ] . items . length ; j ++ ) {
count ++ ;
}
}
return count ;
}
2020-01-13 18:54:46 -07:00
function addPackageByAddress ( number , unit , street , citystate , zip , type , callback ) {
2019-10-29 20:12:22 -06:00
var requestfinished = false ;
var searchingdialogopen = false ;
2019-11-30 16:40:44 -07:00
var deadline = false ;
var ajaxlookup = function ( ) {
2020-01-07 16:06:12 -07:00
var geocodecache = getStorage ( "geocode_cache" ) ;
2020-01-01 20:29:58 -07:00
if ( geocodecache == null ) {
geocodecache = "{}" ;
2020-01-07 16:06:12 -07:00
setStorage ( "geocode_cache" , "{}" ) ;
2020-01-01 20:29:58 -07:00
}
geocodecache = JSON . parse ( geocodecache ) ;
2020-01-13 18:54:46 -07:00
var cachekey = number + " || " + street + " || " + citystate + " || " + zip + " || " + SETTINGS . itemtypes [ type ] . allowedlocationtypes ;
if ( unit != '' ) {
cachekey = number + " || " + unit + " || " + street + " || " + citystate + " || " + zip + " || " + SETTINGS . itemtypes [ type ] . allowedlocationtypes ;
}
2020-01-01 20:29:58 -07:00
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 ] ;
2020-01-07 16:06:12 -07:00
setStorage ( "geocode_cache" , JSON . stringify ( geocodecache ) ) ;
2020-01-01 20:29:58 -07:00
} else {
console . log ( "Info" , "Using cached geocode result" , cacheitem ) ;
2020-01-13 18:54:46 -07:00
addPackage ( {
address : cacheitem . address ,
number : number ,
unit : unit ,
street : street ,
citystate : citystate ,
zip : zip
} , cacheitem . latitude , cacheitem . longitude , type , callback , deadline ) ;
2020-01-01 20:29:58 -07:00
return ;
}
}
2019-11-30 16:40:44 -07:00
$ . ajax ( {
url : SETTINGS . geocodeapi ,
dataType : 'json' ,
data : {
2019-12-31 01:16:00 -07:00
number : number ,
2020-01-13 18:54:46 -07:00
unit : unit ,
2019-12-31 01:16:00 -07:00
street : street ,
2020-01-10 01:41:11 -07:00
citystate : citystate ,
2020-01-13 18:54:46 -07:00
zip : zip ,
type : SETTINGS . itemtypes [ type ] . allowedlocationtypes
2019-11-30 16:40:44 -07:00
} ,
timeout : 15 * 1000 ,
success : function ( resp ) {
if ( searchingdialogopen ) {
app . dialog . close ( ) ;
searchingdialogopen = false ;
}
requestfinished = true ;
if ( resp . status == "OK" ) {
if ( resp . accuracy . ok ) {
2020-01-13 18:54:46 -07:00
addPackage ( {
address : resp . address . street ,
number : number ,
unit : unit ,
street : street ,
citystate : citystate ,
zip : zip
} , resp . coords [ 0 ] , resp . coords [ 1 ] , type , callback , deadline ) ;
2020-01-01 20:29:58 -07:00
geocodecache [ cachekey ] = {
2020-01-13 18:54:46 -07:00
number : resp . address . number ,
unit : unit ,
2020-01-01 20:29:58 -07:00
address : resp . address . street ,
latitude : resp . coords [ 0 ] ,
longitude : resp . coords [ 1 ] ,
added : Math . floor ( Date . now ( ) / 1000 )
} ;
2020-01-07 16:06:12 -07:00
setStorage ( "geocode_cache" , JSON . stringify ( geocodecache ) ) ;
2019-11-30 16:40:44 -07:00
} 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 == "" ) {
2020-01-13 18:54:46 -07:00
addPackage ( {
address : address ,
number : number ,
unit : unit ,
street : street ,
citystate : citystate ,
zip : zip
} , resp . coords [ 0 ] , resp . coords [ 1 ] , type , callback , deadline ) ;
2019-11-30 16:40:44 -07:00
} else {
2020-01-13 18:54:46 -07:00
addPackage ( {
address : resp . address . street ,
number : number ,
unit : unit ,
street : street ,
citystate : citystate ,
zip : zip
} , resp . coords [ 0 ] , resp . coords [ 1 ] , type , callback , deadline ) ;
2019-11-30 16:40:44 -07:00
}
}
) ;
}
2019-10-29 20:12:22 -06:00
} else {
playSound ( "error" ) ;
2019-11-30 16:40:44 -07:00
app . dialog . alert ( resp . message , "Error" ) ;
}
} ,
error : function ( jqXHR , status , errorThrown ) {
if ( searchingdialogopen ) {
app . dialog . close ( ) ;
searchingdialogopen = false ;
2019-10-29 20:12:22 -06:00
}
2019-11-30 16:40:44 -07:00
requestfinished = true ;
2019-09-11 20:19:33 -06:00
playSound ( "error" ) ;
2019-11-30 16:40:44 -07:00
app . dialog . alert ( "There was a network issue while finding the address. Please try adding the item again." , "Error" ) ;
2019-09-11 20:19:33 -06:00
}
2019-11-30 16:40:44 -07:00
} ) ;
// Open a loading message if there's a delay finding the address
setTimeout ( function ( ) {
if ( ! requestfinished ) {
app . dialog . preloader ( "Searching for address..." ) ;
searchingdialogopen = true ;
2019-10-29 20:12:22 -06:00
}
2019-11-30 16:40:44 -07:00
} , 750 ) ;
}
2020-01-08 14:49:29 -07:00
var prelookup = function ( ) {
if ( type == "express" ) {
if ( getStorage ( "deadlinealarm_minutes" ) == null ) {
setStorage ( "deadlinealarm_minutes" , 20 ) ;
}
var minutes = getStorage ( "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
} ,
2021-12-06 22:14:01 -07:00
{
text : '6:00 PM' ,
close : true
} ,
2020-01-08 14:49:29 -07:00
{
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 :
2021-12-06 22:14:01 -07:00
deadline . setMinutes ( 00 ) ;
deadline . setHours ( 12 + 6 ) ;
break ;
2020-01-08 14:49:29 -07:00
default :
deadline = false ;
break ;
}
2019-11-30 16:40:44 -07:00
2020-01-08 14:49:29 -07:00
if ( deadline != false ) {
deadline = deadline . getTime ( ) / 1000 ;
}
ajaxlookup ( ) ;
2019-11-30 16:40:44 -07:00
}
2020-01-08 14:49:29 -07:00
} ) . open ( ) ;
} else {
ajaxlookup ( ) ;
}
}
var deliverable = isDeliverable ( number , street ) ;
if ( deliverable . ok ) {
prelookup ( ) ;
2019-11-30 16:40:44 -07:00
} else {
2020-01-08 14:49:29 -07:00
app . dialog . confirm (
2020-03-18 15:52:49 -06:00
"A route note says this address " + deliverable . reason + ". Add item anyways?" ,
2020-01-08 14:49:29 -07:00
"Confirm" ,
function ( ) {
prelookup ( ) ;
} ,
function ( ) {
// cancel
}
) ;
2019-11-30 16:40:44 -07:00
}
}
2019-11-12 21:36:28 -07:00
2020-05-25 22:02:56 -06:00
function addPackageByBarcode ( barcode , type , callback ) {
var requestfinished = false ;
var searchingdialogopen = false ;
var deadline = false ;
var ajaxlookup = function ( ) {
$ . ajax ( {
url : SETTINGS . geocodebarcodeapi ,
dataType : 'json' ,
data : {
code : barcode ,
type : SETTINGS . itemtypes [ type ] . allowedlocationtypes
} ,
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 ) ;
} else {
playSound ( "error" ) ;
app . dialog . alert ( "The scanned address couldn't be reliably located." , "Error" ) ;
}
} 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 looking up the barcode. Please try again." , "Error" ) ;
}
} ) ;
// Open a loading message if there's a delay finding the address
setTimeout ( function ( ) {
if ( ! requestfinished ) {
app . dialog . preloader ( "Looking up barcode..." ) ;
searchingdialogopen = true ;
}
} , 750 ) ;
}
var prelookup = function ( ) {
if ( type == "express" ) {
if ( getStorage ( "deadlinealarm_minutes" ) == null ) {
setStorage ( "deadlinealarm_minutes" , 20 ) ;
}
var minutes = getStorage ( "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
} ,
2021-12-06 23:44:14 -07:00
{
text : '6:00 PM' ,
close : true
} ,
2020-05-25 22:02:56 -06:00
{
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 :
2021-12-06 23:44:14 -07:00
deadline . setMinutes ( 00 ) ;
deadline . setHours ( 12 + 6 ) ;
break ;
2020-05-25 22:02:56 -06:00
default :
deadline = false ;
break ;
}
if ( deadline != false ) {
deadline = deadline . getTime ( ) / 1000 ;
}
ajaxlookup ( ) ;
}
} ) . open ( ) ;
} else {
ajaxlookup ( ) ;
}
}
2020-06-07 20:24:23 -06:00
2020-05-25 22:02:56 -06:00
prelookup ( ) ;
}
2019-11-30 16:40:44 -07:00
function checkDeadlines ( ) {
2020-01-07 16:06:12 -07:00
if ( getStorage ( "deadlinealarm_minutes" ) == null ) {
setStorage ( "deadlinealarm_minutes" , 20 ) ;
2019-11-30 16:40:44 -07:00
}
2020-01-07 16:06:12 -07:00
var minutes = getStorage ( "deadlinealarm_minutes" ) ;
2019-11-30 16:40:44 -07:00
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 ;
2020-01-07 16:06:12 -07:00
setStorage ( "packages" , JSON . stringify ( packages ) ) ;
2019-11-30 16:40:44 -07:00
}
}
2019-10-29 20:12:22 -06:00
}
2019-11-30 16:40:44 -07:00
}
}
setInterval ( checkDeadlines , 15 * 1000 ) ;