UNPKG

polyv-live-cli

Version:

CLI tool for managing PolyV live streaming services.

416 lines 14.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChannelDetailsPopup = void 0; const blessed_1 = __importDefault(require("blessed")); class ChannelDetailsPopup { constructor(config) { this.channel = null; this.isVisible = false; this.scrollOffset = 0; this.maxScrollOffset = 0; this.config = config; this.screen = config.screen; this.eventBus = config.eventBus; this.createPopup(); this.setupEventListeners(); } createPopup() { this.popup = blessed_1.default.box({ parent: this.screen, top: 'center', left: 'center', width: '90%', height: '85%', border: { type: 'line' }, style: { fg: 'white', bg: 'black', border: { fg: 'cyan' } }, shadow: true, keys: true, vi: true, mouse: true, scrollable: false, hidden: true, label: ' Channel Details ', tags: true }); this.headerBox = blessed_1.default.box({ parent: this.popup, top: 0, left: 0, width: '100%', height: 4, border: { type: 'line' }, style: { fg: 'cyan', bg: 'black', border: { fg: 'gray' } }, tags: true }); this.scrollBox = blessed_1.default.box({ parent: this.popup, top: 4, left: 0, width: '100%', height: 'shrink', bottom: 2, scrollable: true, alwaysScroll: true, keys: true, vi: true, mouse: true, scrollbar: { ch: ' ', track: { bg: 'gray' }, style: { inverse: true } }, style: { fg: 'white', bg: 'black' }, tags: true }); this.footerBox = blessed_1.default.box({ parent: this.popup, bottom: 0, left: 0, width: '100%', height: 2, border: { type: 'line' }, style: { fg: 'gray', bg: 'black', border: { fg: 'gray' } }, content: this.getFooterContent(), tags: true }); this.setupKeyBindings(); } setupKeyBindings() { this.popup.key(['escape', 'q'], () => { this.hide(); }); this.popup.key(['r', 'R', 'f5'], () => { this.refreshChannel(); }); this.popup.key(['up', 'k'], () => { this.scroll(-1); }); this.popup.key(['down', 'j'], () => { this.scroll(1); }); this.popup.key(['pageup'], () => { this.scroll(-10); }); this.popup.key(['pagedown'], () => { this.scroll(10); }); this.popup.key(['home'], () => { this.scrollToTop(); }); this.popup.key(['end'], () => { this.scrollToBottom(); }); this.popup.key(['ctrl+c'], () => { this.copyChannelInfo(); }); } setupEventListeners() { this.eventBus.on('channel:updated', (data) => { if (this.isVisible && this.channel && data.channelId === this.channel.channelId) { this.updateChannel(data.channel); } }); this.eventBus.on('dashboard:refresh', () => { if (this.isVisible) { this.refreshChannel(); } }); } show(channel) { this.channel = channel; this.isVisible = true; this.scrollOffset = 0; this.updateContent(); this.popup.show(); this.popup.focus(); this.screen.render(); if (this.config.refreshInterval > 0) { this.startAutoRefresh(); } this.eventBus.emit('channelDetails:shown', { channelId: channel.channelId, timestamp: new Date() }); } hide() { this.isVisible = false; this.popup.hide(); this.screen.render(); this.stopAutoRefresh(); if (this.channel) { this.eventBus.emit('channelDetails:hidden', { channelId: this.channel.channelId, timestamp: new Date() }); } this.channel = null; } updateChannel(channel) { this.channel = channel; if (this.isVisible) { this.updateContent(); this.screen.render(); } } updateContent() { if (!this.channel) return; const headerContent = this.getHeaderContent(); this.headerBox.setContent(headerContent); const detailsContent = this.getDetailsContent(); this.scrollBox.setContent(detailsContent); this.updateFooter(); const contentLines = detailsContent.split('\n').length; const visibleLines = this.scrollBox.height - 2; this.maxScrollOffset = Math.max(0, contentLines - visibleLines); } getHeaderContent() { if (!this.channel) return ''; const statusColors = this.getStatusColors(this.channel.status); const statusIcon = this.config.showColors ? statusColors.icon : ''; const statusText = `${statusIcon} ${this.channel.statusText}`; return `{center}{bold}${this.channel.name}{/bold}{/center}\n` + `{center}Channel ID: {cyan-fg}${this.channel.channelId}{/cyan-fg} | Status: {${statusColors.fg}-fg}${statusText}{/${statusColors.fg}-fg}{/center}`; } getDetailsContent() { if (!this.channel) return ''; const sections = [ this.getBasicInfoSection(), this.getStatisticsSection(), this.getTimingSection(), this.getPublisherSection(), this.getStatusHistorySection() ]; return sections.join('\n\n'); } getBasicInfoSection() { if (!this.channel) return ''; const statusColors = this.getStatusColors(this.channel.status); const statusDisplay = this.config.showColors ? `{${statusColors.fg}-fg}${statusColors.icon} ${this.channel.statusText}{/${statusColors.fg}-fg}` : this.channel.statusText; return `{yellow-fg}{bold}Basic Information{/bold}{/yellow-fg}\n` + `├─ Channel ID: {cyan-fg}${this.channel.channelId}{/cyan-fg}\n` + `├─ Name: {white-fg}${this.channel.name}{/white-fg}\n` + `├─ Status: ${statusDisplay}\n` + `├─ Publisher: {green-fg}${this.channel.publisher}{/green-fg}\n` + `└─ Selected: {magenta-fg}${this.channel.selected ? 'Yes' : 'No'}{/magenta-fg}`; } getStatisticsSection() { if (!this.channel) return ''; const viewerPercentage = this.channel.maxViewer > 0 ? ((this.channel.viewerCount / this.channel.maxViewer) * 100).toFixed(1) + '%' : 'N/A'; return `{yellow-fg}{bold}Statistics{/bold}{/yellow-fg}\n` + `├─ Current Viewers: {cyan-fg}${this.channel.viewerCount.toLocaleString()}{/cyan-fg}\n` + `├─ Max Viewers: {cyan-fg}${this.channel.maxViewer.toLocaleString()}{/cyan-fg}\n` + `└─ Utilization: {magenta-fg}${viewerPercentage}{/magenta-fg}`; } getTimingSection() { if (!this.channel) return ''; const formatTime = (timestamp) => { if (timestamp === 0) return 'Not set'; return new Date(timestamp).toLocaleString(); }; const getDuration = (start, end) => { if (start === 0 || end === 0) return 'N/A'; const duration = end - start; const hours = Math.floor(duration / (1000 * 60 * 60)); const minutes = Math.floor((duration % (1000 * 60 * 60)) / (1000 * 60)); return `${hours}h ${minutes}m`; }; return `{yellow-fg}{bold}Timing Information{/bold}{/yellow-fg}\n` + `├─ Created: {cyan-fg}${formatTime(this.channel.createdTime)}{/cyan-fg}\n` + `├─ Start Time: {green-fg}${formatTime(this.channel.startTime)}{/green-fg}\n` + `├─ End Time: {red-fg}${formatTime(this.channel.endTime)}{/red-fg}\n` + `└─ Duration: {magenta-fg}${getDuration(this.channel.startTime, this.channel.endTime)}{/magenta-fg}`; } getPublisherSection() { if (!this.channel) return ''; return `{yellow-fg}{bold}Publisher Information{/bold}{/yellow-fg}\n` + `├─ Publisher: {green-fg}${this.channel.publisher}{/green-fg}\n` + `└─ Publishing Status: {cyan-fg}${this.getPublishingStatus()}{/cyan-fg}`; } getStatusHistorySection() { return `{yellow-fg}{bold}Recent Activity{/bold}{/yellow-fg}\n` + `├─ Last Updated: {cyan-fg}${new Date().toLocaleString()}{/cyan-fg}\n` + `├─ Status Changes: {green-fg}Available in full version{/green-fg}\n` + `└─ Performance Metrics: {magenta-fg}Available in full version{/magenta-fg}`; } getPublishingStatus() { if (!this.channel) return 'Unknown'; switch (this.channel.status) { case 'live': return 'Broadcasting Live'; case 'waiting': return 'Waiting to Start'; case 'end': return 'Broadcast Ended'; case 'banpush': return 'Banned from Broadcasting'; case 'playback': return 'Playing Back'; case 'unStart': return 'Not Started'; default: return 'Unknown Status'; } } getFooterContent() { return `{center}{gray-fg}ESC/q: Close | r/F5: Refresh | ↑↓: Scroll | Home/End: Top/Bottom | Ctrl+C: Copy{/gray-fg}{/center}`; } updateFooter() { this.footerBox.setContent(this.getFooterContent()); } getStatusColors(status) { const colorMap = { 'live': { fg: 'green', icon: '●' }, 'waiting': { fg: 'yellow', icon: '◯' }, 'end': { fg: 'gray', icon: '◦' }, 'banpush': { fg: 'red', icon: '✖' }, 'playback': { fg: 'blue', icon: '▶' }, 'unStart': { fg: 'gray', icon: '◦' } }; return colorMap[status] || { fg: 'white', icon: '?' }; } scroll(amount) { this.scrollOffset = Math.max(0, Math.min(this.maxScrollOffset, this.scrollOffset + amount)); this.scrollBox.scrollTo(this.scrollOffset); this.screen.render(); } scrollToTop() { this.scrollOffset = 0; this.scrollBox.scrollTo(0); this.screen.render(); } scrollToBottom() { this.scrollOffset = this.maxScrollOffset; this.scrollBox.scrollTo(this.maxScrollOffset); this.screen.render(); } copyChannelInfo() { if (!this.channel) return; const info = `Channel: ${this.channel.name}\n` + `ID: ${this.channel.channelId}\n` + `Status: ${this.channel.statusText}\n` + `Publisher: ${this.channel.publisher}\n` + `Viewers: ${this.channel.viewerCount}/${this.channel.maxViewer}`; this.eventBus.emit('channelDetails:copied', { channelId: this.channel.channelId, info, timestamp: new Date() }); this.showNotification('Channel info copied to clipboard!'); } showNotification(message) { const notification = blessed_1.default.box({ parent: this.screen, top: 'center', left: 'center', width: 'shrink', height: 'shrink', content: ` ${message} `, style: { fg: 'white', bg: 'green' }, padding: { left: 2, right: 2, top: 1, bottom: 1 } }); this.screen.render(); if (this.notificationTimer) { clearTimeout(this.notificationTimer); } this.notificationTimer = setTimeout(() => { this.screen.remove(notification); this.screen.render(); this.notificationTimer = undefined; }, 2000); } refreshChannel() { if (!this.channel) return; this.eventBus.emit('channel:requestRefresh', { channelId: this.channel.channelId, timestamp: new Date() }); } startAutoRefresh() { this.stopAutoRefresh(); if (this.config.refreshInterval > 0) { this.refreshTimer = setInterval(() => { this.refreshChannel(); }, this.config.refreshInterval); } } stopAutoRefresh() { if (this.refreshTimer) { clearInterval(this.refreshTimer); this.refreshTimer = undefined; } if (this.notificationTimer) { clearTimeout(this.notificationTimer); this.notificationTimer = undefined; } } isShowing() { return this.isVisible; } getCurrentChannel() { return this.channel; } destroy() { this.stopAutoRefresh(); this.hide(); if (this.popup && this.screen) { try { if (typeof this.screen.remove === 'function') { this.screen.remove(this.popup); } } catch (error) { } } this.eventBus.emit('channelDetails:destroyed', { timestamp: new Date() }); } } exports.ChannelDetailsPopup = ChannelDetailsPopup; //# sourceMappingURL=channel-details.popup.js.map