summaryrefslogtreecommitdiff
path: root/raveos-hyprland-theme/theme-data/dms/Modals/DankLauncherV2/Scorer.js
diff options
context:
space:
mode:
authorNippy <nippy@rp1.hu>2026-05-08 19:50:49 +0200
committerNippy <nippy@rp1.hu>2026-05-08 19:50:49 +0200
commit3462bcc46ecf74f576ea4397f16492c16bd75b10 (patch)
treec5ab7aef4498647e057bda8d49c11e5f9dda74c9 /raveos-hyprland-theme/theme-data/dms/Modals/DankLauncherV2/Scorer.js
parent56616f693b4f263cbf0d47da43b67424efa6022d (diff)
downloadRaveOS-PKGBUILD-3462bcc46ecf74f576ea4397f16492c16bd75b10.tar.gz
RaveOS-PKGBUILD-3462bcc46ecf74f576ea4397f16492c16bd75b10.zip
raveos update
Diffstat (limited to 'raveos-hyprland-theme/theme-data/dms/Modals/DankLauncherV2/Scorer.js')
-rw-r--r--raveos-hyprland-theme/theme-data/dms/Modals/DankLauncherV2/Scorer.js265
1 files changed, 265 insertions, 0 deletions
diff --git a/raveos-hyprland-theme/theme-data/dms/Modals/DankLauncherV2/Scorer.js b/raveos-hyprland-theme/theme-data/dms/Modals/DankLauncherV2/Scorer.js
new file mode 100644
index 0000000..7d54df7
--- /dev/null
+++ b/raveos-hyprland-theme/theme-data/dms/Modals/DankLauncherV2/Scorer.js
@@ -0,0 +1,265 @@
+.pragma library
+
+const Weights = {
+ exactMatch: 10000,
+ prefixMatch: 5000,
+ wordBoundary: 3000,
+ substring: 500,
+ fuzzy: 100,
+ frecency: 2000,
+ typeBonus: {
+ app: 1000,
+ plugin: 900,
+ file: 800,
+ action: 600
+ }
+}
+
+function tokenize(text) {
+ return text.toLowerCase().trim().split(/[\s\-_]+/).filter(function (w) { return w.length > 0 })
+}
+
+function hasWordBoundaryMatch(text, query) {
+ var textWords = tokenize(text)
+ var queryWords = tokenize(query)
+
+ if (queryWords.length === 0) return false
+ if (queryWords.length > textWords.length) return false
+
+ for (var i = 0; i <= textWords.length - queryWords.length; i++) {
+ var allMatch = true
+ for (var j = 0; j < queryWords.length; j++) {
+ if (!textWords[i + j].startsWith(queryWords[j])) {
+ allMatch = false
+ break
+ }
+ }
+ if (allMatch) return true
+ }
+ return false
+}
+
+function levenshteinDistance(s1, s2) {
+ var len1 = s1.length
+ var len2 = s2.length
+ var prev = new Array(len2 + 1)
+ var curr = new Array(len2 + 1)
+
+ for (var j = 0; j <= len2; j++)
+ prev[j] = j
+
+ for (var i = 1; i <= len1; i++) {
+ curr[0] = i
+ for (var j = 1; j <= len2; j++) {
+ var cost = s1[i - 1] === s2[j - 1] ? 0 : 1
+ curr[j] = Math.min(prev[j] + 1, curr[j - 1] + 1, prev[j - 1] + cost)
+ }
+ var tmp = prev
+ prev = curr
+ curr = tmp
+ }
+ return prev[len2]
+}
+
+function fuzzyScore(text, query) {
+ var maxDistance = query.length === 3 ? 1 : query.length <= 6 ? 2 : 3
+ var bestScore = 0
+
+ if (Math.abs(text.length - query.length) <= maxDistance) {
+ var distance = levenshteinDistance(text, query)
+ if (distance <= maxDistance) {
+ var maxLen = Math.max(text.length, query.length)
+ bestScore = 1 - (distance / maxLen)
+ }
+ }
+
+ var words = tokenize(text)
+ for (var i = 0; i < words.length && bestScore < 0.8; i++) {
+ if (Math.abs(words[i].length - query.length) > maxDistance) continue
+ var wordDistance = levenshteinDistance(words[i], query)
+ if (wordDistance <= maxDistance) {
+ var wordMaxLen = Math.max(words[i].length, query.length)
+ var score = 1 - (wordDistance / wordMaxLen)
+ bestScore = Math.max(bestScore, score)
+ }
+ }
+
+ return bestScore
+}
+
+function getTimeBucketWeight(daysSinceUsed) {
+ for (var i = 0; i < TimeBuckets.length; i++) {
+ if (daysSinceUsed <= TimeBuckets[i].maxDays) {
+ return TimeBuckets[i].weight
+ }
+ }
+ return 10
+}
+
+function calculateTextScore(name, query) {
+ if (name === query) return Weights.exactMatch
+ if (name.startsWith(query)) return Weights.prefixMatch
+ if (hasWordBoundaryMatch(name, query)) return Weights.wordBoundary
+ if (name.includes(query)) return Weights.substring
+
+ if (query.length >= 3) {
+ var fs = fuzzyScore(name, query)
+ if (fs > 0) return fs * Weights.fuzzy
+ }
+
+ return 0
+}
+
+function score(item, query, frecencyData) {
+ var typeBonus = Weights.typeBonus[item.type] || 0
+
+ if (!query || query.length === 0) {
+ var usageCount = frecencyData ? frecencyData.usageCount : 0
+ return typeBonus + (usageCount * 100)
+ }
+
+ var name = (item.name || "").toLowerCase()
+ var q = query.toLowerCase()
+
+ var textScore = calculateTextScore(name, q)
+
+ if (textScore === 0 && item.subtitle) {
+ var subtitleScore = calculateTextScore(item.subtitle.toLowerCase(), q)
+ textScore = subtitleScore * 0.5
+ }
+
+ if (textScore === 0 && item.keywords) {
+ for (var i = 0; i < item.keywords.length; i++) {
+ var keywordScore = calculateTextScore(item.keywords[i].toLowerCase(), q)
+ if (keywordScore > 0) {
+ textScore = keywordScore * 0.3
+ break
+ }
+ }
+ }
+
+ if (textScore === 0) return 0
+
+ var usageBonus = frecencyData ? Math.min(frecencyData.usageCount * 50, Weights.frecency) : 0
+
+ return textScore + usageBonus + typeBonus
+}
+
+function scoreItems(items, query, getFrecencyFn) {
+ var scored = []
+
+ for (var i = 0; i < items.length; i++) {
+ var item = items[i]
+ var itemScore
+
+ if (item._preScored !== undefined && (query || item._preScored > 900)) {
+ itemScore = item._preScored
+ } else {
+ var frecencyData = getFrecencyFn ? getFrecencyFn(item) : null
+ itemScore = score(item, query, frecencyData)
+ }
+
+ if (itemScore > 0 || !query || query.length === 0) {
+ scored.push({
+ item: item,
+ score: itemScore
+ })
+ }
+ }
+
+ scored.sort(function (a, b) {
+ return b.score - a.score
+ })
+
+ return scored
+}
+
+function groupBySection(scoredItems, sectionOrder, sortAlphabetically, maxPerSection) {
+ var sections = {}
+ var result = []
+ var limit = maxPerSection || 50
+
+ for (var i = 0; i < sectionOrder.length; i++) {
+ var sectionId = sectionOrder[i].id
+ sections[sectionId] = {
+ id: sectionId,
+ title: sectionOrder[i].title,
+ icon: sectionOrder[i].icon,
+ priority: sectionOrder[i].priority,
+ items: [],
+ collapsed: false,
+ flatStartIndex: 0
+ }
+ }
+
+ for (var i = 0; i < scoredItems.length; i++) {
+ var scoredItem = scoredItems[i]
+ var item = scoredItem.item
+ var sectionId = item.section || "apps"
+
+ if (sections[sectionId] && sections[sectionId].items.length < limit) {
+ sections[sectionId].items.push(item)
+ } else if (sections["apps"] && sections["apps"].items.length < limit) {
+ sections["apps"].items.push(item)
+ }
+ }
+
+ for (var i = 0; i < sectionOrder.length; i++) {
+ var section = sections[sectionOrder[i].id]
+ if (section && section.items.length > 0) {
+ if (sortAlphabetically && section.id === "apps") {
+ section.items.sort(function (a, b) {
+ return (a.name || "").localeCompare(b.name || "")
+ })
+ }
+ result.push(section)
+ }
+ }
+
+ return result
+}
+
+function flattenSections(sections) {
+ var flat = []
+ flat._sectionBounds = null
+ var bounds = {}
+
+ for (var i = 0; i < sections.length; i++) {
+ var section = sections[i]
+
+ flat.push({
+ isHeader: true,
+ section: section,
+ sectionId: section.id,
+ sectionIndex: i
+ })
+
+ var itemStart = flat.length
+ section.flatStartIndex = itemStart
+
+ if (!section.collapsed) {
+ for (var j = 0; j < section.items.length; j++) {
+ flat.push({
+ isHeader: false,
+ item: section.items[j],
+ sectionId: section.id,
+ sectionIndex: i,
+ indexInSection: j
+ })
+ }
+ }
+
+ var itemEnd = flat.length - 1
+ var itemCount = flat.length - itemStart
+ if (itemCount > 0) {
+ bounds[section.id] = {
+ start: itemStart,
+ end: itemEnd,
+ count: itemCount
+ }
+ }
+ }
+
+ flat._sectionBounds = bounds
+ return flat
+}