« get me outta code hell

Separate jump-to-item/search logic from UI code - mtui - Music Text User Interface - user-friendly command line music player
about summary refs log tree commit diff
path: root/playlist-utils.js
diff options
context:
space:
mode:
authorFlorrie <towerofnix@gmail.com>2019-07-16 12:08:40 -0300
committerFlorrie <towerofnix@gmail.com>2019-07-16 12:08:40 -0300
commitfa36c81f256a7b357cc64b42129a119d3c98b056 (patch)
tree01574e4145ee140f27b21d97ab816e6ac0356594 /playlist-utils.js
parentcddda96a4622225caee1e889524876c02ab97c87 (diff)
Separate jump-to-item/search logic from UI code
Diffstat (limited to 'playlist-utils.js')
-rw-r--r--playlist-utils.js41
1 files changed, 41 insertions, 0 deletions
diff --git a/playlist-utils.js b/playlist-utils.js
index d679ad7..e6d8947 100644
--- a/playlist-utils.js
+++ b/playlist-utils.js
@@ -574,6 +574,46 @@ function isTrack(obj) {
   return !!(obj && obj.downloaderArg)
 }
 
+function searchForItem(grouplike, value, preferredStartIndex = -1) {
+  if (value.length) {
+    // We prioritize searching past the index that the user opened the jump
+    // element from (oldFocusedIndex). This is so that it's more practical
+    // to do a "repeated" search, wherein the user searches for the same
+    // value over and over, each time jumping to the next match, until they
+    // have found the one they're looking for.
+
+    const lower = value.toLowerCase()
+    const getName = item => (item && item.name) ? item.name.toLowerCase().trim() : ''
+
+    const testStartsWith = item => getName(item).startsWith(lower)
+    const testIncludes = item => getName(item).includes(lower)
+
+    const searchPastCurrentIndex = test => {
+      const start = preferredStartIndex + 1
+      const match = grouplike.items.slice(start).findIndex(test)
+      if (match === -1) {
+        return -1
+      } else {
+        return start + match
+      }
+    }
+
+    const allIndexes = [
+      searchPastCurrentIndex(testStartsWith),
+      searchPastCurrentIndex(testIncludes),
+      grouplike.items.findIndex(testStartsWith),
+      grouplike.items.findIndex(testIncludes)
+    ]
+
+    const matchedIndex = allIndexes.find(value => value >= 0)
+    if (typeof matchedIndex !== 'undefined') {
+      return grouplike.items[matchedIndex]
+    }
+  }
+
+  return null
+}
+
 module.exports = {
   parentSymbol,
   updatePlaylistFormat, updateGroupFormat, updateTrackFormat,
@@ -590,5 +630,6 @@ module.exports = {
   parsePathString,
   getTrackIndexInParent,
   getNameWithoutTrackNumber,
+  searchForItem,
   isGroup, isTrack
 }