/* * 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!
' + address + "", 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);