[missions] support for sync \o/

(API for hooks had to change again. Only the mission ID or combined mission/waypoint ID is now passed)
This commit is contained in:
fkloft 2015-04-14 02:29:07 +02:00
parent 12f54e3582
commit 0b852cd09a

View File

@ -79,6 +79,9 @@ window.plugin.missions = {
// 3 weeks. // 3 weeks.
portalMissionsCacheTime: 21 * 24 * 3600 * 1E3, portalMissionsCacheTime: 21 * 24 * 3600 * 1E3,
SYNC_DELAY: 5000,
enableSync: false,
missionTypeImages: [ missionTypeImages: [
'@@INCLUDEIMAGE:images/mission-type-unknown.png@@', '@@INCLUDEIMAGE:images/mission-type-unknown.png@@',
'@@INCLUDEIMAGE:images/mission-type-sequential.png@@', '@@INCLUDEIMAGE:images/mission-type-sequential.png@@',
@ -231,7 +234,7 @@ window.plugin.missions = {
time: Date.now(), time: Date.now(),
data: missions data: missions
}; };
me.saveData(); me.storeCache();
callback(missions); callback(missions);
}, function(error) { }, function(error) {
console.log('Error loading portal missions', arguments); console.log('Error loading portal missions', arguments);
@ -265,7 +268,7 @@ window.plugin.missions = {
time: Date.now(), time: Date.now(),
data: mission data: mission
}; };
me.saveData(); me.storeCache();
callback(mission); callback(mission);
}, function() { }, function() {
@ -499,16 +502,17 @@ window.plugin.missions = {
else else
this.checkedWaypoints[mwpid] = true; this.checkedWaypoints[mwpid] = true;
window.runHooks('plugin-missions-waypoint-changed', { mission: this.getMissionCache(mid), waypointguid: wpid }); window.runHooks('plugin-missions-waypoint-changed', { mwpid: mwpid, });
if (!dontsave) { if (!dontsave) {
this.saveData(); this.checkedWaypointsUpdateQueue[mwpid] = true;
this.storeLocal('checkedWaypoints');
this.storeLocal('checkedWaypointsUpdateQueue');
this.syncQueue();
} }
}, },
onWaypointChanged: function(data) { onWaypointChanged: function(data) {
var mid = data.mission.guid; var mwpid = data.mwpid;
var wpid = data.wpid;
var mwpid = mid + '-' + wpid;
var checked = !!this.checkedWaypoints[mwpid]; var checked = !!this.checkedWaypoints[mwpid];
@ -524,22 +528,20 @@ window.plugin.missions = {
}, },
toggleMission: function(mid) { toggleMission: function(mid) {
var mission = this.getMissionCache(mid);
if (!mission) {
return;
}
if(this.checkedMissions[mid]) if(this.checkedMissions[mid])
delete this.checkedMissions[mid]; delete this.checkedMissions[mid];
else else
this.checkedMissions[mid] = true; this.checkedMissions[mid] = true;
window.runHooks('plugin-missions-mission-changed', { mission: this.getMissionCache(mid) }); window.runHooks('plugin-missions-mission-changed', { mid: mid, });
this.saveData(); this.checkedMissionsUpdateQueue[mid] = true;
this.storeLocal('checkedMissions');
this.storeLocal('checkedMissionsUpdateQueue');
this.syncQueue();
}, },
onMissionChanged: function(data) { onMissionChanged: function(data) {
var mid = data.mission.guid; var mid = data.mid;
var checked = !!this.checkedMissions[mid]; var checked = !!this.checkedMissions[mid];
@ -582,30 +584,39 @@ window.plugin.missions = {
return null; return null;
}, },
saveData: function() { storeCache: function() {
this.checkCacheSize(); this.checkCacheSize();
localStorage['plugins-missions-portalcache'] = JSON.stringify(this.cacheByPortalGuid); localStorage['plugins-missions-portalcache'] = JSON.stringify(this.cacheByPortalGuid);
localStorage['plugins-missions-missioncache'] = JSON.stringify(this.cacheByMissionGuid); localStorage['plugins-missions-missioncache'] = JSON.stringify(this.cacheByMissionGuid);
localStorage['plugins-missions-checkedMissions'] = JSON.stringify(this.checkedMissions);
localStorage['plugins-missions-checkedWaypoints'] = JSON.stringify(this.checkedWaypoints);
}, },
storeLocal: function(key) {
localStorage['plugins-missions-' + key] = JSON.stringify(this[key]);
},
loadData: function() { loadData: function() {
this.cacheByPortalGuid = JSON.parse(localStorage['plugins-missions-portalcache'] || '{}'); this.cacheByPortalGuid = JSON.parse(localStorage['plugins-missions-portalcache'] || '{}');
this.cacheByMissionGuid = JSON.parse(localStorage['plugins-missions-missioncache'] || '{}'); this.cacheByMissionGuid = JSON.parse(localStorage['plugins-missions-missioncache'] || '{}');
if("plugins-missions-checkedMissions" in localStorage) { if("plugins-missions-settings" in localStorage) {
this.checkedMissions = JSON.parse(localStorage['plugins-missions-checkedMissions'] || '{}');
this.checkedWaypoints = JSON.parse(localStorage['plugins-missions-checkedWaypoints'] || '{}');
} else if("plugins-missions-settings" in localStorage) {
var settings = JSON.parse(localStorage['plugins-missions-settings'] || '{}'); var settings = JSON.parse(localStorage['plugins-missions-settings'] || '{}');
this.checkedMissions = settings.checkedMissions; localStorage['plugins-missions-checkedMissions'] = JSON.stringify(settings.checkedMissions);
this.checkedWaypoints = settings.checkedWaypoints; localStorage['plugins-missions-checkedWaypoints'] = JSON.stringify(settings.checkedWaypoints);
this.saveData();
delete localStorage['plugins-missions-settings']; delete localStorage['plugins-missions-settings'];
} }
this.loadLocal('checkedMissions');
this.loadLocal('checkedMissionsUpdateQueue');
this.loadLocal('checkedMissionsUpdatingQueue');
this.loadLocal('checkedWaypoints');
this.loadLocal('checkedWaypointsUpdateQueue');
this.loadLocal('checkedWaypointsUpdatingQueue');
}, },
loadLocal: function(key) {
this[key] = JSON.parse(localStorage['plugins-missions-' + key] || '{}');
},
checkCacheSize: function() { checkCacheSize: function() {
if (JSON.stringify(this.cacheByPortalGuid).length > 1e6) { // 1 MB not MiB ;) if (JSON.stringify(this.cacheByPortalGuid).length > 1e6) { // 1 MB not MiB ;)
this.cleanupPortalCache(); this.cleanupPortalCache();
@ -721,6 +732,76 @@ window.plugin.missions = {
} }
}, },
// sync the queue, but delay the actual sync to group a few updates in a single request
syncQueue: function() {
if(!this.enableSync) return;
clearTimeout(this.syncTimer);
this.syncTimer = setTimeout(function() {
this.syncTimer = null;
$.extend(this.checkedMissionsUpdatingQueue, this.checkedMissionsUpdateQueue);
this.checkedMissionsUpdateQueue = {};
this.storeLocal('checkedMissionsUpdatingQueue');
this.storeLocal('checkedMissionsUpdateQueue');
plugin.sync.updateMap('missions', 'checkedMissions', Object.keys(this.checkedMissionsUpdatingQueue));
$.extend(this.checkedWaypointsUpdatingQueue, this.checkedWaypointsUpdateQueue);
this.checkedWaypointsUpdateQueue = {};
this.storeLocal('checkedWaypointsUpdatingQueue');
this.storeLocal('checkedWaypointsUpdateQueue');
plugin.sync.updateMap('missions', 'checkedWaypoints', Object.keys(this.checkedWaypointsUpdatingQueue));
}.bind(this), this.SYNC_DELAY);
},
// called after IITC and all plugin loaded
registerFieldForSyncing: function() {
if(!window.plugin.sync) return;
window.plugin.sync.registerMapForSync('missions', 'checkedMissions', this.syncCallback.bind(this), this.syncInitialed.bind(this));
window.plugin.sync.registerMapForSync('missions', 'checkedWaypoints', this.syncCallback.bind(this), this.syncInitialed.bind(this));
},
// called after local or remote change uploaded
syncCallback: function(pluginName, fieldName, e, fullUpdated) {
this.storeLocal(fieldName);
// All data is replaced if another client updates the data while this client was offline,
// fire a complete refresh
if(fullUpdated) {
if(fieldName === 'checkedMissions') {
window.runHooks('plugin-missions-missions-refreshed');
} else if(fieldName === 'checkedWaypoints') {
window.runHooks('plugin-missions-waypoints-refreshed');
}
return;
}
if(!e) return;
if(e.isLocal) {
// Update pushed successfully, remove it from updatingQueue
delete this[fieldName + 'UpdatingQueue'][e.property];
} else {
// Remote update
delete this[fieldName + 'UpdateQueue'][e.property]
this.storeLocal(fieldName + 'UpdateQueue');
if(fieldName === 'checkedMissions') {
window.runHooks('plugin-missions-mission-changed', { mid: e.property, });
} else if(fieldName === 'checkedWaypoints') {
window.runHooks('plugin-missions-waypoint-changed', { mwpid: e.property, });
}
}
},
// syncing of the field is initialed, upload all queued update
syncInitialed: function(pluginName, fieldName) {
this.enableSync = true;
if(Object.keys(this[fieldName + 'UpdateQueue']).length > 0) {
this.syncQueue();
}
},
setup: function() { setup: function() {
this.cacheByPortalGuid = {}; this.cacheByPortalGuid = {};
this.cacheByMissionGuid = {}; this.cacheByMissionGuid = {};
@ -730,13 +811,6 @@ window.plugin.missions = {
this.loadData(); this.loadData();
if (!this.checkedWaypoints) {
this.checkedWaypoints = {};
}
if (!this.checkedMissions) {
this.checkedMissions = {};
}
$('<style>').prop('type', 'text/css').html('@@INCLUDESTRING:plugins/missions.css@@').appendTo('head'); $('<style>').prop('type', 'text/css').html('@@INCLUDESTRING:plugins/missions.css@@').appendTo('head');
$('#toolbox').append('<a tabindex="0" onclick="plugin.missions.openTopMissions();">Missions in view</a>'); $('#toolbox').append('<a tabindex="0" onclick="plugin.missions.openTopMissions();">Missions in view</a>');
@ -784,6 +858,7 @@ window.plugin.missions = {
window.addHook('plugin-missions-missions-refreshed', this.onMissionsRefreshed.bind(this)); window.addHook('plugin-missions-missions-refreshed', this.onMissionsRefreshed.bind(this));
window.addHook('plugin-missions-waypoint-changed', this.onWaypointChanged.bind(this)); window.addHook('plugin-missions-waypoint-changed', this.onWaypointChanged.bind(this));
window.addHook('plugin-missions-waypoints-refreshed', this.onWaypointsRefreshed.bind(this)); window.addHook('plugin-missions-waypoints-refreshed', this.onWaypointsRefreshed.bind(this));
window.addHook('iitcLoaded', this.registerFieldForSyncing.bind(this));
var match = location.pathname.match(/\/mission\/([0-9a-z.]+)/); var match = location.pathname.match(/\/mission\/([0-9a-z.]+)/);
if(match && match[1]) { if(match && match[1]) {