« get me outta code hell

mtui - Music Text User Interface - user-friendly command line music player
about summary refs log tree commit diff
path: root/ui.js
diff options
context:
space:
mode:
Diffstat (limited to 'ui.js')
-rw-r--r--ui.js73
1 files changed, 67 insertions, 6 deletions
diff --git a/ui.js b/ui.js
index 26aa12e..8d43db8 100644
--- a/ui.js
+++ b/ui.js
@@ -1,15 +1,18 @@
+const { getDownloaderFor } = require('./downloaders')
+const { getPlayer } = require('./players')
 const ansi = require('./tui-lib/util/ansi')
 const Button = require('./tui-lib/ui/form/Button')
 const FocusElement = require('./tui-lib/ui/form/FocusElement')
 const ListScrollForm = require('./tui-lib/ui/form/ListScrollForm')
 const Pane = require('./tui-lib/ui/Pane')
 const RecordStore = require('./record-store')
+const telc = require('./tui-lib/util/telchars')
 
 class AppElement extends FocusElement {
-  constructor(internalApp) {
+  constructor() {
     super()
 
-    this.internalApp = internalApp
+    this.player = null
     this.recordStore = new RecordStore()
 
     this.pane = new Pane()
@@ -17,6 +20,18 @@ class AppElement extends FocusElement {
 
     this.grouplikeListingElement = new GrouplikeListingElement(this.recordStore)
     this.pane.addChild(this.grouplikeListingElement)
+
+    this.grouplikeListingElement.on('download', item => this.downloadGrouplikeItem(item))
+    this.grouplikeListingElement.on('play', item => this.playGrouplikeItem(item))
+  }
+
+  async setup() {
+    this.player = await getPlayer()
+  }
+
+  async shutdown() {
+    await this.player.kill()
+    this.emit('quitRequested')
   }
 
   fixLayout() {
@@ -31,13 +46,41 @@ class AppElement extends FocusElement {
   }
 
   keyPressed(keyBuf) {
-    if (keyBuf[0] === 0x03) { // ^C
-      this.emit('quitRequested')
+    if (keyBuf[0] === 0x03 || keyBuf[0] === 'q'.charCodeAt(0) || keyBuf[0] === 'Q'.charCodeAt(0)) {
+      this.shutdown()
       return
     }
 
     super.keyPressed(keyBuf)
   }
+
+  async downloadGrouplikeItem(item) {
+    // TODO: Check if it's an item or a group
+    const arg = item.downloaderArg
+    this.recordStore.getRecord(item).downloading = true
+    try {
+      return await getDownloaderFor(arg)(arg)
+    } finally {
+      this.recordStore.getRecord(item).downloading = false
+    }
+  }
+
+  async playGrouplikeItem(item) {
+    if (this.player === null) {
+      throw new Error('Attempted to play before a player was loaded')
+    }
+
+    // TODO: Check if it's an item or a group
+
+    const downloadFile = await this.downloadGrouplikeItem(item)
+    await this.player.kill()
+    this.recordStore.getRecord(item).playing = true
+    try {
+      await this.player.playFile(downloadFile)
+    } finally {
+      this.recordStore.getRecord(item).playing = false
+    }
+  }
 }
 
 class GrouplikeListingElement extends ListScrollForm {
@@ -59,7 +102,10 @@ class GrouplikeListingElement extends ListScrollForm {
     }
 
     for (const item of this.grouplike.items) {
-      this.addInput(new GrouplikeItemElement(item, this.recordStore))
+      const itemElement = new GrouplikeItemElement(item, this.recordStore)
+      itemElement.on('download', () => this.emit('download', item))
+      itemElement.on('play', () => this.emit('play', item))
+      this.addInput(itemElement)
     }
 
     this.fixLayout()
@@ -100,14 +146,29 @@ class GrouplikeItemElement extends Button {
     const braille = '⠈⠐⠠⠄⠂⠁'
     const brailleChar = braille[Math.floor(Date.now() / 250) % 6]
 
+    const record = this.recordStore.getRecord(this.item)
+
     writable.write(' ')
-    if (this.recordStore.getRecord(this.item).downloading) {
+    if (record.downloading) {
       writable.write(braille[Math.floor(Date.now() / 250) % 6])
+    } else if (record.playing) {
+      writable.write('\u25B6')
     } else {
       writable.write(' ')
     }
     writable.write(' ')
   }
+
+  keyPressed(keyBuf) {
+    // TODO: Helper function for this
+    if (keyBuf[0] === 'd'.charCodeAt(0) || keyBuf[0] === 'D'.charCodeAt(0)) {
+      this.emit('download')
+    }
+
+    if (telc.isSelect(keyBuf)) {
+      this.emit('play')
+    }
+  }
 }
 
 module.exports.AppElement = AppElement