aboutsummaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rwxr-xr-xweb/cobrands/fixmystreet/images/192.pngbin0 -> 6327 bytes
-rwxr-xr-xweb/cobrands/fixmystreet/images/512.pngbin0 -> 20416 bytes
-rw-r--r--web/cobrands/fixmystreet/offline.js400
3 files changed, 175 insertions, 225 deletions
diff --git a/web/cobrands/fixmystreet/images/192.png b/web/cobrands/fixmystreet/images/192.png
new file mode 100755
index 000000000..e43a3bb37
--- /dev/null
+++ b/web/cobrands/fixmystreet/images/192.png
Binary files differ
diff --git a/web/cobrands/fixmystreet/images/512.png b/web/cobrands/fixmystreet/images/512.png
new file mode 100755
index 000000000..13cf165d3
--- /dev/null
+++ b/web/cobrands/fixmystreet/images/512.png
Binary files differ
diff --git a/web/cobrands/fixmystreet/offline.js b/web/cobrands/fixmystreet/offline.js
index 4d7c471aa..908326a69 100644
--- a/web/cobrands/fixmystreet/offline.js
+++ b/web/cobrands/fixmystreet/offline.js
@@ -8,8 +8,7 @@ fixmystreet.offlineBanner = (function() {
}
// Note this non-global way of handling plurals may need looking at in future
- function formText() {
- var num = fixmystreet.offlineData.getForms().length;
+ function formText(num) {
if ( num === 1 ) {
return num + ' ' + translation_strings.offline.update_single;
} else {
@@ -17,12 +16,12 @@ fixmystreet.offlineBanner = (function() {
}
}
- function onlineText() {
- return sprintf(translation_strings.offline.saved_to_submit, formText());
+ function onlineText(num) {
+ return sprintf(translation_strings.offline.saved_to_submit, formText(num));
}
- function offlineText() {
- return translation_strings.offline.you_are_offline + ' \u2013 ' + sprintf(translation_strings.offline.N_saved, formText());
+ function offlineText(num) {
+ return translation_strings.offline.you_are_offline + ' \u2013 ' + sprintf(translation_strings.offline.N_saved, formText(num));
}
function remove() {
@@ -31,24 +30,29 @@ fixmystreet.offlineBanner = (function() {
return {
make: function(offline) {
- var num = fixmystreet.offlineData.getForms().length;
- var banner = ['<div class="top_banner top_banner--offline"><p><span id="offline_saving"></span> <span id="offline_forms">'];
- if (offline || num > 0) {
- banner.push(offline ? offlineText() : onlineText());
- }
- banner.push('</span></p></div>');
- banner = $(banner.join(''));
- banner.prependTo('.content');
- if (num === 0) {
- banner.hide();
- }
+ fixmystreet.offlineData.getFormsLength().then(function(num) {
+ var banner = ['<div class="top_banner top_banner--offline"><p><span id="offline_saving"></span> <span id="offline_forms">'];
+ if (offline || num > 0) {
+ banner.push(offline ? offlineText(num) : onlineText(num));
+ }
+ banner.push('</span></p></div>');
+ banner = $(banner.join(''));
+ banner.prependTo('.content');
+ if (num === 0) {
+ banner.hide();
+ }
+ });
window.addEventListener("offline", function(e) {
- $('#offline_forms').html(offlineText());
+ fixmystreet.offlineData.getFormsLength().then(function(num) {
+ $('#offline_forms').html(offlineText(num));
+ });
});
window.addEventListener("online", function(e) {
- $('#offline_forms').html(onlineText());
+ fixmystreet.offlineData.getFormsLength().then(function(num) {
+ $('#offline_forms').html(onlineText(num));
+ });
});
function nextForm(DataOrJqXHR, textStatus, jqXHROrErrorThrown) {
@@ -62,37 +66,40 @@ fixmystreet.offlineBanner = (function() {
$(document).on('click', '#oFN', function(e) {
e.preventDefault();
- fixmystreet.offlineData.getForms().forEach(function(form) {
- $(document).queue('postForm', function() {
- postForm(form[0], form[1]).fail(function(jqXHR) {
- if (jqXHR.status !== 400) {
- return nextForm();
- }
- // In case the request failed due to out-of-date CSRF token,
- // try once more with a new token given in the error response.
- var m = jqXHR.responseText.match(/content="([^"]*)" name="csrf-token"/);
- if (!m) {
- return nextForm();
- }
- var token = m[1];
- if (!token) {
- return nextForm();
- }
- var param = form[1].replace(/&token=[^&]*/, '&token=' + token);
- return postForm(form[0], param).fail(nextForm);
+ fixmystreet.offlineData.getForms().then(function(forms) {
+ forms.forEach(function(form) {
+ $(document).queue('postForm', function() {
+ postForm(form[0], form[1]).fail(function(jqXHR) {
+ if (jqXHR.status !== 400) {
+ return nextForm();
+ }
+ // In case the request failed due to out-of-date CSRF token,
+ // try once more with a new token given in the error response.
+ var m = jqXHR.responseText.match(/content="([^"]*)" name="csrf-token"/);
+ if (!m) {
+ return nextForm();
+ }
+ var token = m[1];
+ if (!token) {
+ return nextForm();
+ }
+ var param = form[1].replace(/&token=[^&]*/, '&token=' + token);
+ return postForm(form[0], param).fail(nextForm);
+ });
});
});
+ $(document).dequeue('postForm');
});
- $(document).dequeue('postForm');
});
},
update: function() {
$('.top_banner--offline').slideDown();
- $('#offline_forms span').text(formText());
- var num = fixmystreet.offlineData.getForms().length;
- if (num === 0) {
- window.setTimeout(remove, 3000);
- }
+ fixmystreet.offlineData.getFormsLength().then(function(num) {
+ $('#offline_forms span').text(formText(num));
+ if (num === 0) {
+ window.setTimeout(remove, 3000);
+ }
+ });
},
startProgress: function(l) {
$('.top_banner--offline').slideDown();
@@ -115,61 +122,55 @@ fixmystreet.offlineData = (function() {
var data;
function getData() {
- if (data === undefined) {
- data = JSON.parse(localStorage.getItem('offlineData'));
- if (!data) {
- data = { cachedReports: {}, forms: [] };
- }
+ if (data !== undefined) {
+ return Promise.resolve(data);
}
- return data;
+ return idbKeyval.get('offlineData').then(function(d) {
+ data = d || { cachedReports: {}, forms: [] };
+ return data;
+ });
}
- function saveData() {
- localStorage.setItem('offlineData', JSON.stringify(getData()));
+ function updateData(cb) {
+ getData().then(function(data) {
+ cb(data);
+ idbKeyval.set('offlineData', data);
+ });
}
return {
- getForms: function() {
- return getData().forms;
+ getFormsLength: function() {
+ return getData().then(function(data) { return data.forms.length; });
},
- addForm: function(action, formData) {
- var forms = getData().forms;
- if (!forms.length || formData != forms[forms.length - 1][1]) {
- forms.push([action, formData]);
- saveData();
- }
- fixmystreet.offlineBanner.update();
+ getForms: function() {
+ return getData().then(function(data) { return data.forms; });
},
shiftForm: function(idx) {
- getData().forms.shift();
- saveData();
- fixmystreet.offlineBanner.update();
+ updateData(function(data) {
+ data.forms.shift();
+ fixmystreet.offlineBanner.update();
+ });
},
clearForms: function(idx) {
- getData().forms = [];
- saveData();
- fixmystreet.offlineBanner.update();
+ updateData(function(data) {
+ data.forms = [];
+ fixmystreet.offlineBanner.update();
+ });
},
- getCachedUrls: function() {
- return Object.keys(getData().cachedReports);
- },
- isIndexed: function(url, lastupdate) {
- if (lastupdate) {
- return getData().cachedReports[url] === lastupdate;
- }
- return !!getData().cachedReports[url];
+ getCachedReports: function() {
+ return getData().then(function(data) { return data.cachedReports; });
},
add: function(url, lastupdate) {
- var data = getData();
- data.cachedReports[url] = lastupdate || "-";
- saveData();
+ updateData(function(data) {
+ data.cachedReports[url] = lastupdate || "-";
+ });
},
remove: function(urls) {
- var data = getData();
- urls.forEach(function(url) {
- delete data.cachedReports[url];
+ updateData(function(data) {
+ urls.forEach(function(url) {
+ delete data.cachedReports[url];
+ });
});
- saveData();
}
};
})();
@@ -177,57 +178,39 @@ fixmystreet.offlineData = (function() {
fixmystreet.cachet = (function(){
var urlsInProgress = {};
- function cacheURL(url, type) {
+ function cacheURL(url) {
urlsInProgress[url] = 1;
-
- var ret;
- if (type === 'image') {
- ret = $.Deferred(function(deferred) {
- var oReq = new XMLHttpRequest();
- oReq.open("GET", url, true);
- oReq.responseType = "blob";
- oReq.onload = function(oEvent) {
- var blob = oReq.response;
- var reader = new window.FileReader();
- reader.readAsDataURL(blob);
- reader.onloadend = function() {
- localStorage.setItem(url, reader.result);
+ return caches.open('pages').then(function(cache) {
+ return fetch(url).then(function(response) {
+ if (response.ok) {
+ cache.put(url, response.clone()).then(function() {
delete urlsInProgress[url];
- deferred.resolve(blob);
- };
- };
- oReq.send();
- });
- } else {
- ret = $.ajax(url).pipe(function(content, textStatus, jqXHR) {
- localStorage.setItem(url, content);
- delete urlsInProgress[url];
- return content;
+ });
+ }
+ return response;
});
- }
- return ret;
+ });
}
function cacheReport(item) {
- return cacheURL(item.url, 'html').pipe(function(html) {
+ return cacheURL(item.url).then(function(response) {
+ return response.text();
+ }).then(function(html) {
var $reportPage = $(html);
var imagesToGet = [
item.url + '/map' // Static map image
];
$reportPage.find('img').each(function(i, img) {
- if (img.src.indexOf('/photo/') === -1 || fixmystreet.offlineData.isIndexed(img.src) || urlsInProgress[img.src]) {
+ if (img.src.indexOf('/photo/') === -1 || urlsInProgress[img.src]) {
return;
}
imagesToGet.push(img.src);
imagesToGet.push(img.src.replace('.jpeg', '.fp.jpeg'));
});
var imagePromises = imagesToGet.map(function(url) {
- return cacheURL(url, 'image');
+ return cacheURL(url);
});
- return $.when.apply(undefined, imagePromises).pipe(function() {
- fixmystreet.offlineBanner.progress();
- fixmystreet.offlineData.add(item.url, item.lastupdate);
- }, function() {
+ return Promise.all(imagePromises).finally(function() {
fixmystreet.offlineBanner.progress();
fixmystreet.offlineData.add(item.url, item.lastupdate);
});
@@ -241,7 +224,7 @@ fixmystreet.cachet = (function(){
var promises = items.map(function(item) {
return cacheReport(item);
});
- return $.when.apply(undefined, promises);
+ return Promise.all(promises);
}
return {
@@ -265,130 +248,101 @@ fixmystreet.offline = (function() {
var toRemove = [];
var shouldBeCached = {};
- localStorage.setItem('/my/planned', $('.item-list').html());
+ idbKeyval.set('/my/planned', $('.item-list').html());
- getReportsFromList().forEach(function(item, i) {
- if (!fixmystreet.offlineData.isIndexed(item.url, item.lastupdate)) {
- toCache.push(item);
- }
- shouldBeCached[item.url] = 1;
- });
+ fixmystreet.offlineData.getCachedReports().then(function(reports) {
+ getReportsFromList().forEach(function(item, i) {
+ var t = reports[item.url];
+ if (t !== item.lastupdate) {
+ toCache.push(item);
+ }
+ shouldBeCached[item.url] = 1;
+ });
+
+ Object.keys(reports).forEach(function(url) {
+ if ( !shouldBeCached[url] ) {
+ toRemove.push(url);
+ }
+ });
- fixmystreet.offlineData.getCachedUrls().forEach(function(url) {
- if ( !shouldBeCached[url] ) {
- toRemove.push(url);
+ if (toRemove[0]) {
+ removeReports(toRemove);
+ }
+ if (toCache[0]) {
+ fixmystreet.cachet.cacheReports(toCache);
}
});
-
- if (toRemove[0]) {
- removeReports(toRemove);
- }
- if (toCache[0]) {
- fixmystreet.cachet.cacheReports(toCache);
- }
}
// Remove a list of reports from the offline cache
function removeReports(urls) {
- var pathsRemoved = [];
- urls.forEach(function(url) {
- var html = localStorage.getItem(url);
- var $reportPage = $(html);
- localStorage.removeItem(url + '/map');
- $reportPage.find('img').each(function(i, img) {
- if (img.src.indexOf('/photo/') === -1) {
- return;
- }
- localStorage.removeItem(img.src);
- localStorage.removeItem(img.src.replace('.jpeg', '.fp.jpeg'));
+ caches.open('pages').then(function(cache) {
+ urls.forEach(function(url) {
+ fetch(url).then(function(response) {
+ return response.text();
+ }).then(function(html) {
+ var $reportPage = $(html);
+ cache.delete(url + '/map');
+ $reportPage.find('img').each(function(i, img) {
+ if (img.src.indexOf('/photo/') === -1) {
+ return;
+ }
+ cache.delete(img.src);
+ cache.delete(img.src.replace('.jpeg', '.fp.jpeg'));
+ });
+ cache.delete(url);
+ });
});
- localStorage.removeItem(url);
+ fixmystreet.offlineData.remove(urls);
});
- fixmystreet.offlineData.remove(urls);
}
- function showReportFromCache(url) {
- var html = localStorage.getItem(url);
- if (!html) {
- return false;
- }
- var map = localStorage.getItem(url + '/map');
- var found = html.match(/<body[^>]*>[\s\S]*<\/body>/);
- document.body.outerHTML = found[0];
- $('#map_box').html('<img src="' + map + '">').css({ textAlign: 'center', height: 'auto' });
- replaceImages('img');
-
+ function showReportOffline(url) {
+ $('#map_box').html('<img src="' + url + '/map">').css({ textAlign: 'center', height: 'auto' });
$('.moderate-display.segmented-control, .shadow-wrap, #update_form, #report-cta, .mysoc-footer, .nav-wrapper').hide();
-
$('.js-back-to-report-list').attr('href', '/my/planned');
// Refill form with saved data if there is any
- var savedForm;
- fixmystreet.offlineData.getForms().forEach(function(form) {
- if (form[0].endsWith(url)) {
- savedForm = form[1];
- }
- });
- if (savedForm) {
- savedForm.replace(/\+/g, '%20').split('&').forEach(function(kv) {
- kv = kv.split('=', 2);
- if (kv[0] != 'include_update' && kv[0] != 'public_update' && kv[0] != 'save') {
- $('[name=' + kv[0] + ']').val(decodeURIComponent(kv[1]));
+ fixmystreet.offlineData.getForms().then(function(forms) {
+ var savedForm;
+ forms.forEach(function(form) {
+ if (form[0].endsWith(url)) {
+ savedForm = form[1];
}
});
- }
-
- // If we catch the form submit, e.g. Chrome still seems to
- // try and submit and we get the Chrome offline error page
- var btn = $('#report_inspect_form input[type=submit]');
- btn.click(function() {
- var form = $(this).closest('form');
- var data = form.serialize() + '&save=1&saved_at=' + Math.floor(+new Date() / 1000);
- fixmystreet.offlineData.addForm(form.attr('action'), data);
- location.href = '/my/planned?saved=1';
- return false;
- });
- btn[0].type = 'button';
-
- return true;
- }
-
- function replaceImages(selector) {
- $(selector).each(function(i, img) {
- if (img.src.indexOf('/photo/') > -1) {
- var dataImg = localStorage.getItem(img.src);
- if (dataImg) {
- img.src = dataImg;
- }
+ if (savedForm) {
+ savedForm.replace(/\+/g, '%20').split('&').forEach(function(kv) {
+ kv = kv.split('=', 2);
+ if (kv[0] != 'include_update' && kv[0] != 'public_update' && kv[0] != 'save') {
+ $('[name=' + kv[0] + ']').val(decodeURIComponent(kv[1]));
+ }
+ });
}
});
}
return {
- replaceImages: replaceImages,
- showReportFromCache: showReportFromCache,
+ showReportOffline: showReportOffline,
removeReports: removeReports,
updateCachedReports: updateCachedReports
};
})();
+if (!navigator.onLine && location.pathname.indexOf('/report') === 0) {
+ fixmystreet.offline.showReportOffline(location.pathname);
+}
+
if ($('#offline_list').length) {
// We are OFFLINE
- var success = false;
- if (location.pathname.indexOf('/report') === 0) {
- success = fixmystreet.offline.showReportFromCache(location.pathname);
- }
- if (!success) {
- var html = localStorage.getItem('/my/planned');
- if (html) {
- $('#offline_list').before('<h2>'+translation_strings.offline.your_reports+'</h2>');
- $('#offline_list').html(html);
- if (location.search.indexOf('saved=1') > 0) {
- $('#offline_list').before('<p class="form-success">'+translation_strings.offline.update_saved+'</p>');
- }
- fixmystreet.offline.replaceImages('#offline_list img');
- var offlineForms = fixmystreet.offlineData.getForms();
+ idbKeyval.get('/my/planned').then(function(html) {
+ if (!html) { return; }
+ $('#offline_list').before('<h2>'+translation_strings.offline.your_reports+'</h2>');
+ $('#offline_list').html(html);
+ if (location.search.indexOf('saved=1') > 0) {
+ $('#offline_list').before('<p class="form-success">'+translation_strings.offline.update_saved+'</p>');
+ }
+ fixmystreet.offlineData.getForms().then(function(offlineForms) {
var savedForms = {};
offlineForms.forEach(function(form) {
savedForms[form[0]] = 1;
@@ -398,25 +352,21 @@ if ($('#offline_list').length) {
$(this).find('h3').prepend('<em>'+translation_strings.offline.update_data_saved+'</em> ');
}
});
- $('#offline_clear').css('margin-top', '5em').html('<button id="js-clear-localStorage">'+translation_strings.offline.clear_data+'</button>');
- $('#js-clear-localStorage').click(function() {
- if (window.confirm(translation_strings.offline.are_you_sure)) {
- fixmystreet.offline.removeReports(fixmystreet.offlineData.getCachedUrls());
- fixmystreet.offlineData.clearForms();
- localStorage.removeItem('/my/planned');
- alert(translation_strings.offline.data_cleared);
- }
- });
- }
- }
+ });
+ $('#offline_clear').css('margin-top', '5em').html('<button id="js-clear-storage">'+translation_strings.offline.clear_data+'</button>');
+ $('#js-clear-storage').click(function() {
+ if (window.confirm(translation_strings.offline.are_you_sure)) {
+ fixmystreet.offlineData.getCachedReports().then(function(reports) {
+ fixmystreet.offline.removeReports(Object.keys(reports));
+ });
+ fixmystreet.offlineData.clearForms();
+ idbKeyval.del('/my/planned');
+ alert(translation_strings.offline.data_cleared);
+ }
+ });
+ });
fixmystreet.offlineBanner.make(true);
} else {
- // Put the appcache manifest in a page in an iframe so that HTML pages
- // aren't cached (thanks to Jake Archibald for documenting this!)
- if (window.applicationCache && window.localStorage) {
- $(document.body).prepend('<iframe src="/offline/appcache" style="position:absolute;top:-999em;visibility:hidden"></iframe>');
- }
-
fixmystreet.offlineBanner.make(false);
// On /my/planned, when online, cache all shortlisted