« 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
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
parentcddda96a4622225caee1e889524876c02ab97c87 (diff)
Separate jump-to-item/search logic from UI code
-rw-r--r--playlist-utils.js41
-rw-r--r--ui.js52
2 files changed, 56 insertions, 37 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
 }
diff --git a/ui.js b/ui.js
index 7cc55e2..c8d5363 100644
--- a/ui.js
+++ b/ui.js
@@ -20,6 +20,7 @@ const {
   isGroup,
   isTrack,
   parentSymbol,
+  searchForItem,
   shuffleOrderOfGroups
 } = require('./playlist-utils')
 
@@ -1289,46 +1290,23 @@ class GrouplikeListingElement extends Form {
       value = this.previousJumpValue
     }
 
-    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 grouplike = {items: this.form.inputs.map(inp => inp.item)}
 
-      const lower = value.toLowerCase()
-      const getName = inp => (inp.item && inp.item.name) ? inp.item.name.toLowerCase().trim() : ''
+    // 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 preferredStartIndex = this.oldFocusedIndex
 
-      const testStartsWith = inp => getName(inp).startsWith(lower)
-      const testIncludes = inp => getName(inp).includes(lower)
+    const item = searchForItem(grouplike, value, preferredStartIndex)
 
-      const searchPastCurrentIndex = test => {
-        const start = this.oldFocusedIndex + 1
-        const match = this.form.inputs.slice(start).findIndex(test)
-        if (match === -1) {
-          return -1
-        } else {
-          return start + match
-        }
-      }
-
-      const start = this.oldFocusedIndex
-      const allIndexes = [
-        searchPastCurrentIndex(testStartsWith),
-        searchPastCurrentIndex(testIncludes),
-        this.form.inputs.findIndex(testStartsWith),
-        this.form.inputs.findIndex(testIncludes)
-      ]
-
-      const matchedIndex = allIndexes.find(value => value >= 0)
-
-      if (typeof matchedIndex !== 'undefined') {
-        this.form.curIndex = matchedIndex
-        this.form.scrollSelectedElementIntoView()
-      } else {
-        // TODO: Feedback that the search failed.. right now we just close the
-        // jump-to menu, which might not be right.
-      }
+    if (item) {
+      this.form.curIndex = this.form.inputs.findIndex(inp => inp.item === item)
+      this.form.scrollSelectedElementIntoView()
+    } else {
+      // TODO: Feedback that the search failed.. right now we just close the
+      // jump-to menu, which might not be right.
     }
 
     if (isConfirm) {