From cb90c410b5f9c327367ccb1ddfc190dfbcd083ea Mon Sep 17 00:00:00 2001 From: Viet Dinh <54ckb0y789@gmail.com> Date: Sat, 29 Aug 2026 06:06:06 -0700 Subject: [PATCH] Reversed badge order, search badges by text --- badges.js | 77 +++++++++++++++++++++++++++++++++++----------------- index.php | 8 ++++++ lang/ar.json | 3 +- lang/de.json | 3 +- lang/en.json | 3 +- lang/eo.json | 3 +- lang/es.json | 3 +- lang/fr.json | 3 +- lang/id.json | 3 +- lang/it.json | 3 +- lang/ja.json | 3 +- lang/ko.json | 3 +- lang/pl.json | 3 +- lang/pt.json | 3 +- lang/ro.json | 3 +- lang/ru.json | 3 +- lang/tr.json | 3 +- lang/uk.json | 3 +- lang/vi.json | 3 +- lang/zh.json | 3 +- 20 files changed, 96 insertions(+), 43 deletions(-) diff --git a/badges.js b/badges.js index 63325c0c..5ccc12c9 100644 --- a/badges.js +++ b/badges.js @@ -15,6 +15,7 @@ @property {boolean} [unlocked] @property {boolean} hidden @property {boolean} [secret] + @property {boolean} [secretCondition] @property {number} originalOrder */ @@ -202,7 +203,7 @@ function initBadgeControls() { return -1; return 1; } - return a.originalOrder - b.originalOrder; + return sortOrderDesc ? b.originalOrder - a.originalOrder : a.originalOrder - b.originalOrder; }; // If we already have cache and it hasn't been invalidated, only update the modal. @@ -566,6 +567,14 @@ function initBadgeControls() { exactMatch = true; } + function isMatch(haystack, needle, exact) { + if (!haystack) return false; + if (exact) { + return haystack.localeCompare(needle, undefined, { sensitivity: 'base', usage: 'search' }) === 0; + } + return haystack.toLocaleLowerCase().indexOf(needle) > -1; + } + const gameVisibilities = {}; const gameGroupVisibilities = {}; @@ -579,9 +588,10 @@ function initBadgeControls() { visible &= item.el.classList.contains('locked') === !parseInt(unlockStatus); if (searchTerm.trim().length) { switch (searchMode) { - case 'name': + case 'name': { visible &= item.title && (exactMatch ? item.title === parsedSearchTerm : item.title.indexOf(parsedSearchTerm) > -1); break; + } case 'location': { const localizedLocation = gameLocalizedMapLocations[item.game]?.[item.mapId]; let title = determineTitle(localizedLocation, item.mapX, item.mapY); @@ -596,13 +606,22 @@ function initBadgeControls() { title = globalConfig.lang === 'ja' ? desc.titleJP : desc.title; } } - visible &= title && (exactMatch ? title.toLocaleLowerCase() === parsedSearchTerm : title.toLocaleLowerCase().indexOf(parsedSearchTerm) > -1); + visible &= isMatch(title, parsedSearchTerm, exactMatch); break; } case 'artist': { visible &= item.art && (exactMatch ? item.art.split(/ & |, /).includes(parsedSearchTerm) : item.art.indexOf(parsedSearchTerm) > -1); break; } + case 'contents': { + const gameBadgeLocalizations = localizedBadges && localizedBadges[item.game]; + const badgeLocalization = gameBadgeLocalizations && gameBadgeLocalizations[item.badgeId]; + visible &= badgeLocalization && ( + (item.unlocked || !item.secret) && isMatch(badgeLocalization.description, parsedSearchTerm, exactMatch) + || (item.unlocked || !item.secretCondition) && isMatch(badgeLocalization.condition, parsedSearchTerm, exactMatch) + ); + break; + } } } if (!(item.game in gameVisibilities)) { @@ -638,29 +657,30 @@ function initBadgeControls() { return; } + let parsedValue = this.value; + let modifier = null; + if (parsedValue.startsWith('=')) { + parsedValue = parsedValue.slice(1); + modifier = 'exactMatch'; + } + let value = parsedValue; + if (modifier) + value += localizedMessages.badges.search.modifier.template.replace('{MODIFIER}', localizedMessages.badges.search.modifier[modifier]); + + // mappings for user input sanitization + const map = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + "/": '/', + }; + const reg = /[&<>"'/]/ig; + value = value.replace(reg, match => map[match]); + for (const span of badgeDropdown.querySelectorAll('.dropdownItem span')) { - let parsedValue = this.value; - let modifier = null; - if (parsedValue.startsWith('=')) { - parsedValue = parsedValue.slice(1); - modifier = 'exactMatch'; - } - let value = parsedValue; - if (modifier) - value += localizedMessages.badges.search.modifier.template.replace('{MODIFIER}', localizedMessages.badges.search.modifier[modifier]); - - // mappings for user input sanitization - const map = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - "/": '/', - }; - - const reg = /[&<>"'/]/ig; - span.innerHTML = value.replace(reg, (match)=>(map[match])); + span.innerHTML = value; } }; @@ -703,6 +723,9 @@ function initBadgeControls() { const searchArtist = document.getElementById('searchArtist').parentElement; onDropdownActivate(searchArtist, () => searchBadges('artist')); + const searchContents = document.getElementById('searchContents').parentElement; + onDropdownActivate(searchContents, () => searchBadges('contents')); + function searchBadges(mode) { badgeDropdown.classList.add('hidden'); updateBadgeVisibility(mode); @@ -1083,6 +1106,10 @@ function getBadgeItem(badge, includeTooltip, emptyIcon, lockedIcon, scaled, filt percent: badge.percent, badgeId: badge.badgeId, art: '', + originalOrder: badge.originalOrder, + unlocked: badge.unlocked, + secret: badge.secret, + secretCondition: badge.secretCondition, }; item.dataset.cacheIndex = badgeFilterCache.push(filterItem) - 1; } diff --git a/index.php b/index.php index fce75fcd..022feb73 100644 --- a/index.php +++ b/index.php @@ -1080,6 +1080,7 @@ class="joystickBase" />