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.
550 lines
22 KiB
JavaScript
550 lines
22 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 trackingcoderegex = /^[0-9a-zA-Z]{5,40}$/;
|
|
|
|
function openTrackingInfoPage(code) {
|
|
if (typeof code == "undefined" || code == null || code.trim() == "") {
|
|
app.input.validate("#trackingcode");
|
|
app.toast.show({
|
|
text: "Please enter a tracking code.",
|
|
position: "bottom",
|
|
closeTimeout: 2000
|
|
});
|
|
return;
|
|
}
|
|
|
|
router.navigate("/track/" + code);
|
|
}
|
|
|
|
function addTrackingSuggestions() {
|
|
$("#tracking-history-list ul").html("");
|
|
$("#tracking-history-list-empty").addClass("display-none");
|
|
$("#tracking-history-list .list").removeClass("display-none");
|
|
var history = getTrackingHistory();
|
|
if (history == false || history.length == 0) {
|
|
$("#tracking-history-list-empty").removeClass("display-none");
|
|
$("#tracking-history-list .list").addClass("display-none");
|
|
} else {
|
|
for (var i = history.length - 1; i >= 0; i--) {
|
|
$("#tracking-history-list ul").append('<li><a class="item-link item-content hapticbtn tracking-code-history-link" data-trackingcode="' + history[i] + '" href="/track/' + history[i] + '">'
|
|
+ '<div class="item-inner"><div class="item-title">'
|
|
+ history[i]
|
|
+ '</div></div></a></li>');
|
|
}
|
|
}
|
|
if (inStorage("accountkey") && inStorage("accountnumber")) {
|
|
$("#tracking-account-list-empty").addClass("display-none");
|
|
$("#tracking-account-list .list").removeClass("display-none");
|
|
apirequest(SETTINGS.apis.gettrackingnumbers, {
|
|
accountnumber: getStorage("accountnumber"),
|
|
accountkey: getStorage("accountkey")
|
|
}, function (success) {
|
|
if (success.status == "OK") {
|
|
$("#tracking-account-list ul").html("");
|
|
for (var i = 0; i < success.trackingnumbers.length; i++) {
|
|
$("#tracking-account-list ul").append('<li><a class="item-link item-content hapticbtn" href="/track/' + success.trackingnumbers[i].trackingcode + '">'
|
|
+ '<div class="item-inner">'
|
|
+ '<div class="item-title">'
|
|
+ '<div class="item-header">' + success.trackingnumbers[i].nickname + '</div>'
|
|
+ success.trackingnumbers[i].trackingcode
|
|
+ '<div class="item-footer">' + success.trackingnumbers[i].datetimestring + '</div>'
|
|
+ '</div>'
|
|
+ '</div></a></li>');
|
|
}
|
|
|
|
if (success.trackingnumbers.length == 0) {
|
|
$("#tracking-account-list-empty").removeClass("display-none");
|
|
$("#tracking-account-list .list").addClass("display-none");
|
|
}
|
|
} else {
|
|
$("#tracking-account-list ul").html('<li class="item-content"><div class="item-inner justify-content-center"><div class="item-title" style="color: var(--f7-list-item-footer-text-color);">Error: ' + success.msg + '</div></div></li>');
|
|
}
|
|
}, function (xhr, status, error) {
|
|
$("#tracking-account-list ul").html('<li class="item-content"><div class="item-inner justify-content-center"><div class="item-title" style="color: var(--f7-list-item-footer-text-color);">Server or network error. Try again later.</div></div></li>');
|
|
sendErrorReport("Tracking", "Couldn't get account tracking codes", "Server/network problem: " + xhr.status + ": " + xhr.statusText);
|
|
}, "GET");
|
|
} else {
|
|
$("#tracking-account-list-empty").removeClass("display-none");
|
|
$("#tracking-account-list .list").addClass("display-none");
|
|
}
|
|
|
|
$("#tracking-multi-list-empty").addClass("display-none");
|
|
$("#tracking-multi-list .list").removeClass("display-none");
|
|
var codes = getTrackingMultiList();
|
|
if (codes.length > 0) {
|
|
$("#tracking-multi-list ul").html('<li class="item-content"><div class="item-inner justify-content-center text-align-center noselect">Loading...</div></li>');
|
|
// Only update if we're on that tab, since it's not the easiest API call for the server to do
|
|
if ($("#tracking-multi-list").hasClass("tab-active")) {
|
|
updateTrackingMultiListStatus();
|
|
}
|
|
} else {
|
|
$("#tracking-multi-list-empty").removeClass("display-none");
|
|
$("#tracking-multi-list .list").addClass("display-none");
|
|
}
|
|
}
|
|
|
|
function updateTrackingMultiListStatus() {
|
|
var codes = getTrackingMultiList();
|
|
console.log(codes.length);
|
|
$("#tracking-multi-list-empty").addClass("display-none");
|
|
$("#tracking-multi-list .list").removeClass("display-none");
|
|
$("#tracking-multi-list ul").html('<li class="item-content"><div class="item-inner justify-content-center"><div class="item-title">Loading...</div></div></li>');
|
|
if (codes.length > 0) {
|
|
$("#tracking-multi-list ul").html("");
|
|
for (var i = 0; i < codes.length; i++) {
|
|
$("#tracking-multi-list ul").append('<li><div style="cursor: pointer;" class="item-content tracking-code-multi-link noselect" data-trackingcode="' + codes[i].code + '" onclick="router.navigate(\'/track/' + codes[i].code + '\')">'
|
|
+ '<div class="item-inner item-cell">'
|
|
+ (codes[i].nick == "" ? "" : '<div class="item-row"><div class="item-cell"><b>' + codes[i].nick + '</b></div></div>')
|
|
+ '<div class="item-row"><div class="item-cell">' + codes[i].code + '</div></div>'
|
|
+ '<div class="item-row"><div class="item-cell">'
|
|
+ '<img src="" class="trackingeventicon tracking-multi-status-icon" /> <span class="tracking-multi-status-text"></span>'
|
|
+ '</div></div></div></div></li>');
|
|
}
|
|
var codelist = [];
|
|
for (var i = 0; i < codes.length; i++) {
|
|
codelist.push(codes[i].code);
|
|
}
|
|
apirequest(SETTINGS.apis.trackmultiple, {
|
|
code: codelist.join(",")
|
|
}, function (resp) {
|
|
if (resp.status == "OK") {
|
|
for (const code in resp.results) {
|
|
$(".tracking-code-multi-link[data-trackingcode=\"" + code + "\"] .tracking-multi-status-text").text(resp.results[code].text);
|
|
$(".tracking-code-multi-link[data-trackingcode=\"" + code + "\"] .tracking-multi-status-icon").attr("src", "./assets/images/icons/" + resp.results[code].icon + ".svg");
|
|
}
|
|
|
|
$("#tracking-multi-list ul").append('<li class="item-content"><div class="item-inner display-block text-align-center noselect" style="color: var(--f7-list-item-footer-text-color);"><i class="fas fa-info-circle"></i> <span class="taptext">Long-press</span><span class="clicktext">Right-click</span> an entry to remove it.</div></li>');
|
|
} else {
|
|
$("#tracking-multi-list ul").html('<li class="item-content"><div class="item-inner justify-content-center text-align-center noselect">Error: ' + resp.msg + '</div></li>');
|
|
sendErrorReport("Tracking", "Couldn't get multi tracking", resp.msg);
|
|
}
|
|
}, function (xhr) {
|
|
try {
|
|
var resp = $.parseJSON(xhr.responseText);
|
|
if (resp && typeof resp.msg != 'undefined') {
|
|
$("#tracking-multi-list ul").html('<li class="item-content"><div class="item-inner justify-content-center text-align-center">Error: ' + resp.msg + '</div></li>');
|
|
sendErrorReport("Tracking", "Couldn't get multi tracking", resp.msg);
|
|
} else {
|
|
$("#tracking-multi-list ul").html('<li class="item-content"><div class="item-inner justify-content-center text-align-center noselect">There\'s a server or network problem. Check your Internet connection or try again later.</div></li>');
|
|
sendErrorReport("Tracking", "Couldn't get multi tracking", "Server/network problem: " + xhr.status + ": " + xhr.statusText);
|
|
}
|
|
} catch (ex) {
|
|
$("#tracking-multi-list ul").html('<li class="item-content"><div class="item-inner justify-content-center text-align-center noselect">There\'s a server or network problem. Check your Internet connection or try again later.</div></li>');
|
|
sendErrorReport("Tracking", "Couldn't get multi tracking", "Server/network problem: " + xhr.status + ": " + xhr.statusText);
|
|
}
|
|
});
|
|
|
|
} else {
|
|
$("#tracking-multi-list-empty").removeClass("display-none");
|
|
$("#tracking-multi-list .list").addClass("display-none");
|
|
}
|
|
}
|
|
|
|
function openTrackingBarcodeScanner() {
|
|
scanBarcode(function (result) {
|
|
var code = "";
|
|
if (result.startsWith("https://helena.express/track#")) {
|
|
code = result.split("#")[1];
|
|
} else if (result.startsWith("http") && result.includes("#")) {
|
|
if (trackingcoderegex.test(result.split("#")[1])) {
|
|
code = result.split("#")[1];
|
|
} else {
|
|
app.dialog.alert("This app can't understand what's in that barcode.", "Error");
|
|
return;
|
|
}
|
|
} else if (trackingcoderegex.test(result)) {
|
|
code = result;
|
|
} else {
|
|
app.dialog.alert("This app can't understand what's in that barcode.", "Error");
|
|
return;
|
|
}
|
|
code = code.toUpperCase();
|
|
openTrackingInfoPage(code);
|
|
}, function () {
|
|
app.dialog.alert("Something went wrong and we can't scan right now.", "Error");
|
|
});
|
|
}
|
|
|
|
function trackOpenAsync( {to, resolve, reject}) {
|
|
app.dialog.preloader("Loading...");
|
|
|
|
apirequest(
|
|
SETTINGS.apis.track,
|
|
{
|
|
code: to.params.code,
|
|
format: "json"
|
|
},
|
|
function (resp) {
|
|
app.dialog.close();
|
|
if (resp.status == "OK") {
|
|
addToTrackingHistory(resp.code);
|
|
|
|
var context = {
|
|
code: resp.code,
|
|
info: [
|
|
{label: "Tracking Code", value: resp.code},
|
|
],
|
|
events: [],
|
|
map: {
|
|
enabled: (typeof resp.info.latitude == "number" && typeof resp.info.longitude == "number" && MapControl.supported()),
|
|
latitude: resp.info.latitude,
|
|
longitude: resp.info.longitude,
|
|
accurate: resp.info.geoaccurate,
|
|
geoiscountrylevel: (typeof resp.info.geoiscountrylevel == "undefined" ? false : resp.info.geoiscountrylevel)
|
|
}
|
|
};
|
|
if (resp.info.statustext) {
|
|
context.info.push({label: "Status", value: resp.info.statustext});
|
|
}
|
|
if (resp.info.carrier) {
|
|
if (resp.info.carrier_logo) {
|
|
context.info.push({label: "Carrier", value: "<img style=\"height: 2em; padding: 0.667em; max-width: 80%; background-color: white; border-radius: 0.25em; margin-top: 0.5em;\" src=\"" + resp.info.carrier_logo + "\" />"});
|
|
} else {
|
|
context.info.push({label: "Carrier", value: resp.info.carrier});
|
|
}
|
|
}
|
|
if (resp.info.delivery_date) {
|
|
var deliverydatelabel = "Estimated delivery on";
|
|
if (resp.info.status == "DELIVERED") {
|
|
deliverydatelabel = "Delivered on";
|
|
}
|
|
context.info.push({label: deliverydatelabel, value: formatTimestamp("F j Y", resp.info.delivery_date_unixtime)});
|
|
}
|
|
if (resp.info.carrier_tracking_url) {
|
|
context.carrierurl = resp.info.carrier_tracking_url;
|
|
}
|
|
if (resp.info.carrier_attribution) {
|
|
context.carrier_attribution = resp.info.carrier_attribution;
|
|
}
|
|
|
|
for (var i = 0; i < resp.events.length; i++) {
|
|
context.events.push({
|
|
text: resp.events[i].text,
|
|
date: resp.events[i].timestring,
|
|
icon: "./assets/images/icons/" + resp.events[i].icon + ".svg"
|
|
});
|
|
}
|
|
|
|
if (context.events.length == 0) {
|
|
context.events = false;
|
|
}
|
|
|
|
sendActionReport("Tracking", "Tracked package");
|
|
resolve({
|
|
content: compiledPages.trackresult(context)
|
|
});
|
|
} else {
|
|
app.dialog.alert(resp.msg, "Error");
|
|
sendErrorReport("Tracking", "Couldn't get tracking", resp.msg);
|
|
reject();
|
|
}
|
|
},
|
|
function (xhr) {
|
|
app.dialog.close();
|
|
try {
|
|
var error = $.parseJSON(xhr.responseText);
|
|
if (error && typeof error.msg != 'undefined') {
|
|
app.dialog.alert(error.msg, "Error");
|
|
sendErrorReport("Tracking", "Couldn't get tracking", error.msg);
|
|
} else {
|
|
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later.", "Error");
|
|
sendErrorReport("Tracking", "Couldn't get tracking", "Server/network problem: " + xhr.status + ": " + xhr.statusText);
|
|
}
|
|
} catch (ex) {
|
|
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later.", "Error");
|
|
sendErrorReport("Tracking", "Couldn't get tracking", "Server/network problem: " + xhr.status + ": " + xhr.statusText);
|
|
}
|
|
reject();
|
|
}, "GET");
|
|
}
|
|
|
|
$("#app").on("submit", "#tracking-searchbar-form", function (evt) {
|
|
evt.preventDefault();
|
|
|
|
openTrackingInfoPage($('input[name=\'trackingcode\']').val());
|
|
|
|
return false;
|
|
});
|
|
|
|
$("#app").on("contextmenu taphold", ".tracking-code-history-link", function (evt) {
|
|
evt.preventDefault();
|
|
|
|
// Don't trigger contextmenu on a touch device because we'll also get a taphold
|
|
if (evt.type == "contextmenu" && window.matchMedia("(pointer: coarse)").matches) {
|
|
return;
|
|
}
|
|
|
|
var code = $(this).data("trackingcode");
|
|
|
|
var action = app.actions.create({
|
|
buttons: [
|
|
[
|
|
{
|
|
text: 'Track',
|
|
bold: true,
|
|
onClick: function () {
|
|
openTrackingInfoPage(code);
|
|
}
|
|
},
|
|
{
|
|
text: 'Add to Multi list',
|
|
onClick: function () {
|
|
addToTrackingMultiList(code);
|
|
addTrackingSuggestions();
|
|
}
|
|
},
|
|
{
|
|
text: 'Remove From History',
|
|
onClick: function () {
|
|
removeFromTrackingHistory(code);
|
|
addTrackingSuggestions();
|
|
}
|
|
}
|
|
],
|
|
[
|
|
{
|
|
text: 'Cancel',
|
|
color: 'red'
|
|
}
|
|
]
|
|
]
|
|
});
|
|
|
|
action.open();
|
|
return false;
|
|
});
|
|
|
|
$("#app").on("contextmenu taphold", ".tracking-code-multi-link", function (evt) {
|
|
evt.preventDefault();
|
|
|
|
// Don't trigger contextmenu on a touch device because we'll also get a taphold
|
|
if (evt.type == "contextmenu" && window.matchMedia("(pointer: coarse)").matches) {
|
|
return;
|
|
}
|
|
|
|
var code = $(this).data("trackingcode");
|
|
|
|
var action = app.actions.create({
|
|
buttons: [
|
|
[
|
|
{
|
|
text: 'Open',
|
|
bold: true,
|
|
onClick: function () {
|
|
openTrackingInfoPage(code);
|
|
}
|
|
},
|
|
{
|
|
text: 'Add/Change Nickname',
|
|
onClick: function () {
|
|
app.dialog.prompt("Set a nickname for " + code, "Package Name", function (input) {
|
|
addNicknameToTrackingMultiList(code, htmlEntities(input));
|
|
updateTrackingMultiListStatus();
|
|
}, function () {
|
|
// canceled
|
|
}, "");
|
|
}
|
|
},
|
|
{
|
|
text: 'Remove from list',
|
|
onClick: function () {
|
|
removeFromTrackingMultiList(code);
|
|
addTrackingSuggestions();
|
|
}
|
|
}
|
|
],
|
|
[
|
|
{
|
|
text: 'Cancel',
|
|
color: 'red'
|
|
}
|
|
]
|
|
]
|
|
});
|
|
|
|
action.open();
|
|
return false;
|
|
});
|
|
|
|
$("#app").on("contextmenu taphold", "#brokenscannercodeadd", function (evt) {
|
|
evt.preventDefault();
|
|
|
|
// Don't trigger contextmenu on a touch device because we'll also get a taphold
|
|
if (evt.type == "contextmenu" && window.matchMedia("(pointer: coarse)").matches) {
|
|
return;
|
|
}
|
|
|
|
var code = $('input[name=\'trackingcode\']').val().trim().replace(/\s/, "");
|
|
|
|
var action = app.actions.create({
|
|
buttons: [
|
|
[
|
|
{
|
|
text: 'Track',
|
|
bold: true,
|
|
onClick: function () {
|
|
if (code == "") {
|
|
app.dialog.alert("You need to type a tracking code first.", "Error");
|
|
return;
|
|
}
|
|
openTrackingInfoPage(code);
|
|
}
|
|
},
|
|
{
|
|
text: 'Add to Multi list',
|
|
onClick: function () {
|
|
if (code == "") {
|
|
app.dialog.alert("You need to type a tracking code first.", "Error");
|
|
return;
|
|
}
|
|
if (!code.match(trackingcoderegex)) {
|
|
app.dialog.alert("That doesn't seem like a valid tracking code.", "Error");
|
|
return;
|
|
}
|
|
addToTrackingMultiList(code);
|
|
addTrackingSuggestions();
|
|
}
|
|
}
|
|
],
|
|
[
|
|
{
|
|
text: 'Cancel',
|
|
color: 'red'
|
|
}
|
|
]
|
|
]
|
|
});
|
|
|
|
action.open();
|
|
return false;
|
|
});
|
|
|
|
$("#app").on("tab:show", "#tracking-multi-list", function (evt) {
|
|
updateTrackingMultiListStatus();
|
|
});
|
|
|
|
function getTrackingHistory() {
|
|
var history = getStorage("trackinghistory");
|
|
if (history == "false" || history == "null" || history == null) {
|
|
return [];
|
|
} else {
|
|
return JSON.parse(history);
|
|
}
|
|
}
|
|
|
|
function addToTrackingHistory(code) {
|
|
var history = getTrackingHistory();
|
|
|
|
for (var i = 0; i < history.length; i++) {
|
|
if (history[i] == code) {
|
|
history.splice(i, 1);
|
|
}
|
|
}
|
|
// Add the code back to the list so it's at the top
|
|
history.push(code);
|
|
|
|
while (history.length > 10) {
|
|
history.shift();
|
|
}
|
|
setStorage("trackinghistory", JSON.stringify(history));
|
|
}
|
|
|
|
function removeFromTrackingHistory(code) {
|
|
var history = getTrackingHistory();
|
|
|
|
for (var i = 0; i < history.length; i++) {
|
|
if (history[i] == code) {
|
|
history.splice(i, 1);
|
|
}
|
|
}
|
|
|
|
while (history.length > 10) {
|
|
history.shift();
|
|
}
|
|
setStorage("trackinghistory", JSON.stringify(history));
|
|
|
|
$(".tracking-code-history-link[data-trackingcode=\"" + code + "\"]").parent("li").remove();
|
|
}
|
|
|
|
|
|
function getTrackingMultiList() {
|
|
var multilist = getStorage("multitrackingcodes");
|
|
|
|
if (multilist == "false" || multilist == "null" || multilist == null) {
|
|
return [];
|
|
} else {
|
|
var multilistjson = JSON.parse(multilist);
|
|
|
|
if (multilistjson.length > 0) {
|
|
if (typeof multilistjson[0] == "object") {
|
|
return multilistjson;
|
|
} else {
|
|
// Old version is just string array, new version is array of objects,
|
|
// do a conversion
|
|
// TODO: Remove this code once everyone's updated to this version, since it's not efficient to do typeof every time
|
|
var newmultilist = [];
|
|
for (var i = 0; i < multilistjson.length; i++) {
|
|
newmultilist.push({
|
|
code: multilistjson[i],
|
|
nick: ""
|
|
});
|
|
}
|
|
setStorage("multitrackingcodes", JSON.stringify(newmultilist));
|
|
return newmultilist;
|
|
}
|
|
} else {
|
|
return [];
|
|
}
|
|
}
|
|
}
|
|
|
|
function addToTrackingMultiList(code, nickname) {
|
|
if (typeof nickname != "string") {
|
|
nickname = "";
|
|
}
|
|
var multilist = getTrackingMultiList();
|
|
|
|
for (var i = 0; i < multilist.length; i++) {
|
|
if (multilist[i].code == code) {
|
|
// Already in list, remove so we can add with the new nick if set
|
|
multilist.splice(i, 1);
|
|
}
|
|
}
|
|
// Add the code to the list
|
|
multilist.push({
|
|
code: code,
|
|
nick: nickname
|
|
});
|
|
|
|
setStorage("multitrackingcodes", JSON.stringify(multilist));
|
|
}
|
|
|
|
function addNicknameToTrackingMultiList(code, nickname) {
|
|
var multilist = getTrackingMultiList();
|
|
|
|
for (var i = 0; i < multilist.length; i++) {
|
|
if (multilist[i].code == code) {
|
|
multilist[i].nick = nickname;
|
|
}
|
|
}
|
|
|
|
setStorage("multitrackingcodes", JSON.stringify(multilist));
|
|
}
|
|
|
|
function removeFromTrackingMultiList(code) {
|
|
var multilist = getTrackingMultiList();
|
|
|
|
for (var i = 0; i < multilist.length; i++) {
|
|
if (multilist[i].code == code) {
|
|
multilist.splice(i, 1);
|
|
}
|
|
}
|
|
|
|
setStorage("multitrackingcodes", JSON.stringify(multilist));
|
|
|
|
$(".tracking-code-multi-link[data-trackingcode=\"" + code + "\"]").parent("li").remove();
|
|
} |