diff options
-rw-r--r-- | giii.json | 256 | ||||
-rw-r--r-- | index.js | 9 | ||||
-rw-r--r-- | todo.txt | 3 | ||||
-rw-r--r-- | ui.js | 49 |
4 files changed, 305 insertions, 12 deletions
diff --git a/giii.json b/giii.json new file mode 100644 index 0000000..c2b3f4b --- /dev/null +++ b/giii.json @@ -0,0 +1,256 @@ +{ + "items": [ + { + "name": "Grandia III ost - The Legendary Pilot King", + "downloaderArg": "https://youtube.com/watch?v=mXj_PRy3mIQ" + }, + { + "name": "Grandia III ost - Anfog", + "downloaderArg": "https://youtube.com/watch?v=2UVrf2mzf0s" + }, + { + "name": "Grandia III ost - Miranda's Theme", + "downloaderArg": "https://youtube.com/watch?v=O0TL0R0XvAY" + }, + { + "name": "Grandia III ost - Yuki & Rotts", + "downloaderArg": "https://youtube.com/watch?v=_9RfmMdqkIU" + }, + { + "name": "Grandia III ost - Tension 1", + "downloaderArg": "https://youtube.com/watch?v=8BDXTAo9Yc8" + }, + { + "name": "Grandia III ost - A Trap Lurking in the Darkness", + "downloaderArg": "https://youtube.com/watch?v=Co8N9ySUkvI" + }, + { + "name": "Grandia III ost - GR-Turbo", + "downloaderArg": "https://youtube.com/watch?v=wfiqIKvt8mo" + }, + { + "name": "Grandia III ost - Yes! We Broke Through One More Barrier!", + "downloaderArg": "https://youtube.com/watch?v=0rAg9kB-4rU" + }, + { + "name": "Grandia III ost - PEACEFUL", + "downloaderArg": "https://youtube.com/watch?v=eLanK9Tj6e4" + }, + { + "name": "Grandia III ost - Happy Mushrooming", + "downloaderArg": "https://youtube.com/watch?v=uHIfJTwf8WU" + }, + { + "name": "Grandia III ost - Sabatal", + "downloaderArg": "https://youtube.com/watch?v=EnBGlElHeNY" + }, + { + "name": "Grandia III ost - Theme of Alonso", + "downloaderArg": "https://youtube.com/watch?v=i24Bc6qT_xc" + }, + { + "name": "Grandia III ost - The Gambler", + "downloaderArg": "https://youtube.com/watch?v=U44_DhixrI0" + }, + { + "name": "Grandia III ost - Gambling House", + "downloaderArg": "https://youtube.com/watch?v=s4v6O2TuZqk" + }, + { + "name": "Grandia III ost - Sailor's Spirit", + "downloaderArg": "https://youtube.com/watch?v=_sr0L9bDbE4" + }, + { + "name": "Grandia III ost - Theme of Bianca", + "downloaderArg": "https://youtube.com/watch?v=7QUCVSraOA4" + }, + { + "name": "Grandia III ost - Mendy", + "downloaderArg": "https://youtube.com/watch?v=YwEuVznql0A" + }, + { + "name": "Grandia III ost - A HOT CRASH!!", + "downloaderArg": "https://youtube.com/watch?v=gFZfs6ydxAY" + }, + { + "name": "Grandia III ost - Requiem of Birth", + "downloaderArg": "https://youtube.com/watch?v=2pX85EIPLn0" + }, + { + "name": "Grandia III ost - Theme Arrangement 1", + "downloaderArg": "https://youtube.com/watch?v=IilSsDUJEVI" + }, + { + "name": "Grandia III ost - Morning of Departure -Piano-", + "downloaderArg": "https://youtube.com/watch?v=_HdGqevLj-s" + }, + { + "name": "Grandia III ost - Where is the Right Way", + "downloaderArg": "https://youtube.com/watch?v=jJR6TQ21oqg" + }, + { + "name": "Grandia III ost - Morning of Departure -Euph-", + "downloaderArg": "https://youtube.com/watch?v=qhDTCI8ST1w" + }, + { + "name": "Grandia III ost - Spread the Wings, to the Sky!!", + "downloaderArg": "https://youtube.com/watch?v=DXiYScqgDX4" + }, + { + "name": "Grandia III ost - Believe in the Future", + "downloaderArg": "https://youtube.com/watch?v=cUiNtjxDNYc" + }, + { + "name": "Grandia III ost - Tension 4", + "downloaderArg": "https://youtube.com/watch?v=vsklG-OGwzg" + }, + { + "name": "Grandia III ost - Forest of Arcliff", + "downloaderArg": "https://youtube.com/watch?v=NGlvRKU7B30" + }, + { + "name": "Grandia III ost - Sacred Soul", + "downloaderArg": "https://youtube.com/watch?v=VAfe5fYAqC4" + }, + { + "name": "Grandia III ost - Theme of Beast Saint Griffon", + "downloaderArg": "https://youtube.com/watch?v=f_TAnGMwNMs" + }, + { + "name": "Grandia III ost - Forest of a Fantasy", + "downloaderArg": "https://youtube.com/watch?v=tDDbFDE_k18" + }, + { + "name": "Grandia III ost - Tension 3 Theme of Emelious", + "downloaderArg": "https://youtube.com/watch?v=2C2U1apFA44" + }, + { + "name": "Grandia III ost - Baccla", + "downloaderArg": "https://youtube.com/watch?v=KKqfJgUGUVc" + }, + { + "name": "Games Ost Emotional - To the Moon ~Grandia III~", + "downloaderArg": "https://youtube.com/watch?v=FhqVIxkiYAY" + }, + { + "name": "Grandia III ost - Alfina's Theme", + "downloaderArg": "https://youtube.com/watch?v=Rl3SyIO3sv4" + }, + { + "name": "Grandia III ost - Alfina's Sorrow", + "downloaderArg": "https://youtube.com/watch?v=k07XaqVvHhM" + }, + { + "name": "Grandia III ost - Attack With Conviction!!", + "downloaderArg": "https://youtube.com/watch?v=FOtHK7axaOk" + }, + { + "name": "Grandia III ost - Will the Airplane Fall and Crash On the Ground", + "downloaderArg": "https://youtube.com/watch?v=quBSzk6icJE" + }, + { + "name": "Grandia III ost - Proprietress of the Inn", + "downloaderArg": "https://youtube.com/watch?v=sNjNhTID7cU" + }, + { + "name": "Grandia III ost - Raflid -Crowded City-", + "downloaderArg": "https://youtube.com/watch?v=73J3k_2GviM" + }, + { + "name": "Grandia III ost - What Do You Fight For", + "downloaderArg": "https://youtube.com/watch?v=SCQVOzjbAHo" + }, + { + "name": "Grandia III ost - Caravans", + "downloaderArg": "https://youtube.com/watch?v=ouLijSrqt1o" + }, + { + "name": "Grandia III ost - Terrarium", + "downloaderArg": "https://youtube.com/watch?v=Qs5wV81gkqo" + }, + { + "name": "Grandia III ost - ZETEC", + "downloaderArg": "https://youtube.com/watch?v=LJ2nNxu5-mI" + }, + { + "name": "Grandia III ost - Requiem of a Birth (Reverse)", + "downloaderArg": "https://youtube.com/watch?v=FhILyonXI-U" + }, + { + "name": "Grandia III ost - ATTACK OF A FLASH -Synth-", + "downloaderArg": "https://youtube.com/watch?v=8xF-bhPOaW4" + }, + { + "name": "Grandia III ost - Hey!, Was That Just Real!", + "downloaderArg": "https://youtube.com/watch?v=Qin4Rkj-BPo" + }, + { + "name": "Grandia III ost - Tensions 2 Theme of Emelious 1", + "downloaderArg": "https://youtube.com/watch?v=Zxxx0xErnYw" + }, + { + "name": "Grandia III ost - An Elder Brother and a Younger Sister", + "downloaderArg": "https://youtube.com/watch?v=h2nUk6GGS0w" + }, + { + "name": "Grandia III ost - Surumania", + "downloaderArg": "https://youtube.com/watch?v=EPoL2QvLiKw" + }, + { + "name": "Grandia III ost - E vs. D", + "downloaderArg": "https://youtube.com/watch?v=E9BQ8aRcEBo" + }, + { + "name": "Grandia III ost - Decision of Moonlight", + "downloaderArg": "https://youtube.com/watch?v=5Mu5Y043z0w" + }, + { + "name": "Grandia III ost - Feel the Love of Eternity..", + "downloaderArg": "https://youtube.com/watch?v=xPj7tULZIqQ" + }, + { + "name": "Grandia III ost - ATTACK OF A FLASH -Orchestral-", + "downloaderArg": "https://youtube.com/watch?v=zil2JsduVXg" + }, + { + "name": "Grandia III ost - SORROW", + "downloaderArg": "https://youtube.com/watch?v=gn3oSRQ4ntc" + }, + { + "name": "Grandia III ost - Raflid -Defeated Hope-", + "downloaderArg": "https://youtube.com/watch?v=fX19yi1vJLc" + }, + { + "name": "Grandia III ost - Theme Arrangement 2", + "downloaderArg": "https://youtube.com/watch?v=NKADNL2EUHQ" + }, + { + "name": "Grandia III ost - Pilot King", + "downloaderArg": "https://youtube.com/watch?v=wkRjTb6TYuc" + }, + { + "name": "Grandia III ost - Zone Revival", + "downloaderArg": "https://youtube.com/watch?v=HFyPnZXnroI" + }, + { + "name": "Grandia III ost - Great Man Schmitt", + "downloaderArg": "https://youtube.com/watch?v=Wz9DaBlA9CE" + }, + { + "name": "Grandia III ost - GREAT ASSIZE", + "downloaderArg": "https://youtube.com/watch?v=1zUED9kLS7E" + }, + { + "name": "Grandia III ost - Theme Arrangement 3", + "downloaderArg": "https://youtube.com/watch?v=r-g5Ap8ZaK0" + }, + { + "name": "Grandia III ost - Thank You..", + "downloaderArg": "https://youtube.com/watch?v=4wyI-Qc3bQ8" + }, + { + "name": "Grandia III ost - Theme of GRANDIA III", + "downloaderArg": "https://youtube.com/watch?v=22BxmpZh-qs" + } + ] +} diff --git a/index.js b/index.js index a345301..ca62f17 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,5 @@ // omg I am tired of code -const { getPlayer } = require('./players') -const { getDownloaderFor } = require('./downloaders') const { AppElement } = require('./ui') const { updatePlaylistFormat } = require('./playlist-utils') const ansi = require('./tui-lib/util/ansi') @@ -10,6 +8,11 @@ const EventEmitter = require('events') const Flushable = require('./tui-lib/util/Flushable') const Root = require('./tui-lib/ui/Root') +// Hack to get around errors when piping many things to stdout/err +// (from general-util promisifyProcess) +process.stdout.setMaxListeners(Infinity) +process.stderr.setMaxListeners(Infinity) + process.on('unhandledRejection', error => { console.error(error.stack) process.exit(1) @@ -55,7 +58,7 @@ async function main() { ] } - grouplike = require('./library.json') + grouplike = require(process.argv[2] || './library.json') grouplike = updatePlaylistFormat(grouplike) diff --git a/todo.txt b/todo.txt index ca43148..1023eff 100644 --- a/todo.txt +++ b/todo.txt @@ -8,3 +8,6 @@ TODO: A "clear queue" button. TODO: A way to jump to an item with a particular name. Probably press "/". It'd be nice if the closest match got highlighted while you were typing. + +TODO: "Queue to play next"... maybe also a cursor in the queue list, which + would tell after what track to place newly-queued items? diff --git a/ui.js b/ui.js index 189aa85..1a583ab 100644 --- a/ui.js +++ b/ui.js @@ -18,6 +18,8 @@ class AppElement extends FocusElement { this.player = null this.recordStore = new RecordStore() + this.queueGrouplike = {isTheQueue: true, items: []} + this.form = new Form() this.addChild(this.form) @@ -32,24 +34,28 @@ class AppElement extends FocusElement { this.paneLeft.addChild(this.grouplikeListingElement) this.form.addInput(this.grouplikeListingElement, false) - this.grouplikeListingElement.on('download', item => this.downloadGrouplikeItem(item)) - this.grouplikeListingElement.on('select', item => { + const handleSelectFromMain = item => { if (isGroup(item)) { this.grouplikeListingElement.loadGrouplike(item) } else { this.playGrouplikeItem(item) } - }) - this.grouplikeListingElement.on('queue', item => this.queueGrouplikeItem(item)) + } - this.queueGrouplike = {isTheQueue: true, items: []} + this.grouplikeListingElement.on('download', item => this.downloadGrouplikeItem(item)) + this.grouplikeListingElement.on('select (enter)', item => handleSelectFromMain(item)) + this.grouplikeListingElement.on('select (space)', item => this.handleSpacePressed( + () => handleSelectFromMain(item))) + this.grouplikeListingElement.on('queue', item => this.queueGrouplikeItem(item)) this.queueListingElement = new GrouplikeListingElement(this.recordStore) this.queueListingElement.loadGrouplike(this.queueGrouplike) this.paneRight.addChild(this.queueListingElement) this.form.addInput(this.queueListingElement, false) - this.queueListingElement.on('select', item => this.playGrouplikeItem(item)) + this.queueListingElement.on('select (enter)', item => this.playGrouplikeItem(item)) + this.queueListingElement.on('select (space)', item => this.handleSpacePressed( + () => this.playGrouplikeItem(item))) this.playbackPane = new Pane() this.addChild(this.playbackPane) @@ -105,6 +111,17 @@ class AppElement extends FocusElement { } } + handleSpacePressed(callback) { + // Pauses/resumes if a track is currently playing; otherwise, calls the + // callback function. + + if (this.playingTrack) { + this.togglePause() + } else { + return callback() + } + } + seekAhead(seconds) { this.player.seekAhead(seconds) } @@ -192,7 +209,18 @@ class AppElement extends FocusElement { // TODO: Check if it's an item or a group + // If, by the time the track is downloaded, we're playing something + // different from when the download started, assume that we just want to + // keep listening to whatever new thing we started. + + const oldTrack = this.playingTrack + const downloadFile = await this.downloadGrouplikeItem(item) + + if (this.playingTrack !== oldTrack) { + return + } + await this.player.kill() this.recordStore.getRecord(item).playing = true this.playingTrack = item @@ -284,7 +312,8 @@ class GrouplikeListingElement extends ListScrollForm { for (const item of this.grouplike.items) { const itemElement = new GrouplikeItemElement(item, this.recordStore) itemElement.on('download', () => this.emit('download', item)) - itemElement.on('select', () => this.emit('select', item)) + itemElement.on('select (space)', () => this.emit('select (space)', item)) + itemElement.on('select (enter)', () => this.emit('select (enter)', item)) itemElement.on('queue', () => this.emit('queue', item)) this.addInput(itemElement) } @@ -370,8 +399,10 @@ class GrouplikeItemElement extends Button { this.emit('download') } else if (telc.isCaselessLetter(keyBuf, 'q')) { this.emit('queue') - } else if (telc.isSelect(keyBuf)) { - this.emit('select') + } else if (telc.isSpace(keyBuf)) { + this.emit('select (space)') + } else if (telc.isEnter(keyBuf)) { + this.emit('select (enter)') } } } |