diff --git a/plugins/keys-on-map.user.js b/plugins/keys-on-map.user.js index 43aa1338..6b1bc160 100644 --- a/plugins/keys-on-map.user.js +++ b/plugins/keys-on-map.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @id iitc-plugin-keys-on-map@xelio // @name IITC plugin: Keys on map -// @version 0.2.0.@@DATETIMEVERSION@@ +// @version 0.2.1.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ @@ -55,6 +55,13 @@ window.plugin.keysOnMap.keyUpdate = function(data) { plugin.keysOnMap.renderKey(data.guid, latLng) } +window.plugin.keysOnMap.refreshAllKeys = function() { + plugin.keysOnMap.keyLayerGroup.clearLayers(); + $.each(plugin.keys.keys, function(key, count) { + plugin.keysOnMap.keyUpdate({guid: key}); + }); +} + window.plugin.keysOnMap.renderKey = function(guid,latLng) { plugin.keysOnMap.removeKey(guid); @@ -117,9 +124,12 @@ var setup = function() { // Avoid error if this plugin load first if($.inArray('pluginKeysUpdateKey', window.VALID_HOOKS) < 0) window.VALID_HOOKS.push('pluginKeysUpdateKey'); + if($.inArray('pluginKeysRefreshAll', window.VALID_HOOKS) < 0) + window.VALID_HOOKS.push('pluginKeysRefreshAll'); window.addHook('portalAdded', window.plugin.keysOnMap.portalAdded); window.addHook('pluginKeysUpdateKey', window.plugin.keysOnMap.keyUpdate); + window.addHook('pluginKeysRefreshAll', window.plugin.keysOnMap.refreshAllKeys); } // PLUGIN END ////////////////////////////////////////////////////////// diff --git a/plugins/keys.user.js b/plugins/keys.user.js index 465c2e31..7c0c210c 100644 --- a/plugins/keys.user.js +++ b/plugins/keys.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @id iitc-plugin-keys@xelio // @name IITC plugin: Keys -// @version 0.1.0.@@DATETIMEVERSION@@ +// @version 0.2.0.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ @@ -22,11 +22,23 @@ if(typeof window.plugin !== 'function') window.plugin = function() {}; // use own namespace for plugin window.plugin.keys = function() {}; +// delay in ms +window.plugin.keys.SYNC_DELAY = 10000; + window.plugin.keys.LOCAL_STORAGE_KEY = 'plugin-keys-data'; +window.plugin.keys.KEY = {key: 'plugin-keys-data', field: 'keys'}; +window.plugin.keys.UPDATE_QUEUE = {key: 'plugin-keys-data-queue', field: 'updateQueue'}; +window.plugin.keys.UPDATING_QUEUE = {key: 'plugin-keys-data-updating-queue', field: 'updatingQueue'}; + window.plugin.keys.keys = {}; -window.plugin.keys.disabledMessage; -window.plugin.keys.contentHTML; +window.plugin.keys.updateQueue = {}; +window.plugin.keys.updatingQueue = {}; + +window.plugin.keys.enableSync = false; + +window.plugin.keys.disabledMessage = null; +window.plugin.keys.contentHTML = null; window.plugin.keys.addToSidebar = function() { if(typeof(Storage) === "undefined") { @@ -51,26 +63,102 @@ window.plugin.keys.addKey = function(addCount) { if(oldCount !== newCount) { if(newCount === 0) { delete plugin.keys.keys[guid]; + plugin.keys.updateQueue[guid] = null; } else { plugin.keys.keys[guid] = newCount; + plugin.keys.updateQueue[guid] = newCount; } - plugin.keys.storeKeys(); + + plugin.keys.storeLocal(plugin.keys.KEY); + plugin.keys.storeLocal(plugin.keys.UPDATE_QUEUE); plugin.keys.updateDisplayCount(); window.runHooks('pluginKeysUpdateKey', {guid: guid, count: newCount}); + plugin.keys.delaySync(); } } -window.plugin.keys.storeKeys = function() { - var keysObject = {keys: plugin.keys.keys}; - var keysObjectJSON = JSON.stringify(keysObject); - localStorage[plugin.keys.LOCAL_STORAGE_KEY] = keysObjectJSON; +// Delay the syncing to group a few updates in a single request +window.plugin.keys.delaySync = function() { + if(!plugin.keys.enableSync) return; + clearTimeout(plugin.keys.delaySync.timer); + plugin.keys.delaySync.timer = setTimeout(function() { + plugin.keys.delaySync.timer = null; + window.plugin.keys.syncNow(); + }, plugin.keys.SYNC_DELAY); } +window.plugin.keys.syncNow = function() { + if(!plugin.keys.enableSync) return; + $.extend(plugin.keys.updatingQueue, plugin.keys.updateQueue); + plugin.keys.updateQueue = {}; + plugin.keys.storeLocal(plugin.keys.UPDATING_QUEUE); + plugin.keys.storeLocal(plugin.keys.UPDATE_QUEUE); + + plugin.sync.updateMap('keys', 'keys', Object.keys(plugin.keys.updatingQueue)); +} + +// Called after IITC and all plugin loaded +window.plugin.keys.registerFieldForSyncing = function() { + if(!window.plugin.sync) return; + window.plugin.sync.registerMapForSync('keys', 'keys', window.plugin.keys.syncCallback, window.plugin.keys.syncInitialed); +} + +window.plugin.keys.syncCallback = function(pluginName, fieldName, e, fullUpdated) { + if(fieldName === 'keys') { + plugin.keys.storeLocal(plugin.keys.KEY); + if(fullUpdated) { + plugin.keys.updateDisplayCount(); + window.runHooks('pluginKeysRefreshAll'); + } + + if(!e) return; + if(e.isLocal) { + // Update pushed successfully, remove it from updatingQueue + delete plugin.keys.updatingQueue[e.property]; + } else { + // Remote update + delete plugin.keys.updateQueue[e.property]; + plugin.keys.storeLocal(plugin.keys.UPDATE_QUEUE); + plugin.keys.updateDisplayCount(); + window.runHooks('pluginKeysUpdateKey', {guid: e.property, count: plugin.keys.keys[e.property]}); + } + } +} + +// syncing of the field is initialed +window.plugin.keys.syncInitialed = function(pluginName, fieldName) { + if(fieldName === 'keys') { + plugin.keys.enableSync = true; + if(Object.keys(plugin.keys.updateQueue).length > 0) { + plugin.keys.delaySync(); + } + } +} + +window.plugin.keys.storeLocal = function(mapping) { + if(typeof(plugin.keys[mapping.field]) !== 'undefined' && plugin.keys[mapping.field] !== null) { + localStorage[mapping.key] = JSON.stringify(plugin.keys[mapping.field]); + } else { + localStorage.removeItem(mapping.key); + } +} + +window.plugin.keys.loadLocal = function(mapping) { + var objectJSON = localStorage[mapping.key]; + if(!objectJSON) return; + plugin.keys[mapping.field] = mapping.convertFunc + ? mapping.convertFunc(JSON.parse(objectJSON)) + : JSON.parse(objectJSON); +} + +// For backward compitable, will change to use loadLocal after a few version window.plugin.keys.loadKeys = function() { - var keysObjectJSON = localStorage[plugin.keys.LOCAL_STORAGE_KEY]; + var keysObjectJSON = localStorage[plugin.keys.KEY.key]; if(!keysObjectJSON) return; var keysObject = JSON.parse(keysObjectJSON); - plugin.keys.keys = keysObject.keys; + // Move keys data up one level, it was {keys: keys_data} in localstorage in previous version + plugin.keys.keys = keysObject.keys ? keysObject.keys : keysObject; + if(keysObject.keys) plugin.keys.storeLocal(plugin.keys.KEY); } window.plugin.keys.setupCSS = function() { @@ -102,11 +190,15 @@ window.plugin.keys.setupContent = function() { var setup = function() { if($.inArray('pluginKeysUpdateKey', window.VALID_HOOKS) < 0) window.VALID_HOOKS.push('pluginKeysUpdateKey'); + if($.inArray('pluginKeysRefreshAll', window.VALID_HOOKS) < 0) + window.VALID_HOOKS.push('pluginKeysRefreshAll'); window.plugin.keys.setupCSS(); window.plugin.keys.setupContent(); + window.plugin.keys.loadLocal(plugin.keys.UPDATE_QUEUE); window.plugin.keys.loadKeys(); window.addHook('portalDetailsUpdated', window.plugin.keys.addToSidebar); + window.addHook('iitcLoaded', window.plugin.keys.registerFieldForSyncing); } // PLUGIN END //////////////////////////////////////////////////////////