« get me outta code hell

mtui - Music Text User Interface - user-friendly command line music player
about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--todo.txt6
-rw-r--r--ui.js64
2 files changed, 59 insertions, 11 deletions
diff --git a/todo.txt b/todo.txt
index e7a2e31..f41609b 100644
--- a/todo.txt
+++ b/todo.txt
@@ -595,3 +595,9 @@ TODO: Some kind of timestamp indicator in the progress bar area??? E.g, name
       progress bar itself?
 
 TODO: Timestamp editing within mtui itself?????????
+
+TODO: Automatically expand/collapse timestamp lists in the queue sidebar!
+
+TODO: Apparently, seeking to a timestamp under a previous track in the queue
+      doesn't respect the current queue order (i.e. it sticks the track after
+      the current track). Definitely a bug!
diff --git a/ui.js b/ui.js
index 3601071..0383807 100644
--- a/ui.js
+++ b/ui.js
@@ -1138,11 +1138,18 @@ class AppElement extends FocusElement {
       .filter(line => !line.startsWith('#'))
       .filter(line => line)
 
+    const metadata = this.backend.getMetadataFor(item)
+    const duration = (metadata ? metadata.duration : Infinity)
+
     const data = lines
       .map(line => line.match(/^\s*([0-9:]+)\s*(\S.*)\s*$/))
       .filter(match => match)
       .map(match => ({timestamp: getSecFromTimestamp(match[1]), comment: match[2]}))
       .filter(({ timestamp: sec }) => !isNaN(sec))
+      .map((cur, i, arr) =>
+        (i + 1 === arr.length
+          ? {...cur, timestampEnd: duration}
+          : {...cur, timestampEnd: arr[i + 1].timestamp}))
 
     return data
   }
@@ -2233,7 +2240,7 @@ class GrouplikeListingElement extends Form {
       // Generate some items! Just go over the data list and generate one for
       // each timestamp.
       const tsElements = timestampData.map(ts => {
-        const el = new TimestampGrouplikeItemElement(item, ts.timestamp, ts.comment, this.app)
+        const el = new TimestampGrouplikeItemElement(item, ts.timestamp, ts.timestampEnd, ts.comment, this.app)
         el.on('pressed', () => this.emit('timestamp', item, ts.timestamp))
         return el
       })
@@ -2259,6 +2266,7 @@ class GrouplikeListingElement extends Form {
       form.selectInput(form.inputs.indexOf(selectedInput))
     }
 
+    this.scheduleDrawWithoutPropertyChange()
     this.fixAllLayout()
   }
 
@@ -3391,12 +3399,12 @@ class InteractiveGrouplikeItemElement extends BasicGrouplikeItemElement {
       writable.write('G')
     } else if (!this.isPlayable) {
       writable.write('F')
-    } else if (this.app.hasTimestampsFile(this.item)) {
-      writable.write(':')
     } else if (record.downloading) {
       writable.write(braille[Math.floor(Date.now() / 250) % 6])
     } else if (this.app.SQP.playingTrack === this.item) {
       writable.write('\u25B6')
+    } else if (this.app.hasTimestampsFile(this.item)) {
+      writable.write(':')
     } else {
       writable.write(' ')
     }
@@ -3418,11 +3426,12 @@ class InteractiveGrouplikeItemElement extends BasicGrouplikeItemElement {
 }
 
 class TimestampGrouplikeItemElement extends BasicGrouplikeItemElement {
-  constructor(item, timestamp, comment, app) {
+  constructor(item, timestamp, timestampEnd, comment, app) {
     super('')
 
     this.app = app
     this.timestamp = timestamp
+    this.timestampEnd = timestampEnd
     this.comment = comment
     this.item = item
   }
@@ -3431,11 +3440,15 @@ class TimestampGrouplikeItemElement extends BasicGrouplikeItemElement {
     const metadata = this.app.backend.getMetadataFor(this.item)
     const duration = (metadata && metadata.duration) || 0
     const strings = getTimeStringsFromSec(this.timestamp, duration)
+    const stringsEnd = getTimeStringsFromSec(this.timestampEnd, duration)
 
     this.text = (
-      (duration
+      /*
+      (trackDuration
         ? `(${strings.timeDone} - ${strings.percentDone})`
         : `(${strings.timeDone})`) +
+        */
+      `(${strings.timeDone})` +
       (this.comment
         ? ` ${this.comment}`
         : '')
@@ -3445,12 +3458,41 @@ class TimestampGrouplikeItemElement extends BasicGrouplikeItemElement {
   }
 
   writeStatus(writable) {
-    writable.write(ansi.setAttributes([ansi.A_BRIGHT, ansi.C_CYAN]))
-    writable.write('  ')
-    writable.write(ansi.setAttributes([ansi.C_RESET]))
-    writable.write(':')
-    writable.write(ansi.setAttributes([ansi.A_BRIGHT, ansi.C_CYAN]))
-    writable.write(' ')
+    let parts = []
+
+    const color = ansi.setAttributes([ansi.A_BRIGHT, ansi.C_CYAN])
+    const reset = ansi.setAttributes([ansi.C_RESET])
+
+    const { SQP } = this.app
+    if (
+      SQP.playingTrack === this.item &&
+      SQP.timeData &&
+      SQP.timeData.curSecTotal >= this.timestamp &&
+      SQP.timeData.curSecTotal < this.timestampEnd
+    ) {
+      parts = [
+        color,
+        ' ',
+        // reset,
+        '\u25B6 ',
+        // color,
+        ' '
+      ]
+    } else {
+      parts = [
+        color,
+        '  ',
+        reset,
+        ':',
+        color,
+        ' '
+      ]
+    }
+
+    for (const part of parts) {
+      writable.write(part)
+    }
+
     this.drawX += 4
   }