diff options
author | Florrie <towerofnix@gmail.com> | 2019-07-07 18:49:54 -0300 |
---|---|---|
committer | Florrie <towerofnix@gmail.com> | 2019-07-07 18:49:54 -0300 |
commit | a0d5dfcd12b27811dad61b2fea5b73c359f54cf5 (patch) | |
tree | fa52f00c74b1e8bbd6d5efe1bca51ca783591a68 | |
parent | d7f31bd2541e5d37057136bc34e3f9603803ab57 (diff) |
PARTY MODE
-rwxr-xr-x | index.js | 1 | ||||
-rw-r--r-- | telnet-server.js | 13 | ||||
-rw-r--r-- | ui.js | 131 |
3 files changed, 134 insertions, 11 deletions
diff --git a/index.js b/index.js index 10e0696..a36eceb 100755 --- a/index.js +++ b/index.js @@ -106,6 +106,7 @@ async function main() { if (process.argv.includes('--telnet-server')) { telnetServer = new TelnetServer(backend) await telnetServer.listen(1244) + appElement.attachAsServerHost(telnetServer) } if (process.argv.includes('--stress-test')) { diff --git a/telnet-server.js b/telnet-server.js index 6111d9d..d8d8e07 100644 --- a/telnet-server.js +++ b/telnet-server.js @@ -1,5 +1,6 @@ 'use strict' +const EventEmitter = require('events') const net = require('net') const setupClient = require('./client') @@ -9,8 +10,10 @@ const { } } = require('./tui-lib') -class TelnetServer { +class TelnetServer extends EventEmitter { constructor(backend) { + super() + this.backend = backend this.server = new net.Server(socket => this.handleConnection(socket)) this.sockets = [] @@ -28,7 +31,7 @@ class TelnetServer { interfacer, appConfig: { canControlPlayback: false, - canControlQueue: false, + canControlQueue: true, canProcessMetadata: false, canSuspend: false, showLeftPane: true, @@ -37,6 +40,8 @@ class TelnetServer { } }) + appElement.attachAsServerClient(this) + let closed = false const quit = (msg = 'See you!') => { @@ -52,16 +57,18 @@ class TelnetServer { appElement.on('quitRequested', quit) socket.on('close', () => { + clearInterval(renderInterval) if (!closed) { - clearInterval(renderInterval) flushable.end() closed = true this.sockets.splice(this.sockets.indexOf(socket), 1) } + this.emit('left', socket) }) socket.quit = quit this.sockets.push(socket) + this.emit('joined', socket) } disconnectAllSockets(msg) { diff --git a/ui.js b/ui.js index 0a1cbca..378cd77 100644 --- a/ui.js +++ b/ui.js @@ -138,6 +138,8 @@ class AppElement extends FocusElement { super() this.backend = backend + this.telnetServer = null + this.isPartyHost = false this.bindListeners() this.attachListeners() @@ -212,6 +214,21 @@ class AppElement extends FocusElement { this.playbackInfoElement.on('seek ahead', () => this.backend.seekAhead(5)) this.playbackInfoElement.on('toggle pause', () => this.backend.togglePause()) + this.partyTop = new DisplayElement() + this.partyBottom = new DisplayElement() + this.addChild(this.partyTop) + this.addChild(this.partyBottom) + this.partyTop.visible = false + this.partyBottom.visible = false + + this.partyTopBanner = new PartyBanner(1) + this.partyBottomBanner = new PartyBanner(-1) + this.partyTop.addChild(this.partyTopBanner) + this.partyBottom.addChild(this.partyBottomBanner) + + this.partyLabel = new Label('') + this.partyTop.addChild(this.partyLabel) + // Dialogs this.openPlaylistDialog = new OpenPlaylistDialog() @@ -666,12 +683,42 @@ class AppElement extends FocusElement { this.menubar.fixLayout() - const mainHeight = this.contentH - 6 + let topY = this.contentH + + if (this.partyBottom.visible) { + this.partyBottom.w = this.contentW + this.partyBottom.h = 1 + this.partyBottom.x = 0 + this.partyBottom.y = topY - this.partyBottom.h + topY = this.partyBottom.top + this.partyBottomBanner.w = this.partyBottom.w + } + + this.playbackPane.w = this.contentW + this.playbackPane.h = 5 + this.playbackPane.x = 0 + this.playbackPane.y = topY - this.playbackPane.h + topY = this.playbackPane.top + + let bottomY = 1 + + if (this.partyTop.visible) { + this.partyTop.w = this.contentW + this.partyTop.h = 1 + this.partyTop.x = 0 + this.partyTop.y = 1 + bottomY = this.partyTop.bottom + + this.partyTopBanner.w = this.partyTop.w + this.partyTopBanner.y = this.partyTop.contentH - 1 + + this.alignPartyLabel() + } if (this.paneLeft.visible) { this.paneLeft.w = Math.max(Math.floor(0.8 * this.contentW), this.contentW - 80) - this.paneLeft.h = mainHeight - this.paneLeft.y = 1 + this.paneLeft.y = bottomY + this.paneLeft.h = topY - this.paneLeft.y this.paneRight.x = this.paneLeft.right this.paneRight.w = this.contentW - this.paneLeft.right } else { @@ -679,11 +726,9 @@ class AppElement extends FocusElement { this.paneRight.w = this.contentW } - this.paneRight.y = 1 - this.paneRight.h = mainHeight - this.playbackPane.y = mainHeight + 1 - this.playbackPane.w = this.contentW - this.playbackPane.h = this.contentH - this.playbackPane.y + this.paneRight.y = bottomY + this.paneRight.h = topY - this.paneRight.y + topY = this.paneRight.y this.tabber.fillParent() @@ -702,6 +747,42 @@ class AppElement extends FocusElement { this.playbackInfoElement.fillParent() } + alignPartyLabel() { + this.partyLabel.centerInParent() + this.partyLabel.y = 0 + } + + attachAsServerHost(telnetServer) { + this.isPartyHost = true + this.attachAsServer(telnetServer) + } + + attachAsServerClient(telnetServer) { + this.isPartyHost = false + this.attachAsServer(telnetServer) + } + + attachAsServer(telnetServer) { + this.telnetServer = telnetServer + this.updatePartyLabel() + + this.telnetServer.on('joined', () => this.updatePartyLabel()) + this.telnetServer.on('left', () => this.updatePartyLabel()) + + this.partyTop.visible = true + this.partyBottom.visible = true + this.fixLayout() + } + + updatePartyLabel() { + const clients = this.telnetServer.sockets.length + const clientsMsg = clients === 1 ? '1-ish connection' : `${clients}-ish connections` + let msg = `${process.env.USER} playing for ${clientsMsg}` + + this.partyLabel.text = ` ${msg} ` + this.alignPartyLabel() + } + keyPressed(keyBuf) { if (keyBuf[0] === 0x03) { // Ctrl-C this.shutdown() @@ -2787,4 +2868,38 @@ class Menubar extends ListScrollForm { } } +class PartyBanner extends DisplayElement { + constructor(direction) { + super() + + this.direction = direction + } + + drawTo(writable) { + writable.write(ansi.moveCursor(this.absTop, this.absLeft)) + + const timerNum = Date.now() / 2000 * this.direction + let lastAttribute = '' + const updateAttribute = offsetNum => { + const attr = (Math.cos(offsetNum - timerNum) < 0 ? '\x1b[0;1m' : '\x1b[0;2m') + if (attr === lastAttribute) { + return '' + } else { + lastAttribute = attr + return attr + } + } + let str = new Array(this.w).fill('0').map((_, i) => { + const offsetNum = i / this.w * 2 * Math.PI + return ( + updateAttribute(offsetNum) + + (Math.sin(offsetNum + timerNum) < 0 ? '-' : '*') + ) + }).join('') + + writable.write(str) + writable.write(ansi.resetAttributes()) + } +} + module.exports = AppElement |