UNPKG

polyv-live-cli

Version:

CLI tool for managing PolyV live streaming services.

340 lines 11.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.BatchOperationsDialog = void 0; const blessed_1 = __importDefault(require("blessed")); class BatchOperationsDialog { constructor(config) { this.selectedChannels = []; this.isVisible = false; this.currentOperation = null; this.operationInProgress = false; this.config = config; this.screen = config.screen; this.eventBus = config.eventBus; this.createDialog(); this.setupEventListeners(); } createDialog() { this.dialog = blessed_1.default.box({ parent: this.screen, top: 'center', left: 'center', width: '60%', height: '70%', border: { type: 'line' }, style: { fg: 'white', bg: 'black', border: { fg: 'cyan' } }, shadow: true, keys: true, vi: true, mouse: true, hidden: true, label: ' Batch Operations ', tags: true }); this.operationsList = blessed_1.default.list({ parent: this.dialog, top: 1, left: 1, width: '100%-2', height: '60%', border: { type: 'line' }, style: { fg: 'white', bg: 'black', border: { fg: 'gray' }, selected: { bg: 'blue', fg: 'white' } }, label: ' Available Operations ', keys: true, vi: true, mouse: true, scrollable: true, items: this.getOperationItems(), tags: true }); this.statusBox = blessed_1.default.box({ parent: this.dialog, top: '60%', left: 1, width: '100%-2', height: 6, border: { type: 'line' }, style: { fg: 'white', bg: 'black', border: { fg: 'gray' } }, label: ' Operation Status ', scrollable: true, tags: true }); this.progressBar = blessed_1.default.progressbar({ parent: this.dialog, bottom: 4, left: 1, width: '100%-2', height: 3, border: { type: 'line' }, style: { fg: 'white', bg: 'black', border: { fg: 'gray' }, bar: { bg: 'green' } }, label: ' Progress ', filled: 0, hidden: true }); this.footerBox = blessed_1.default.box({ parent: this.dialog, 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(); } getOperationItems() { return [ '{green-fg}Start Streaming{/green-fg} - Start broadcasting on selected channels', '{red-fg}Stop Streaming{/red-fg} - Stop broadcasting on selected channels', '{yellow-fg}Refresh Data{/yellow-fg} - Refresh information for selected channels', '{cyan-fg}Export Data{/cyan-fg} - Export selected channels data to file', '{red-fg}Delete Channels{/red-fg} - {bold}DANGER:{/bold} Permanently delete selected channels' ]; } setupKeyBindings() { this.dialog.key(['escape', 'q'], () => { if (!this.operationInProgress) { this.hide(); } }); this.dialog.key(['enter'], () => { if (!this.operationInProgress) { this.executeSelectedOperation(); } }); this.dialog.key(['up', 'k'], () => { this.operationsList.up(1); this.screen.render(); }); this.dialog.key(['down', 'j'], () => { this.operationsList.down(1); this.screen.render(); }); this.dialog.key(['1'], () => { this.operationsList.select(0); this.executeSelectedOperation(); }); this.dialog.key(['2'], () => { this.operationsList.select(1); this.executeSelectedOperation(); }); this.dialog.key(['3'], () => { this.operationsList.select(2); this.executeSelectedOperation(); }); this.dialog.key(['4'], () => { this.operationsList.select(3); this.executeSelectedOperation(); }); this.dialog.key(['5'], () => { this.operationsList.select(4); this.executeSelectedOperation(); }); } setupEventListeners() { this.eventBus.on('batchOperation:completed', (result) => { this.handleOperationCompleted(result); }); this.eventBus.on('batchOperation:progress', (data) => { this.updateProgress(data.current, data.total, data.channel); }); } show(selectedChannels) { this.selectedChannels = selectedChannels; this.isVisible = true; this.operationInProgress = false; this.updateStatusBox(`Ready to perform batch operations on ${selectedChannels.length} selected channels.`); this.progressBar.hide(); this.dialog.show(); this.operationsList.focus(); this.screen.render(); this.eventBus.emit('batchOperations:shown', { selectedChannels: selectedChannels.length, timestamp: new Date() }); } hide() { this.isVisible = false; this.dialog.hide(); this.screen.render(); if (this.selectedChannels.length > 0) { this.eventBus.emit('batchOperations:hidden', { selectedChannels: this.selectedChannels.length, timestamp: new Date() }); } this.selectedChannels = []; this.currentOperation = null; this.operationInProgress = false; } executeSelectedOperation() { if (this.operationInProgress || this.selectedChannels.length === 0) { return; } const selectedIndex = this.operationsList.selected; const operations = ['start', 'stop', 'refresh', 'export', 'delete']; const operation = operations[selectedIndex]; if (!operation) return; if (operation === 'delete') { this.showConfirmationDialog(operation); return; } this.startOperation(operation); } showConfirmationDialog(operation) { const confirmDialog = blessed_1.default.question({ parent: this.screen, top: 'center', left: 'center', width: '50%', height: 'shrink', border: { type: 'line' }, style: { fg: 'white', bg: 'red', border: { fg: 'red' } }, label: ' Confirmation Required ', tags: true }); const message = operation === 'delete' ? `Are you sure you want to DELETE ${this.selectedChannels.length} channels?\nThis action cannot be undone!` : `Are you sure you want to perform ${operation} on ${this.selectedChannels.length} channels?`; confirmDialog.ask(message, (_err, confirmed) => { this.screen.remove(confirmDialog); this.screen.render(); if (confirmed) { this.startOperation(operation); } }); } startOperation(operation) { this.currentOperation = operation; this.operationInProgress = true; this.updateStatusBox(`Starting ${operation} operation on ${this.selectedChannels.length} channels...`); this.progressBar.show(); this.progressBar.setProgress(0); this.refreshFooter(); this.eventBus.emit('batchOperation:start', { operation, channels: this.selectedChannels, timestamp: new Date() }); } updateProgress(current, total, channelInfo) { if (!this.isVisible || !this.operationInProgress) return; const percentage = total > 0 ? Math.round((current / total) * 100) : 0; this.progressBar.setProgress(percentage); const statusText = channelInfo ? `Processing ${current}/${total} - ${channelInfo}` : `Processing ${current}/${total} channels (${percentage}%)`; this.updateStatusBox(statusText); this.screen.render(); } handleOperationCompleted(result) { if (!this.isVisible || result.operation !== this.currentOperation) return; this.operationInProgress = false; this.progressBar.setProgress(100); const statusText = this.formatOperationResult(result); this.updateStatusBox(statusText); this.refreshFooter(); if (result.failureCount === 0) { setTimeout(() => { if (this.isVisible && !this.operationInProgress) { this.hide(); } }, 3000); } } formatOperationResult(result) { const { operation, totalChannels, successCount, failureCount } = result; let statusText = `{bold}Operation Complete:{/bold} ${operation}\n`; statusText += `Total: ${totalChannels}, Success: {green-fg}${successCount}{/green-fg}, Failed: {red-fg}${failureCount}{/red-fg}\n`; if (failureCount > 0 && result.errors.length > 0) { statusText += '\n{red-fg}Errors:{/red-fg}\n'; result.errors.slice(0, 3).forEach(error => { statusText += `- ${error.channelId}: ${error.error}\n`; }); if (result.errors.length > 3) { statusText += `... and ${result.errors.length - 3} more errors\n`; } } return statusText; } updateStatusBox(content) { this.statusBox.setContent(content); } getFooterContent() { if (this.operationInProgress) { return `{center}{gray-fg}Operation in progress... Please wait{/gray-fg}{/center}`; } const colorSupport = this.config.showColors ? 'Colors: ON' : 'Colors: OFF'; return `{center}{gray-fg}Enter: Execute | ↑↓: Navigate | 1-5: Quick Select | ESC/q: Close | ${colorSupport}{/gray-fg}{/center}`; } updateFooter() { this.footerBox.setContent(this.getFooterContent()); } refreshFooter() { this.updateFooter(); this.screen.render(); } isShowing() { return this.isVisible; } getSelectedChannels() { return [...this.selectedChannels]; } getOperationStatus() { return { operation: this.currentOperation, inProgress: this.operationInProgress }; } destroy() { this.hide(); if (this.dialog && this.screen) { try { if (typeof this.screen.remove === 'function') { this.screen.remove(this.dialog); } } catch (error) { } } this.eventBus.emit('batchOperations:destroyed', { timestamp: new Date() }); } } exports.BatchOperationsDialog = BatchOperationsDialog; //# sourceMappingURL=batch-operations.dialog.js.map