From a0d5dfcd12b27811dad61b2fea5b73c359f54cf5 Mon Sep 17 00:00:00 2001 From: Florrie Date: Sun, 7 Jul 2019 18:49:54 -0300 Subject: PARTY MODE --- ui.js | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 123 insertions(+), 8 deletions(-) (limited to 'ui.js') 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 -- cgit 1.3.0-6-gf8a5