unified-video-framework 1.4.135 → 1.4.137
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -2402,6 +2402,87 @@ export class WebPlayer extends BasePlayer {
|
|
|
2402
2402
|
transform: translateY(0);
|
|
2403
2403
|
}
|
|
2404
2404
|
|
|
2405
|
+
/* Accordion Styles */
|
|
2406
|
+
.uvf-settings-accordion {
|
|
2407
|
+
padding: 0;
|
|
2408
|
+
}
|
|
2409
|
+
|
|
2410
|
+
.uvf-accordion-item {
|
|
2411
|
+
border-bottom: 1px solid rgba(255,255,255,0.08);
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2414
|
+
.uvf-accordion-item:last-child {
|
|
2415
|
+
border-bottom: none;
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2418
|
+
.uvf-accordion-header {
|
|
2419
|
+
display: flex;
|
|
2420
|
+
align-items: center;
|
|
2421
|
+
justify-content: space-between;
|
|
2422
|
+
padding: 14px 18px;
|
|
2423
|
+
cursor: pointer;
|
|
2424
|
+
transition: all 0.2s ease;
|
|
2425
|
+
border-radius: 8px;
|
|
2426
|
+
margin: 4px 8px;
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2429
|
+
.uvf-accordion-header:hover {
|
|
2430
|
+
background: rgba(255,255,255,0.08);
|
|
2431
|
+
transform: translateX(2px);
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2434
|
+
.uvf-accordion-title {
|
|
2435
|
+
display: flex;
|
|
2436
|
+
align-items: center;
|
|
2437
|
+
gap: 10px;
|
|
2438
|
+
font-size: 14px;
|
|
2439
|
+
font-weight: 500;
|
|
2440
|
+
color: #fff;
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
.uvf-accordion-icon {
|
|
2444
|
+
font-size: 16px;
|
|
2445
|
+
opacity: 0.8;
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2448
|
+
.uvf-accordion-current {
|
|
2449
|
+
font-size: 12px;
|
|
2450
|
+
color: rgba(255,255,255,0.7);
|
|
2451
|
+
background: rgba(255,255,255,0.1);
|
|
2452
|
+
padding: 4px 8px;
|
|
2453
|
+
border-radius: 12px;
|
|
2454
|
+
font-weight: 500;
|
|
2455
|
+
}
|
|
2456
|
+
|
|
2457
|
+
.uvf-accordion-arrow {
|
|
2458
|
+
font-size: 12px;
|
|
2459
|
+
color: rgba(255,255,255,0.6);
|
|
2460
|
+
transition: transform 0.3s ease;
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
.uvf-accordion-item.expanded .uvf-accordion-arrow {
|
|
2464
|
+
transform: rotate(180deg);
|
|
2465
|
+
}
|
|
2466
|
+
|
|
2467
|
+
.uvf-accordion-content {
|
|
2468
|
+
max-height: 0;
|
|
2469
|
+
overflow: hidden;
|
|
2470
|
+
transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1), padding 0.3s ease;
|
|
2471
|
+
padding: 0 18px;
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2474
|
+
.uvf-accordion-item.expanded .uvf-accordion-content {
|
|
2475
|
+
max-height: 300px;
|
|
2476
|
+
padding: 8px 18px 16px;
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
.uvf-settings-empty {
|
|
2480
|
+
padding: 20px;
|
|
2481
|
+
text-align: center;
|
|
2482
|
+
color: rgba(255,255,255,0.6);
|
|
2483
|
+
font-size: 14px;
|
|
2484
|
+
}
|
|
2485
|
+
|
|
2405
2486
|
.uvf-settings-group {
|
|
2406
2487
|
padding: 10px 0;
|
|
2407
2488
|
border-bottom: 1px solid rgba(255,255,255,0.1);
|
|
@@ -5029,11 +5110,44 @@ export class WebPlayer extends BasePlayer {
|
|
|
5029
5110
|
|
|
5030
5111
|
// Settings menu - dynamically populated
|
|
5031
5112
|
const settingsMenu = document.getElementById('uvf-settings-menu');
|
|
5113
|
+
this.debugLog('Settings menu element found:', !!settingsMenu);
|
|
5114
|
+
this.debugLog('Settings button found:', !!settingsBtn);
|
|
5115
|
+
|
|
5032
5116
|
settingsBtn?.addEventListener('click', (e) => {
|
|
5033
5117
|
e.stopPropagation();
|
|
5118
|
+
this.debugLog('Settings button clicked!');
|
|
5119
|
+
this.debugLog('Settings menu before update:', settingsMenu?.innerHTML?.length || 0, 'characters');
|
|
5120
|
+
|
|
5034
5121
|
// Update the menu content before showing it
|
|
5035
5122
|
this.updateSettingsMenu();
|
|
5123
|
+
|
|
5124
|
+
this.debugLog('Settings menu after update:', settingsMenu?.innerHTML?.length || 0, 'characters');
|
|
5125
|
+
this.debugLog('Settings menu classes before toggle:', Array.from(settingsMenu?.classList || []).join(' '));
|
|
5126
|
+
|
|
5036
5127
|
settingsMenu?.classList.toggle('active');
|
|
5128
|
+
|
|
5129
|
+
// Force visibility if menu is not showing properly
|
|
5130
|
+
if (settingsMenu && settingsMenu.classList.contains('active')) {
|
|
5131
|
+
settingsMenu.style.display = 'block';
|
|
5132
|
+
settingsMenu.style.visibility = 'visible';
|
|
5133
|
+
settingsMenu.style.opacity = '1';
|
|
5134
|
+
settingsMenu.style.transform = 'translateY(0)';
|
|
5135
|
+
settingsMenu.style.zIndex = '9999';
|
|
5136
|
+
settingsMenu.style.position = 'absolute';
|
|
5137
|
+
settingsMenu.style.bottom = '50px';
|
|
5138
|
+
settingsMenu.style.right = '0';
|
|
5139
|
+
settingsMenu.style.background = 'rgba(0,0,0,0.9)';
|
|
5140
|
+
settingsMenu.style.border = '1px solid rgba(255,255,255,0.2)';
|
|
5141
|
+
settingsMenu.style.borderRadius = '8px';
|
|
5142
|
+
settingsMenu.style.minWidth = '200px';
|
|
5143
|
+
settingsMenu.style.padding = '10px 0';
|
|
5144
|
+
this.debugLog('Applied fallback styles to force menu visibility');
|
|
5145
|
+
}
|
|
5146
|
+
|
|
5147
|
+
this.debugLog('Settings menu classes after toggle:', Array.from(settingsMenu?.classList || []).join(' '));
|
|
5148
|
+
this.debugLog('Settings menu computed display:', window.getComputedStyle(settingsMenu || document.body).display);
|
|
5149
|
+
this.debugLog('Settings menu computed visibility:', window.getComputedStyle(settingsMenu || document.body).visibility);
|
|
5150
|
+
this.debugLog('Settings menu computed opacity:', window.getComputedStyle(settingsMenu || document.body).opacity);
|
|
5037
5151
|
});
|
|
5038
5152
|
|
|
5039
5153
|
// EPG button
|
|
@@ -6288,67 +6402,129 @@ export class WebPlayer extends BasePlayer {
|
|
|
6288
6402
|
* Dynamically populate settings menu based on video capabilities
|
|
6289
6403
|
*/
|
|
6290
6404
|
private updateSettingsMenu(): void {
|
|
6405
|
+
this.debugLog('updateSettingsMenu called');
|
|
6291
6406
|
const settingsMenu = document.getElementById('uvf-settings-menu');
|
|
6292
|
-
if (!settingsMenu)
|
|
6407
|
+
if (!settingsMenu) {
|
|
6408
|
+
this.debugError('Settings menu element not found!');
|
|
6409
|
+
return;
|
|
6410
|
+
}
|
|
6293
6411
|
|
|
6412
|
+
this.debugLog('Settings menu element found, updating content...');
|
|
6294
6413
|
// Detect available qualities from video
|
|
6295
6414
|
this.detectAvailableQualities();
|
|
6296
6415
|
// Detect available subtitles
|
|
6297
6416
|
this.detectAvailableSubtitles();
|
|
6298
6417
|
|
|
6299
|
-
|
|
6418
|
+
this.debugLog('Available qualities:', this.availableQualities);
|
|
6419
|
+
this.debugLog('Available subtitles:', this.availableSubtitles);
|
|
6420
|
+
this.debugLog('Settings config:', this.settingsConfig);
|
|
6300
6421
|
|
|
6301
|
-
//
|
|
6422
|
+
// Generate accordion-style menu
|
|
6423
|
+
this.generateAccordionMenu();
|
|
6424
|
+
}
|
|
6425
|
+
|
|
6426
|
+
/**
|
|
6427
|
+
* Generate accordion-style settings menu
|
|
6428
|
+
*/
|
|
6429
|
+
private generateAccordionMenu(): void {
|
|
6430
|
+
const settingsMenu = document.getElementById('uvf-settings-menu');
|
|
6431
|
+
if (!settingsMenu) return;
|
|
6432
|
+
|
|
6433
|
+
let menuHTML = '<div class="uvf-settings-accordion">';
|
|
6434
|
+
|
|
6435
|
+
// Playback Speed Accordion Section (only if enabled in config)
|
|
6302
6436
|
if (this.settingsConfig.speed) {
|
|
6437
|
+
const currentSpeedLabel = this.currentPlaybackRate === 1 ? 'Normal' : `${this.currentPlaybackRate}x`;
|
|
6303
6438
|
menuHTML += `
|
|
6304
|
-
<div class="uvf-
|
|
6305
|
-
<div class="uvf-
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
<div class="uvf-
|
|
6439
|
+
<div class="uvf-accordion-item">
|
|
6440
|
+
<div class="uvf-accordion-header" data-section="speed">
|
|
6441
|
+
<div class="uvf-accordion-title">
|
|
6442
|
+
<span class="uvf-accordion-icon">⚡</span>
|
|
6443
|
+
<span>Playback Speed</span>
|
|
6444
|
+
</div>
|
|
6445
|
+
<div class="uvf-accordion-current">${currentSpeedLabel}</div>
|
|
6446
|
+
<div class="uvf-accordion-arrow">▼</div>
|
|
6447
|
+
</div>
|
|
6448
|
+
<div class="uvf-accordion-content" data-section="speed">
|
|
6449
|
+
<div class="uvf-settings-option speed-option ${this.currentPlaybackRate === 0.25 ? 'active' : ''}" data-speed="0.25">0.25x</div>
|
|
6450
|
+
<div class="uvf-settings-option speed-option ${this.currentPlaybackRate === 0.5 ? 'active' : ''}" data-speed="0.5">0.5x</div>
|
|
6451
|
+
<div class="uvf-settings-option speed-option ${this.currentPlaybackRate === 0.75 ? 'active' : ''}" data-speed="0.75">0.75x</div>
|
|
6452
|
+
<div class="uvf-settings-option speed-option ${this.currentPlaybackRate === 1 ? 'active' : ''}" data-speed="1">Normal</div>
|
|
6453
|
+
<div class="uvf-settings-option speed-option ${this.currentPlaybackRate === 1.25 ? 'active' : ''}" data-speed="1.25">1.25x</div>
|
|
6454
|
+
<div class="uvf-settings-option speed-option ${this.currentPlaybackRate === 1.5 ? 'active' : ''}" data-speed="1.5">1.5x</div>
|
|
6455
|
+
<div class="uvf-settings-option speed-option ${this.currentPlaybackRate === 1.75 ? 'active' : ''}" data-speed="1.75">1.75x</div>
|
|
6456
|
+
<div class="uvf-settings-option speed-option ${this.currentPlaybackRate === 2 ? 'active' : ''}" data-speed="2">2x</div>
|
|
6457
|
+
</div>
|
|
6314
6458
|
</div>`;
|
|
6315
6459
|
}
|
|
6316
6460
|
|
|
6317
|
-
// Quality Section (only if enabled in config and qualities detected)
|
|
6461
|
+
// Quality Accordion Section (only if enabled in config and qualities detected)
|
|
6318
6462
|
if (this.settingsConfig.quality && this.availableQualities.length > 0) {
|
|
6319
|
-
|
|
6320
|
-
|
|
6463
|
+
const currentQuality = this.availableQualities.find(q => q.value === this.currentQuality);
|
|
6464
|
+
const currentQualityLabel = currentQuality ? currentQuality.label : 'Auto';
|
|
6465
|
+
|
|
6466
|
+
menuHTML += `
|
|
6467
|
+
<div class="uvf-accordion-item">
|
|
6468
|
+
<div class="uvf-accordion-header" data-section="quality">
|
|
6469
|
+
<div class="uvf-accordion-title">
|
|
6470
|
+
<span class="uvf-accordion-icon">🎬</span>
|
|
6471
|
+
<span>Quality</span>
|
|
6472
|
+
</div>
|
|
6473
|
+
<div class="uvf-accordion-current">${currentQualityLabel}</div>
|
|
6474
|
+
<div class="uvf-accordion-arrow">▼</div>
|
|
6475
|
+
</div>
|
|
6476
|
+
<div class="uvf-accordion-content" data-section="quality">`;
|
|
6321
6477
|
|
|
6322
6478
|
this.availableQualities.forEach(quality => {
|
|
6323
6479
|
const isActive = quality.value === this.currentQuality ? 'active' : '';
|
|
6324
6480
|
menuHTML += `<div class="uvf-settings-option quality-option ${isActive}" data-quality="${quality.value}">${quality.label}</div>`;
|
|
6325
6481
|
});
|
|
6326
6482
|
|
|
6327
|
-
menuHTML += `</div>`;
|
|
6483
|
+
menuHTML += `</div></div>`;
|
|
6328
6484
|
}
|
|
6329
6485
|
|
|
6330
|
-
// Subtitles Section (only if enabled in config and subtitles available)
|
|
6486
|
+
// Subtitles Accordion Section (only if enabled in config and subtitles available)
|
|
6331
6487
|
if (this.settingsConfig.subtitles && this.availableSubtitles.length > 0) {
|
|
6332
|
-
|
|
6333
|
-
|
|
6488
|
+
const currentSubtitle = this.availableSubtitles.find(s => s.value === this.currentSubtitle);
|
|
6489
|
+
const currentSubtitleLabel = currentSubtitle ? currentSubtitle.label : 'Off';
|
|
6490
|
+
|
|
6491
|
+
menuHTML += `
|
|
6492
|
+
<div class="uvf-accordion-item">
|
|
6493
|
+
<div class="uvf-accordion-header" data-section="subtitles">
|
|
6494
|
+
<div class="uvf-accordion-title">
|
|
6495
|
+
<span class="uvf-accordion-icon">💬</span>
|
|
6496
|
+
<span>Subtitles</span>
|
|
6497
|
+
</div>
|
|
6498
|
+
<div class="uvf-accordion-current">${currentSubtitleLabel}</div>
|
|
6499
|
+
<div class="uvf-accordion-arrow">▼</div>
|
|
6500
|
+
</div>
|
|
6501
|
+
<div class="uvf-accordion-content" data-section="subtitles">`;
|
|
6334
6502
|
|
|
6335
6503
|
this.availableSubtitles.forEach(subtitle => {
|
|
6336
6504
|
const isActive = subtitle.value === this.currentSubtitle ? 'active' : '';
|
|
6337
6505
|
menuHTML += `<div class="uvf-settings-option subtitle-option ${isActive}" data-subtitle="${subtitle.value}">${subtitle.label}</div>`;
|
|
6338
6506
|
});
|
|
6339
6507
|
|
|
6340
|
-
menuHTML += `</div>`;
|
|
6508
|
+
menuHTML += `</div></div>`;
|
|
6341
6509
|
}
|
|
6342
6510
|
|
|
6511
|
+
// Close accordion container
|
|
6512
|
+
menuHTML += '</div>';
|
|
6513
|
+
|
|
6343
6514
|
// If no sections are enabled or available, show a message
|
|
6344
|
-
if (
|
|
6345
|
-
menuHTML = '<div class="uvf-settings-
|
|
6515
|
+
if (menuHTML === '<div class="uvf-settings-accordion"></div>') {
|
|
6516
|
+
menuHTML = '<div class="uvf-settings-accordion"><div class="uvf-settings-empty">No settings available</div></div>';
|
|
6346
6517
|
}
|
|
6347
6518
|
|
|
6519
|
+
this.debugLog('Generated menu HTML length:', menuHTML.length);
|
|
6520
|
+
this.debugLog('Generated menu HTML content:', menuHTML.substring(0, 200) + (menuHTML.length > 200 ? '...' : ''));
|
|
6521
|
+
|
|
6348
6522
|
settingsMenu.innerHTML = menuHTML;
|
|
6523
|
+
this.debugLog('Settings menu HTML set successfully');
|
|
6349
6524
|
|
|
6350
6525
|
// Add event listeners for settings options
|
|
6351
6526
|
this.setupSettingsEventListeners();
|
|
6527
|
+
this.debugLog('Settings event listeners setup complete');
|
|
6352
6528
|
}
|
|
6353
6529
|
|
|
6354
6530
|
/**
|
|
@@ -6428,18 +6604,33 @@ export class WebPlayer extends BasePlayer {
|
|
|
6428
6604
|
}
|
|
6429
6605
|
|
|
6430
6606
|
/**
|
|
6431
|
-
* Setup event listeners for settings menu
|
|
6607
|
+
* Setup event listeners for accordion-style settings menu
|
|
6432
6608
|
*/
|
|
6433
6609
|
private setupSettingsEventListeners(): void {
|
|
6434
6610
|
const settingsMenu = document.getElementById('uvf-settings-menu');
|
|
6435
6611
|
if (!settingsMenu) return;
|
|
6436
6612
|
|
|
6613
|
+
// Accordion header click handlers
|
|
6614
|
+
settingsMenu.querySelectorAll('.uvf-accordion-header').forEach(header => {
|
|
6615
|
+
header.addEventListener('click', (e) => {
|
|
6616
|
+
e.preventDefault();
|
|
6617
|
+
e.stopPropagation();
|
|
6618
|
+
|
|
6619
|
+
const accordionItem = header.parentElement;
|
|
6620
|
+
const section = header.getAttribute('data-section');
|
|
6621
|
+
|
|
6622
|
+
if (accordionItem && section) {
|
|
6623
|
+
this.toggleAccordionSection(accordionItem, section);
|
|
6624
|
+
}
|
|
6625
|
+
});
|
|
6626
|
+
});
|
|
6627
|
+
|
|
6437
6628
|
// Speed options
|
|
6438
6629
|
settingsMenu.querySelectorAll('.speed-option').forEach(option => {
|
|
6439
6630
|
option.addEventListener('click', (e) => {
|
|
6440
6631
|
const speed = parseFloat((e.target as HTMLElement).dataset.speed || '1');
|
|
6441
6632
|
this.setPlaybackRateFromSettings(speed);
|
|
6442
|
-
this.
|
|
6633
|
+
this.updateAccordionAfterSelection('speed');
|
|
6443
6634
|
});
|
|
6444
6635
|
});
|
|
6445
6636
|
|
|
@@ -6448,7 +6639,7 @@ export class WebPlayer extends BasePlayer {
|
|
|
6448
6639
|
option.addEventListener('click', (e) => {
|
|
6449
6640
|
const quality = (e.target as HTMLElement).dataset.quality || 'auto';
|
|
6450
6641
|
this.setQualityFromSettings(quality);
|
|
6451
|
-
this.
|
|
6642
|
+
this.updateAccordionAfterSelection('quality');
|
|
6452
6643
|
});
|
|
6453
6644
|
});
|
|
6454
6645
|
|
|
@@ -6457,10 +6648,53 @@ export class WebPlayer extends BasePlayer {
|
|
|
6457
6648
|
option.addEventListener('click', (e) => {
|
|
6458
6649
|
const subtitle = (e.target as HTMLElement).dataset.subtitle || 'off';
|
|
6459
6650
|
this.setSubtitle(subtitle);
|
|
6460
|
-
this.
|
|
6651
|
+
this.updateAccordionAfterSelection('subtitles');
|
|
6461
6652
|
});
|
|
6462
6653
|
});
|
|
6463
6654
|
}
|
|
6655
|
+
|
|
6656
|
+
/**
|
|
6657
|
+
* Toggle accordion section
|
|
6658
|
+
*/
|
|
6659
|
+
private toggleAccordionSection(accordionItem: Element, section: string): void {
|
|
6660
|
+
const isExpanded = accordionItem.classList.contains('expanded');
|
|
6661
|
+
|
|
6662
|
+
// Close all other sections
|
|
6663
|
+
const settingsMenu = document.getElementById('uvf-settings-menu');
|
|
6664
|
+
if (settingsMenu) {
|
|
6665
|
+
settingsMenu.querySelectorAll('.uvf-accordion-item.expanded').forEach(item => {
|
|
6666
|
+
if (item !== accordionItem) {
|
|
6667
|
+
item.classList.remove('expanded');
|
|
6668
|
+
}
|
|
6669
|
+
});
|
|
6670
|
+
}
|
|
6671
|
+
|
|
6672
|
+
// Toggle current section
|
|
6673
|
+
if (isExpanded) {
|
|
6674
|
+
accordionItem.classList.remove('expanded');
|
|
6675
|
+
} else {
|
|
6676
|
+
accordionItem.classList.add('expanded');
|
|
6677
|
+
}
|
|
6678
|
+
}
|
|
6679
|
+
|
|
6680
|
+
/**
|
|
6681
|
+
* Update accordion after user makes a selection
|
|
6682
|
+
*/
|
|
6683
|
+
private updateAccordionAfterSelection(section: string): void {
|
|
6684
|
+
// Close the accordion section after selection
|
|
6685
|
+
setTimeout(() => {
|
|
6686
|
+
const settingsMenu = document.getElementById('uvf-settings-menu');
|
|
6687
|
+
const accordionItem = settingsMenu?.querySelector(`[data-section="${section}"]`)?.parentElement;
|
|
6688
|
+
|
|
6689
|
+
if (accordionItem) {
|
|
6690
|
+
accordionItem.classList.remove('expanded');
|
|
6691
|
+
}
|
|
6692
|
+
|
|
6693
|
+
// Refresh the menu to update current values
|
|
6694
|
+
this.generateAccordionMenu();
|
|
6695
|
+
this.setupSettingsEventListeners();
|
|
6696
|
+
}, 300);
|
|
6697
|
+
}
|
|
6464
6698
|
|
|
6465
6699
|
/**
|
|
6466
6700
|
* Update active states in settings menu
|