Munzee Map Filters

New way of catagorized filters

当前为 2021-10-25 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Munzee Map Filters
  3. // @namespace http://tampermonkey.net/
  4. // @version 21.10.25.001
  5. // @description New way of catagorized filters
  6. // @author CzPeet
  7. // @match https://www.munzee.com/specials*
  8. // @icon https://www.google.com/s2/favicons?domain=munzee.com
  9. // @update https://greasyfork.org/en/scripts/433078-munzee-map-filters
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. var isMapLoading = false;
  14. var imgPrefix = "https://munzee.global.ssl.fastly.net/images/pins/";
  15. var filterImgsContainer = null;
  16. var filterIMGS = [];
  17.  
  18. var categoryMainImages = ["frankeinstein", "theunicorn", "retiredunicorn", "icedragon", "poseidon", "beachflatrob", "phantomflatrob", "tuli", "zombietuli", "nomad", "vikerkaar", "spyderbot", "gardengnome", "skyland10", "boxjellyfish", "fire", "quizvirtual"];
  19. var categorizedFilterOrder = ["Seasonals", "Mythologicals", "RetiredMyths", "AlternaMyths", "ModernMyths", "FancyFlats", "PhantomFlats", "PouchCreations", "ZombiePouchs", "Nomads", "FunfinityStones", "MechZBouncers", "GardenGnomes", "Destinations", "EvoBouncers", "Scatters", "UnCategorized"];
  20. var categorizedFilterObject = {};
  21.  
  22. categorizedFilterObject.Seasonals = ["backstitchsisters", "dr.acula", "frankeinstein", "fabiooooooo", "h3adl3ssh0rs3man"];
  23. categorizedFilterObject.Mythologicals = ["theunicorn","hippocampunicorn","battleunicorn","candycornunicorn","leprechaun","dwarfleprechaun","goblinleprechaun","leprecorn","dragon","chinesedragon","wyverndragon","midnightdragon","yeti","reptoidyeti","lycanthropeyeti","monsteryeti","faun","centaurfaun","krampusfaun","hydra","cerberushydra","cthulhuhydra","pegasus","alicornpegasus","griffinpegasus","nightmarepegasus","cyclops","balorcyclops","minotaurcyclops","mermaid","hotspringmermaid","melusinemermaid","fairy","dryadfairy","wildfirefairy","banshee","harpybanshee","witchbanshee","nymph","elfnymph","vampirenymph"];
  24. categorizedFilterObject.RetiredMyths = ["retiredunicorn","retiredleprechaun","retireddragon","retiredyeti","retiredfaun","retiredhydra","retiredpegasus","retiredcyclops","retiredmermaid","retiredfairy","retiredbanshee","retirednymph"];
  25. categorizedFilterObject.AlternaMyths = ["cherub","chimera","fairygodmother","firepegasus","gnomeleprechaun","gorgon","icedragon","motherearth","ogre","rainbowunicorn","sasquatchyeti","siren"];
  26. categorizedFilterObject.ModernMyths = ["aphrodite","glasses","shell-phone","poseidon","trident","lifebuoy","hades","bident","firestarter"];
  27. categorizedFilterObject.FancyFlats = ["beachflatrob","coldflatrob","tuxflatrob","face-offflatmatt","footyflatmatt","matt'erupflatmatt","internationellesflatlou","polkadotflatlou","teamgbflatlou"];
  28. categorizedFilterObject.PhantomFlats = ["phantomflatrob", "phantomflatmatt", "phantomflatlou"];
  29. categorizedFilterObject.PouchCreations = ["tuli","tuliferno","tulimber","gleamingtuli","gleamingtuliferno","gleamingtulimber","vesi","vesial","vesisaur","gleamingvesi","gleamingvesial","gleamingvesisaur","muru","muruchi","murutain","gleamingmuru","gleamingmuruchi","gleamingmurutain","mitmegu","jootmegu","lokemegu","rohimegu","murinmegu","ohkmegu","urgasmegu","koobas","kartus","kabuhirm","pimedus","puffle","puflawn","pufrain","magnetus","elekjoud","elekter","elektrivool","hadavale"];
  30. categorizedFilterObject.ZombiePouchs = ["zombietuli","zombievesi","zombiemuru","zombiepimedus","zombiepuffle","zombiemagnetus","zombieelekter"];
  31. categorizedFilterObject.Nomads = ["nomad","nomadvirtual","nomadmystery","jewelthiefnomad","bellhopnomad","piratenomad","warriornomad","travelernomad","seasonalnomad","virtualflatnomad","coupechampionnomad","virtualzeecretagentnomad","zeecretagentnomad","virtualgamingnomad","gamingnomad","virtualjewelthiefnomad","virtualwarriornomad","virtualbellhopnomad","jason4zeesnomad","killermask"];
  32. categorizedFilterObject.FunfinityStones = ["akvamariin","ametust","oniks","roosa","rubiin","safiir","smaragd","teemant","topaas","tsitriin","vikerkaar"];
  33. categorizedFilterObject.MechZBouncers = ["spyderbot","arcticlasershark","botwurst","carafeborg","cybersaurusrex","cyborgsanta","dronut","fr057y","geologgersrumbot","gingermechman","goldenlasershark","goldncoinsrumbot","kingc0g","lasershark","mechanic4k3","monk3y","mumm33","negsrumbot","prim8","rud01ph","s4rc0ph4gus","sc4rab","scgsrumbot","steinbot","krampbot","31f","reindroid"];
  34. categorizedFilterObject.GardenGnomes = ["gardengnome","archerygardengnome","gnomearcheryhood","astronautgardengnome","gnomeastronauthelmet","aussieexplorergardengnome","gnomeexplorerhat","awardshowgardengnome","10thmunzeebirthdayhat","baseballgardengnome","gnomecatcherscap","basketballgardengnome","gnomenogginnet","cricketgardengnome","gnomeclubcap","footballgardengnome","gnometouchdowntopper","goldminergardengnome","gnomeminerhat","icehockeygardengnome","gnomehockeyhelmet","queen'sguardsmangardengnome","gnomebearskinhat","runninggardengnome","gnomeheadphones","skateboardinggardengnome","gnomeheelfliphat","soccergardengnome","gnomeheaderhat","cyclinggardengnome","cyclingcasquette"];
  35. categorizedFilterObject.Destinations = ["skyland1","skyland2","skyland3","skyland4","skyland5","skyland6","skyland7","skyland8","skyland9","skyland10","treehouse1","treehouse2","treehouse3","treehouse4","treehouse5","treehouse6","treehouse7","treehouse8","treehouse9","treehouse10"];
  36. categorizedFilterObject.EvoBouncers = ["boxjellyfish","goldenjellyfish","pb&jellyfish","limebutterfly","monarchbutterfly","morphobutterfly","poisondartfrog","tomatofrog","treefrog","seaturtle","snappingturtle","taekwondotortoise","honeybee","queenbee","wallabee"];
  37. categorizedFilterObject.Scatters = ["fire","frozengreenie","waterdroplet","feather","goldenfeather","charge","tree","redapple","cherryblossom","peach","pear","pecan","acorn","deadbranch","cardinalfeather","blackhole","planet","spaceship","lostkey","lostsock","meteor","satellite","scattered","boulder","flamingarrow","sc4rab","ankhartifact","ouroborosartifact","djedartifact","scarabartifact","eyeofraartifact","shenartifact","canopicjarartifact","sesenartifact","wasscepterartifact","sistrumartifact","sistrumartifact","tyetartifact","eyeofhorusartifact","sweettreats","scgsresellerpackage","geologgersresellerpackage","gold'ncoinsresellerpackage","negsresellerpackage","cloverleaf","goldenclover","snowball","dossier","infraredvirtual","lasertrail1","lasertrail2","lasertrail3","pixelpresent","undercoveragent","liaisonagent","maplepawn","mapleknight","maplebishop","maplerook","maplequeen","mapleking","walnutpawn","walnutknight","walnutbishop","walnutrook","walnutqueen","walnutking","leapfrog","munch-man","runzeerob","goldcoin","fly","ghostzee","1stroll","bowling-1stroll","2ndroll","bowling-2ndroll","trickortreat","flamingpumpkin"];
  38. categorizedFilterObject.UnCategorized = [];
  39.  
  40. var disabledFilterImgs = [];
  41.  
  42. function sleep(ms) {
  43. return new Promise(resolve => setTimeout(resolve, ms));
  44. }
  45.  
  46. async function restructureImages() {
  47.  
  48. //Wait until the progressbar is hidden
  49. if ($("#map-box-special-loading").is(':visible'))
  50. {
  51. return;
  52. }
  53.  
  54. //remove original filter_all button
  55. $('#filter_all').remove();
  56.  
  57. filterImgsContainer = $('#filterimgs');
  58. filterImgsContainer[0].addEventListener('mouseleave', deactivateFilterImages);
  59.  
  60. //Filters label removed
  61. filterImgsContainer.prev().remove();
  62.  
  63. //Collect original filter images
  64. filterIMGS = filterImgsContainer[0].getElementsByClassName('filterimg');
  65.  
  66. //Sort into Categories
  67. var filterHelper = CreateCategories();
  68.  
  69. //Reload the new layout
  70. filterImgsContainer.empty();
  71. filterImgsContainer.html(filterHelper);
  72. filterHelper = null;
  73.  
  74. //mainImages update needed after map action
  75. Array.from(document.getElementsByClassName('categoryDIV')).forEach(function(categDIV){
  76. updateMainImage(categDIV);
  77. });
  78.  
  79. //Add to all img the click eventListener
  80. Array.from(filterImgsContainer[0].getElementsByClassName('filterimg')).forEach(function(img) {
  81. img.addEventListener('click', FilterImgClick);
  82. img.setAttribute("style", "cursor:pointer");
  83. img.setAttribute("title", img.currentSrc.substring(img.currentSrc.lastIndexOf("/")+1,img.currentSrc.lastIndexOf(".")));
  84. });
  85.  
  86. //all mainImages stuffs
  87. Array.from(filterImgsContainer[0].getElementsByClassName('mainImage')).forEach(function(mainIMG){
  88. mainIMG.setAttribute("style", "border: solid grey 1px; width:63px; padding-right:3px; padding-top:3px; cursor:pointer");
  89. mainIMG.addEventListener('mouseover', activateFilterImages);
  90. mainIMG.addEventListener('click', mainImageClick);
  91. });
  92.  
  93. //all categoryDIVs stuff
  94. Array.from(filterImgsContainer[0].getElementsByClassName('categoryDIV')).forEach(function(cDIV){
  95. cDIV.setAttribute("style", "display: none; border: solid grey 1px; padding-top: 5px; padding-bottom: 5px; width: 100%");
  96. cDIV.addEventListener('mouseleave', deactivateFilterImages);
  97. });
  98.  
  99. //refresh
  100. refreshMap();
  101. }
  102.  
  103. function CreateCategories()
  104. {
  105. //Div
  106. var mainImageDIV = document.createElement('DIV');
  107. mainImageDIV.setAttribute("id", "mainImageDIV");
  108.  
  109. var categName = "" ;
  110. var filterStructure = "";
  111. for (var o = 0; o<categorizedFilterOrder.length; o++)
  112. {
  113. categName = categorizedFilterOrder[o];
  114. var array = categorizedFilterObject[categName];
  115.  
  116. //Div
  117. var categDIV = document.createElement('DIV');
  118. categDIV.setAttribute("id", categName+"_Category");
  119. categDIV.setAttribute("class", "categoryDIV");
  120.  
  121. var addedAtLeatOne = false;
  122.  
  123. if (array.length > 0)
  124. {
  125. for (let a = 0; a < array.length; a++)
  126. {
  127. for (let i = 0; i < filterIMGS.length; i++)
  128. {
  129. if (filterIMGS[i].src == imgPrefix + array[a] + ".png")
  130. {
  131. categDIV.appendChild(filterIMGS[i]);
  132. addedAtLeatOne = true;
  133. }
  134. }
  135. }
  136. }
  137. else
  138. {
  139. for (let i = filterIMGS.length-1; i >= 0; i--)
  140. {
  141. categDIV.appendChild(filterIMGS[i]);
  142. addedAtLeatOne = true;
  143. }
  144. }
  145.  
  146. if (addedAtLeatOne)
  147. {
  148. filterStructure += categDIV.outerHTML;
  149.  
  150. //main image
  151. var categMainIMG = document.createElement('IMG');
  152. categMainIMG.setAttribute("id", categName+'_MainIMG');
  153. categMainIMG.setAttribute("title", categName);
  154. categMainIMG.setAttribute("class", "mainImage");
  155. categMainIMG.src = imgPrefix + categoryMainImages[o] + ".png";
  156.  
  157. mainImageDIV.appendChild(categMainIMG);
  158. }
  159. }
  160.  
  161. //Show/Hide all main image
  162. var allOrnothingIMG = document.createElement('IMG');
  163. allOrnothingIMG.setAttribute("id", 'ALL_MainIMG');
  164. allOrnothingIMG.setAttribute("title", 'Show/Hide All Category');
  165. allOrnothingIMG.setAttribute("class", "mainImage");
  166. allOrnothingIMG.src = imgPrefix + "premium.png";
  167. mainImageDIV.appendChild(allOrnothingIMG);
  168.  
  169. filterStructure = mainImageDIV.outerHTML + filterStructure;
  170.  
  171. return filterStructure;
  172. }
  173.  
  174. function mainImageClick(sender)
  175. {
  176. //find related filterimgs
  177. var categDIV = document.getElementById(sender.target.getAttribute("title")+"_Category");
  178.  
  179. if (categDIV != null)
  180. {
  181. let imgs = categDIV.getElementsByTagName('img');
  182.  
  183. if (sender.target.classList.contains("filterdisabled"))
  184. {
  185. //Set own state
  186. sender.target.classList.remove("filterdisabled");
  187.  
  188. //Set the related filterimg states
  189. Array.from(imgs).forEach(function(img) {
  190. if (img.classList.contains("filterdisabled"))
  191. {
  192. enableFilter(img);
  193. }
  194. });
  195. }
  196. else
  197. {
  198. //Set own state
  199. sender.target.classList.add("filterdisabled");
  200.  
  201. //Set the related filterimg states
  202. Array.from(imgs).forEach(function(img) {
  203. if (!img.classList.contains("filterdisabled"))
  204. {
  205. disableFilter(img);
  206. }
  207. });
  208. }
  209. }
  210. else
  211. {
  212. let mimgs = document.getElementsByClassName('mainImage');
  213. let imgs = document.getElementsByClassName('filterimg');
  214. //Clicked on ALL button
  215. if (sender.target.classList.contains("filterdisabled"))
  216. {
  217. //Set own state
  218. sender.target.classList.remove("filterdisabled");
  219.  
  220. //Set all category states
  221. Array.from(mimgs).forEach(function(mimg) {
  222. mimg.classList.remove("filterdisabled");
  223. });
  224.  
  225. //Set all filterimg states
  226. Array.from(imgs).forEach(function(img) {
  227. if (img.classList.contains("filterdisabled"))
  228. {
  229. enableFilter(img);
  230. }
  231. });
  232. }
  233. else
  234. {
  235. //Set own state
  236. sender.target.classList.add("filterdisabled");
  237.  
  238. //Set all category states
  239. Array.from(mimgs).forEach(function(mimg) {
  240. mimg.classList.add("filterdisabled");
  241. });
  242.  
  243. //Set all filterimg states
  244. Array.from(imgs).forEach(function(img) {
  245. if (!img.classList.contains("filterdisabled"))
  246. {
  247. disableFilter(img);
  248. }
  249. });
  250. }
  251. }
  252.  
  253. refreshMap();
  254. }
  255.  
  256. function activateFilterImages(sender)
  257. {
  258. //1st - Hide all
  259. Array.from(filterImgsContainer[0].getElementsByClassName('categoryDIV')).forEach(function(cDIV){
  260. $(cDIV).hide();
  261. });
  262.  
  263. //2nd - Show the related
  264. $(document.getElementById(sender.target.getAttribute("title")+"_Category")).show();
  265. }
  266.  
  267. function deactivateFilterImages(sender)
  268. {
  269. Array.from(filterImgsContainer[0].getElementsByClassName('categoryDIV')).forEach(function(cDIV){
  270. $(cDIV).hide();
  271. });
  272. }
  273.  
  274. function FilterImgClick(sender)
  275. {
  276. if (sender.target.classList.contains("filterdisabled"))
  277. {
  278. enableFilter(sender.target);
  279. }
  280. else
  281. {
  282. disableFilter(sender.target);
  283. }
  284.  
  285. updateMainImage(sender.target.parentNode);
  286.  
  287. refreshMap();
  288. }
  289.  
  290. function updateMainImage(containerDIV)
  291. {
  292. var hide = true;
  293. var relatedMainImage = document.getElementById(containerDIV.id.replace('Category', 'MainIMG'));
  294. Array.from(containerDIV.getElementsByClassName('filterimg')).forEach(function(img){
  295. hide &= img.classList.contains("filterdisabled");
  296. });
  297.  
  298. if (hide)
  299. {
  300. relatedMainImage.classList.add("filterdisabled");
  301. }
  302. else
  303. {
  304. relatedMainImage.classList.remove("filterdisabled");
  305. }
  306. }
  307.  
  308. //Enable 1 filterimg
  309. function enableFilter(target)
  310. {
  311. target.classList.remove("filterdisabled");
  312.  
  313. var pos = disabledFilterImgs.indexOf(target.src);
  314. if (pos >= 0)
  315. {
  316. disabledFilterImgs.splice(pos, 1);
  317. }
  318. }
  319.  
  320. //Disable 1 filterimg
  321. function disableFilter(target)
  322. {
  323. target.classList.add("filterdisabled");
  324.  
  325. if (disabledFilterImgs.indexOf(target.src) < 0)
  326. {
  327. disabledFilterImgs.push(target.src);
  328. }
  329. }
  330.  
  331. function refreshMap()
  332. {
  333. for (var mID in mapMarkers)
  334. {
  335. if (disabledFilterImgs.indexOf(mapMarkers[mID].munzee_logo) == -1)
  336. {
  337. $( "[data-index='" + mID + "']" ).show();
  338. }
  339. else
  340. {
  341. $( "[data-index='" + mID + "']" ).hide();
  342. }
  343. }
  344. }
  345.  
  346. $(document).ajaxSuccess(restructureImages);