diff --git a/www/assets/js/packages.js b/www/assets/js/packages.js
index bb9b0e6..2c412dc 100644
--- a/www/assets/js/packages.js
+++ b/www/assets/js/packages.js
@@ -153,6 +153,49 @@ function addPackage(address, latitude, longitude, type, callback, deadline) {
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];
+ var address = newlist[latlng].address;
+
+ for (pkg in newlist[latlng].items) {
+ var added = false;
+ for (var i = 0; i < packages.length; i++) {
+ if (packages[i].coords[0] == latitude && packages[i].coords[1] == longitude && packages[i].address == address) {
+ 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) {
for (var i = 0; i < packages.length; i++) {
for (var j = 0; j < packages[i].items.length; j++) {
diff --git a/www/assets/js/toolbox_sharelist.js b/www/assets/js/toolbox_sharelist.js
new file mode 100644
index 0000000..7a84db1
--- /dev/null
+++ b/www/assets/js/toolbox_sharelist.js
@@ -0,0 +1,101 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+
+function uploadList() {
+ if (packages.length == 0) {
+ app.dialog.alert("Your list doesn't have anything to send.", "Empty List");
+ return;
+ }
+ app.dialog.preloader("Uploading...");
+ var uploadlistdialogopen = true;
+ $.ajax({
+ url: SETTINGS.sharelistapi,
+ dataType: 'json',
+ method: 'post',
+ data: {
+ packages: JSON.stringify(packages)
+ },
+ timeout: 15 * 1000,
+ success: function (resp) {
+ if (uploadlistdialogopen) {
+ app.dialog.close();
+ uploadlistdialogopen = false;
+ }
+ if (resp.status == "OK") {
+ JsBarcode("#listidbarcode", resp.uuid, {
+ format: "code128",
+ ean128: false,
+ width: 2,
+ height: 40
+ });
+ $("#listidbarcodeli").css("display", "");
+ } else {
+ app.dialog.alert(resp.message, "Error");
+ }
+ },
+ error: function (jqXHR, status, errorThrown) {
+ if (uploadlistdialogopen) {
+ app.dialog.close();
+ uploadlistdialogopen = false;
+ }
+ app.dialog.alert("There was a network or server issue while uploading the list. Please try again.", "Error");
+ }
+ });
+}
+
+function downloadItemList(code) {
+ if (typeof code == "undefined") {
+ code = $("#getlistidbox").val();
+ }
+ if (code.match(/^[a-f0-9]{10}$/i)) {
+ app.dialog.preloader("Downloading...");
+ var downloadlistdialogopen = true;
+ $.ajax({
+ url: SETTINGS.sharelistapi,
+ dataType: 'json',
+ method: 'get',
+ data: {
+ uuid: code
+ },
+ timeout: 15 * 1000,
+ success: function (resp) {
+ if (downloadlistdialogopen) {
+ app.dialog.close();
+ downloadlistdialogopen = false;
+ }
+ if (resp.status == "OK") {
+ var skipped = importPackageList(resp.packages);
+ if (skipped > 0) {
+ app.dialog.alert("List imported and merged with the existing one. " + skipped + " items already existed locally and were skipped. Verify their delivery status manually.", "Import Complete");
+ } else {
+ app.dialog.alert("List imported and merged with the existing one.", "Import Complete");
+ }
+ } else {
+ app.dialog.alert(resp.message, "Error");
+ }
+ },
+ error: function (jqXHR, status, errorThrown) {
+ if (downloadlistdialogopen) {
+ app.dialog.close();
+ downloadlistdialogopen = false;
+ }
+ app.dialog.alert("There was a network or server issue while downloading the list. Please try again.", "Error");
+ }
+ });
+ } else {
+ app.dialog.alert("That's not a valid list ID.", "Error");
+ }
+}
+
+function scanListIDBarcode() {
+ scanBarcode(function (code) {
+ playSound("scan");
+ downloadItemList(code);
+ }, function (error) {
+ app.dialog.alert(error, "Error");
+ });
+}
\ No newline at end of file
diff --git a/www/pages/toolbox.html b/www/pages/toolbox.html
index 626b905..0ab5660 100644
--- a/www/pages/toolbox.html
+++ b/www/pages/toolbox.html
@@ -43,6 +43,14 @@
+
+
+
+
+
+
diff --git a/www/pages/toolbox/sharelist.html b/www/pages/toolbox/sharelist.html
new file mode 100644
index 0000000..d1c064e
--- /dev/null
+++ b/www/pages/toolbox/sharelist.html
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+ info
+
+ 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.
+
+
+
+
+
\ No newline at end of file
diff --git a/www/routes.js b/www/routes.js
index 37ffd3d..6b23b91 100644
--- a/www/routes.js
+++ b/www/routes.js
@@ -161,6 +161,11 @@ var routes = [
loadWeather();
}
}
+ },
+ {
+ path: '/sharelist',
+ url: './pages/toolbox/sharelist.html',
+ name: 'sharelist'
}
]
},
diff --git a/www/settings.js b/www/settings.js
index 1763e93..b8e14f3 100644
--- a/www/settings.js
+++ b/www/settings.js
@@ -300,5 +300,6 @@ var SETTINGS = {
geocodeapi: "https://apis.netsyms.net/packagehelper/geocode.php",
trackingapi: "https://apis.netsyms.net/packagehelper/track.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"
}