You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
PackageHelper/www/assets/js/packages.js

385 lines
12 KiB
JavaScript

/*
* 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 packages = [];
if (localStorage.getItem("packages") != null) {
packages = JSON.parse(localStorage.getItem("packages"));
}
/**
* Count how many items are still undelivered for an address.
* @param {type} address An item in the packages array.
* @returns {Number}
*/
function getUndeliveredCount(address) {
var undelivered = 0;
for (var i = 0; i < address.items.length; i++) {
if (!address.items[i].delivered) {
undelivered++;
}
}
return undelivered;
}
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];
}
}
}
}
function getIconForType(type) {
return SETTINGS.itemtypes[type].icon;
}
function getMapIconForItems(items) {
var types = {};
var deliveredcount = 0;
var type = "package";
for (var i = 0; i < items.length; i++) {
// Don't consider delivered packages when determining icon,
// only count them to check if everything is delivered
if (items[i].delivered) {
deliveredcount++;
continue;
}
if (isNaN(types[items[i].type])) {
types[items[i].type] = 0;
}
types[items[i].type]++;
}
if (deliveredcount == items.length) {
return "check";
}
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.
console.log(types);
for (var type in types) {
console.log(type);
item_types++;
if (types[type] == 1) {
icon = SETTINGS.itemtypes[type].mapicon;
} else {
icon = SETTINGS.itemtypes[type].pluralmapicon;
}
console.log(icon);
}
if (item_types > 1) {
return "multiple-items";
}
return icon;
}
function addPackage(address, latitude, longitude, type, callback, deadline) {
var added = false;
if (typeof type == 'undefined') {
type = SETTINGS.itemtypes[0].id;
}
if (typeof deadline == 'undefined') {
deadline = false;
}
var packageID = uuidv4();
var coordsID = "";
for (var i = 0; i < packages.length; i++) {
if (packages[i].coords[0] == latitude && packages[i].coords[1] == longitude && packages[i].address == address) {
coordsID = packages[i].id;
packages[i].items.push({
address: address,
delivered: false,
type: type,
deadline: deadline,
id: packageID
});
added = true;
break;
}
}
if (!added) {
coordsID = uuidv4();
packages.push({
coords: [
latitude,
longitude
],
id: coordsID,
address: address,
items: [
{
address: address,
delivered: false,
type: type,
deadline: deadline,
id: packageID
}
]
});
}
localStorage.setItem("packages", JSON.stringify(packages));
playSound("ok");
app.toast.show({
text: 'Package Added!<br><span style="font-size: 80%;">' + address + "</span>",
position: "bottom",
destroyOnClose: true,
closeTimeout: 1000 * 3
});
if (map != null) {
reloadMap();
}
if (typeof callback == 'function') {
callback({
coordsID: coordsID,
packageID: packageID
});
}
addAutofillEntry(address);
}
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) {
if (typeof delivered == 'undefined') {
if (packages[i].items[j].delivered == false) {
delivered = true;
} else {
delivered = false;
}
}
packages[i].items[j].delivered = delivered;
if (delivered) {
packages[i].items[j].deliverytimestamp = Date.now();
}
}
}
}
localStorage.setItem("packages", JSON.stringify(packages));
}
function confirmDeletePackage(package, callback) {
app.dialog.confirm(
"Delete item at " + package.address + "?",
"Confirm",
function () {
// delete
deletePackage(package.id, callback);
},
function () {
// cancel
}
);
}
function deletePackage(id, callback) {
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) {
packages[i].items.splice(j, 1);
if (packages[i].items.length == 0) {
packages.splice(i, 1);
}
localStorage.setItem("packages", JSON.stringify(packages));
loadPackageList();
if (typeof callback == 'function') {
callback(id);
}
return;
}
}
}
}
function countRemainingPackages() {
var undelivered = 0;
for (var i = 0; i < packages.length; i++) {
for (var j = 0; j < packages[i].items.length; j++) {
if (packages[i].items[j].delivered != true) {
undelivered++;
}
}
}
return undelivered;
}
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;
}
function addPackageByAddress(address, citystate, type, callback) {
var requestfinished = false;
var searchingdialogopen = false;
var deadline = false;
var ajaxlookup = function () {
$.ajax({
url: SETTINGS.geocodeapi,
dataType: 'json',
data: {
address: address + " " + 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);
} 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 {
playSound("error");
app.dialog.alert(resp.message, "Error");
}
},
error: function (jqXHR, status, errorThrown) {
if (searchingdialogopen) {
app.dialog.close();
searchingdialogopen = false;
}
requestfinished = true;
playSound("error");
app.dialog.alert("There was a network issue while finding the address. Please try adding the item again.", "Error");
}
});
// Open a loading message if there's a delay finding the address
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;
}
}
}
}
}
setInterval(checkDeadlines, 15 * 1000);