[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:
		| @@ -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,28 +584,37 @@ 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() { | ||||||
| @@ -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]) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user