UNPKG

polyv-live-cli

Version:

CLI tool for managing PolyV live streaming services.

458 lines 16.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CustomThemeBuilder = void 0; const events_1 = require("events"); const config_validator_1 = require("./config-validator"); const errors_1 = require("../utils/errors"); class CustomThemeBuilder extends events_1.EventEmitter { constructor(options = {}) { super(); this.currentTheme = {}; this.colorPalettes = new Map(); this.templates = new Map(); this.validationErrors = []; this.validationWarnings = []; this.options = { enablePreview: options.enablePreview ?? true, autoValidate: options.autoValidate ?? true, strictMode: options.strictMode ?? false, }; this.loadBuiltInColorPalettes(); this.loadBuiltInTemplates(); this.initializeTheme(); } startNew(baseTemplate) { if (baseTemplate && this.templates.has(baseTemplate)) { const template = this.templates.get(baseTemplate); this.currentTheme = JSON.parse(JSON.stringify(template.baseTheme)); } else { this.initializeTheme(); } this.emit('theme:started', this.currentTheme); return this; } loadTheme(theme) { this.currentTheme = JSON.parse(JSON.stringify(theme)); if (this.options.autoValidate) { this.validateCurrentTheme(); } this.emit('theme:loaded', this.currentTheme); return this; } setThemeInfo(info) { this.currentTheme.id = info.id; this.currentTheme.name = info.name; if (info.description !== undefined) { this.currentTheme.description = info.description; } if (info.author !== undefined) { this.currentTheme.author = info.author; } this.currentTheme.version = info.version || '1.0.0'; this.currentTheme.isBuiltIn = false; this.validateAndEmit('theme:info-updated'); return this; } setColors(colors) { if (typeof colors === 'string') { const palette = this.colorPalettes.get(colors); if (!palette) { throw new errors_1.ConfigurationError(`Color palette '${colors}' not found`); } this.currentTheme.colors = this.paletteToColorScheme(palette); } else { this.currentTheme.colors = { ...this.getDefaultColors(), ...this.currentTheme.colors, ...colors, }; } this.validateAndEmit('theme:colors-updated'); return this; } setColor(colorName, colorValue) { if (!this.currentTheme.colors) { this.currentTheme.colors = this.getDefaultColors(); } this.currentTheme.colors[colorName] = colorValue; this.validateAndEmit('theme:color-updated', { colorName, colorValue }); return this; } setFonts(fonts) { this.currentTheme.fonts = { ...this.getDefaultFonts(), ...this.currentTheme.fonts, ...fonts, }; this.validateAndEmit('theme:fonts-updated'); return this; } setBorders(borders) { this.currentTheme.borders = { ...this.getDefaultBorders(), ...this.currentTheme.borders, ...borders, }; this.validateAndEmit('theme:borders-updated'); return this; } setComponentStyles(componentStyles) { this.currentTheme.components = { ...this.getDefaultComponentStyles(), ...this.currentTheme.components, ...componentStyles, }; this.validateAndEmit('theme:components-updated'); return this; } setComponentStyle(componentName, style) { if (!this.currentTheme.components) { this.currentTheme.components = this.getDefaultComponentStyles(); } this.currentTheme.components[componentName] = { ...this.currentTheme.components[componentName], ...style, }; this.validateAndEmit('theme:component-style-updated', { componentName, style }); return this; } transformColors(transformation) { if (!this.currentTheme.colors) { this.currentTheme.colors = this.getDefaultColors(); } const transformedColors = {}; for (const [key, value] of Object.entries(this.currentTheme.colors)) { transformedColors[key] = transformation(value); } this.currentTheme.colors = { ...this.currentTheme.colors, ...transformedColors, }; this.validateAndEmit('theme:colors-transformed'); return this; } adjustBrightness(factor) { return this.transformColors(color => this.adjustColorBrightness(color, factor)); } adjustSaturation(factor) { return this.transformColors(color => this.adjustColorSaturation(color, factor)); } generateComplementaryScheme(baseColor) { const complementaryColors = this.generateComplementaryColors(baseColor); return this.setColors(complementaryColors); } validateCurrentTheme() { try { const completeTheme = this.buildCompleteTheme(); const validation = config_validator_1.ConfigValidator.validateThemeConfig(completeTheme); this.validationErrors = [...validation.errors, ...validation.critical]; this.validationWarnings = validation.warnings; return { valid: validation.valid, errors: this.validationErrors, warnings: this.validationWarnings, }; } catch (error) { this.validationErrors = [error instanceof Error ? error.message : String(error)]; this.validationWarnings = []; return { valid: false, errors: this.validationErrors, warnings: this.validationWarnings, }; } } getValidationErrors() { return [...this.validationErrors]; } getValidationWarnings() { return [...this.validationWarnings]; } build() { const validation = this.validateCurrentTheme(); if (!validation.valid) { if (this.options.strictMode) { throw new errors_1.ConfigurationError(`Cannot build invalid theme: ${validation.errors.join(', ')}`); } else { console.warn('Building theme with validation errors:', validation.errors); } } const completeTheme = this.buildCompleteTheme(); this.emit('theme:built', completeTheme); return completeTheme; } getProgress() { const requiredFields = [ 'id', 'name', 'colors', 'fonts', 'borders', 'components' ]; const completed = requiredFields.filter(field => this.currentTheme[field] !== undefined); const missing = requiredFields.filter(field => this.currentTheme[field] === undefined); return { completed, missing, percentage: (completed.length / requiredFields.length) * 100, }; } getCurrentTheme() { return JSON.parse(JSON.stringify(this.currentTheme)); } getAvailableColorPalettes() { return Array.from(this.colorPalettes.keys()); } getColorPalette(name) { return this.colorPalettes.get(name); } addColorPalette(palette) { this.colorPalettes.set(palette.name, palette); this.emit('palette:added', palette); return this; } getAvailableTemplates() { return Array.from(this.templates.keys()); } getTemplate(id) { return this.templates.get(id); } addTemplate(template) { this.templates.set(template.id, template); this.emit('template:added', template); return this; } reset() { this.initializeTheme(); this.validationErrors = []; this.validationWarnings = []; this.emit('theme:reset'); return this; } initializeTheme() { this.currentTheme = { id: '', name: '', isBuiltIn: false, colors: this.getDefaultColors(), fonts: this.getDefaultFonts(), borders: this.getDefaultBorders(), components: this.getDefaultComponentStyles(), }; } validateAndEmit(eventName, data) { if (this.options.autoValidate) { this.validateCurrentTheme(); } this.emit(eventName, data); } buildCompleteTheme() { return { id: this.currentTheme.id || 'custom-theme', name: this.currentTheme.name || 'Custom Theme', ...(this.currentTheme.description !== undefined && { description: this.currentTheme.description }), ...(this.currentTheme.author !== undefined && { author: this.currentTheme.author }), version: this.currentTheme.version || '1.0.0', isBuiltIn: false, colors: { ...this.getDefaultColors(), ...this.currentTheme.colors, }, fonts: { ...this.getDefaultFonts(), ...this.currentTheme.fonts, }, borders: { ...this.getDefaultBorders(), ...this.currentTheme.borders, }, components: { ...this.getDefaultComponentStyles(), ...this.currentTheme.components, }, }; } getDefaultColors() { return { primary: '#0066cc', secondary: '#6c757d', background: '#000000', foreground: '#ffffff', accent: '#17a2b8', error: '#dc3545', warning: '#ffc107', success: '#28a745', info: '#17a2b8', muted: '#6c757d', highlight: '#ffff00', border: '#666666', selection: '#0066cc', }; } getDefaultFonts() { return { family: 'monospace', size: 12, weight: 'normal', style: 'normal', }; } getDefaultBorders() { return { type: 'line', style: 'solid', color: '#666666', }; } getDefaultComponentStyles() { return { header: { fg: '#ffffff', bg: '#0066cc', bold: true }, content: { fg: '#ffffff', bg: '#000000' }, status: { fg: '#17a2b8', bg: '#000000' }, border: { fg: '#666666' }, scrollbar: { fg: '#666666', bg: '#333333' }, selection: { fg: '#ffffff', bg: '#0066cc' }, }; } paletteToColorScheme(palette) { const colors = palette.colors; return { primary: colors[0] || '#0066cc', secondary: colors[1] || '#6c757d', background: colors[2] || '#000000', foreground: colors[3] || '#ffffff', accent: colors[4] || '#17a2b8', error: colors[5] || '#dc3545', warning: colors[6] || '#ffc107', success: colors[7] || '#28a745', info: colors[8] || '#17a2b8', muted: colors[9] || '#6c757d', highlight: colors[10] || '#ffff00', border: colors[11] || '#666666', selection: colors[12] || '#0066cc', }; } adjustColorBrightness(color, factor) { if (color.startsWith('#')) { const hex = color.slice(1); const r = parseInt(hex.slice(0, 2), 16); const g = parseInt(hex.slice(2, 4), 16); const b = parseInt(hex.slice(4, 6), 16); const adjust = (c) => { const adjusted = c + (factor > 0 ? (255 - c) * factor : c * factor); return Math.max(0, Math.min(255, Math.round(adjusted))); }; const newR = adjust(r).toString(16).padStart(2, '0'); const newG = adjust(g).toString(16).padStart(2, '0'); const newB = adjust(b).toString(16).padStart(2, '0'); return `#${newR}${newG}${newB}`; } return color; } adjustColorSaturation(color, factor) { return this.adjustColorBrightness(color, factor * 0.3); } generateComplementaryColors(baseColor) { return { primary: baseColor, secondary: this.adjustColorBrightness(baseColor, -0.3), accent: this.adjustColorBrightness(baseColor, 0.2), selection: this.adjustColorBrightness(baseColor, 0.1), }; } loadBuiltInColorPalettes() { const palettes = [ { name: 'modern-dark', description: 'Modern dark color palette', colors: [ '#007acc', '#6c7b7f', '#1e1e1e', '#d4d4d4', '#4fc1ff', '#f44747', '#ffcc02', '#89d185', '#4fc1ff', '#808080', '#ffff00', '#3c3c3c', '#007acc' ], }, { name: 'vibrant-light', description: 'Vibrant light color palette', colors: [ '#0066cc', '#6c757d', '#ffffff', '#000000', '#e83e8c', '#dc3545', '#fd7e14', '#28a745', '#17a2b8', '#6c757d', '#fff3cd', '#dee2e6', '#0066cc' ], }, { name: 'high-contrast', description: 'High contrast accessibility palette', colors: [ '#ffff00', '#ffffff', '#000000', '#ffffff', '#00ffff', '#ff0000', '#ffff00', '#00ff00', '#00ffff', '#808080', '#ffff00', '#ffffff', '#ffff00' ], }, ]; palettes.forEach(palette => { this.colorPalettes.set(palette.name, palette); }); } loadBuiltInTemplates() { const templates = [ { id: 'minimal-dark', name: 'Minimal Dark', description: 'Clean and minimal dark theme', category: 'dark', baseTheme: { colors: { primary: '#007acc', secondary: '#6c7b7f', background: '#1e1e1e', foreground: '#d4d4d4', accent: '#4fc1ff', error: '#f44747', warning: '#ffcc02', success: '#89d185', info: '#4fc1ff', muted: '#808080', highlight: '#ffff00', border: '#3c3c3c', selection: '#007acc', }, fonts: { family: 'monospace', size: 12, weight: 'normal', style: 'normal', }, }, }, { id: 'clean-light', name: 'Clean Light', description: 'Clean and bright light theme', category: 'light', baseTheme: { colors: { primary: '#0066cc', secondary: '#6c757d', background: '#ffffff', foreground: '#212529', accent: '#6f42c1', error: '#dc3545', warning: '#fd7e14', success: '#198754', info: '#0dcaf0', muted: '#6c757d', highlight: '#fff3cd', border: '#dee2e6', selection: '#0066cc', }, }, }, ]; templates.forEach(template => { this.templates.set(template.id, template); }); } } exports.CustomThemeBuilder = CustomThemeBuilder; //# sourceMappingURL=custom-theme-builder.js.map