unified-video-framework 1.4.137 → 1.4.139

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.
@@ -2337,28 +2337,33 @@ export class WebPlayer extends BasePlayer {
2337
2337
  position: absolute;
2338
2338
  bottom: 50px;
2339
2339
  right: 0;
2340
- background: rgba(0,0,0,0.95);
2340
+ background: rgba(0,0,0,0.92);
2341
2341
  backdrop-filter: blur(20px);
2342
- border: 1px solid rgba(255,255,255,0.1);
2342
+ -webkit-backdrop-filter: blur(20px);
2343
+ border: 1px solid rgba(255,255,255,0.15);
2343
2344
  border-radius: 12px;
2344
- padding: 10px 0;
2345
- min-width: 200px;
2345
+ padding: 8px 0;
2346
+ min-width: 220px;
2347
+ max-width: 280px;
2346
2348
  max-height: 60vh;
2347
2349
  overflow-y: auto;
2348
2350
  -webkit-overflow-scrolling: touch;
2349
2351
  overscroll-behavior: contain;
2350
- z-index: 1000; /* Ensure settings menu appears above other elements */
2352
+ z-index: 9999;
2353
+ box-shadow: 0 20px 40px rgba(0,0,0,0.4), 0 8px 25px rgba(0,0,0,0.3);
2351
2354
  /* Firefox */
2352
2355
  scrollbar-width: thin;
2353
- scrollbar-color: var(--uvf-firefox-scrollbar-color) transparent;
2356
+ scrollbar-color: rgba(255,255,255,0.3) transparent;
2354
2357
  /* Avoid layout shift when scrollbar appears */
2355
2358
  scrollbar-gutter: stable both-edges;
2356
2359
  /* Space on the right so content doesn't hug the scrollbar */
2357
- padding-right: 6px;
2360
+ padding-right: 8px;
2361
+ /* Initial hidden state */
2358
2362
  opacity: 0;
2359
2363
  visibility: hidden;
2360
- transform: translateY(10px);
2361
- transition: all 0.3s ease;
2364
+ transform: translateY(15px) scale(0.95);
2365
+ pointer-events: none;
2366
+ transition: opacity 0.25s ease, visibility 0.25s ease, transform 0.25s cubic-bezier(0.4, 0.0, 0.2, 1);
2362
2367
  }
2363
2368
 
2364
2369
  /* WebKit-based browsers (Chrome, Edge, Safari) */
@@ -2399,65 +2404,87 @@ export class WebPlayer extends BasePlayer {
2399
2404
  .uvf-settings-menu.active {
2400
2405
  opacity: 1;
2401
2406
  visibility: visible;
2402
- transform: translateY(0);
2407
+ transform: translateY(0) scale(1);
2408
+ pointer-events: all;
2403
2409
  }
2404
2410
 
2405
- /* Accordion Styles */
2411
+ /* Improved Accordion Styles */
2406
2412
  .uvf-settings-accordion {
2407
- padding: 0;
2413
+ padding: 8px 0;
2408
2414
  }
2409
2415
 
2410
2416
  .uvf-accordion-item {
2411
- border-bottom: 1px solid rgba(255,255,255,0.08);
2417
+ margin-bottom: 2px;
2418
+ border-radius: 8px;
2419
+ overflow: hidden;
2420
+ background: rgba(255,255,255,0.03);
2412
2421
  }
2413
2422
 
2414
2423
  .uvf-accordion-item:last-child {
2415
- border-bottom: none;
2424
+ margin-bottom: 0;
2416
2425
  }
2417
2426
 
2418
2427
  .uvf-accordion-header {
2419
2428
  display: flex;
2420
2429
  align-items: center;
2421
2430
  justify-content: space-between;
2422
- padding: 14px 18px;
2431
+ padding: 12px 16px;
2423
2432
  cursor: pointer;
2424
2433
  transition: all 0.2s ease;
2425
- border-radius: 8px;
2426
- margin: 4px 8px;
2434
+ background: rgba(255,255,255,0.05);
2435
+ border-bottom: 1px solid rgba(255,255,255,0.08);
2427
2436
  }
2428
2437
 
2429
2438
  .uvf-accordion-header:hover {
2439
+ background: rgba(255,255,255,0.1);
2440
+ }
2441
+
2442
+ .uvf-accordion-item.expanded .uvf-accordion-header {
2430
2443
  background: rgba(255,255,255,0.08);
2431
- transform: translateX(2px);
2444
+ border-bottom-color: rgba(255,255,255,0.12);
2432
2445
  }
2433
2446
 
2434
2447
  .uvf-accordion-title {
2435
2448
  display: flex;
2436
2449
  align-items: center;
2437
- gap: 10px;
2438
- font-size: 14px;
2450
+ gap: 8px;
2451
+ font-size: 13px;
2439
2452
  font-weight: 500;
2440
2453
  color: #fff;
2454
+ flex: 1;
2441
2455
  }
2442
2456
 
2443
2457
  .uvf-accordion-icon {
2444
- font-size: 16px;
2445
- opacity: 0.8;
2458
+ display: flex;
2459
+ align-items: center;
2460
+ justify-content: center;
2461
+ opacity: 0.9;
2462
+ width: 16px;
2463
+ height: 16px;
2464
+ }
2465
+
2466
+ .uvf-accordion-icon svg {
2467
+ width: 14px;
2468
+ height: 14px;
2469
+ fill: currentColor;
2446
2470
  }
2447
2471
 
2448
2472
  .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;
2473
+ font-size: 11px;
2474
+ color: var(--uvf-accent-1);
2475
+ background: rgba(255,255,255,0.08);
2476
+ padding: 2px 8px;
2477
+ border-radius: 8px;
2478
+ font-weight: 600;
2479
+ margin-right: 8px;
2455
2480
  }
2456
2481
 
2457
2482
  .uvf-accordion-arrow {
2458
- font-size: 12px;
2459
- color: rgba(255,255,255,0.6);
2460
- transition: transform 0.3s ease;
2483
+ font-size: 10px;
2484
+ color: rgba(255,255,255,0.7);
2485
+ transition: transform 0.25s ease;
2486
+ width: 16px;
2487
+ text-align: center;
2461
2488
  }
2462
2489
 
2463
2490
  .uvf-accordion-item.expanded .uvf-accordion-arrow {
@@ -2467,13 +2494,46 @@ export class WebPlayer extends BasePlayer {
2467
2494
  .uvf-accordion-content {
2468
2495
  max-height: 0;
2469
2496
  overflow: hidden;
2470
- transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1), padding 0.3s ease;
2471
- padding: 0 18px;
2497
+ transition: max-height 0.25s cubic-bezier(0.4, 0, 0.2, 1);
2498
+ background: rgba(0,0,0,0.2);
2472
2499
  }
2473
2500
 
2474
2501
  .uvf-accordion-item.expanded .uvf-accordion-content {
2475
- max-height: 300px;
2476
- padding: 8px 18px 16px;
2502
+ max-height: 250px;
2503
+ }
2504
+
2505
+ /* Settings options within accordion */
2506
+ .uvf-accordion-content .uvf-settings-option {
2507
+ color: #fff;
2508
+ font-size: 13px;
2509
+ padding: 10px 16px;
2510
+ cursor: pointer;
2511
+ transition: all 0.2s ease;
2512
+ border-bottom: 1px solid rgba(255,255,255,0.05);
2513
+ display: flex;
2514
+ align-items: center;
2515
+ justify-content: space-between;
2516
+ }
2517
+
2518
+ .uvf-accordion-content .uvf-settings-option:last-child {
2519
+ border-bottom: none;
2520
+ }
2521
+
2522
+ .uvf-accordion-content .uvf-settings-option:hover {
2523
+ background: rgba(255,255,255,0.06);
2524
+ padding-left: 20px;
2525
+ }
2526
+
2527
+ .uvf-accordion-content .uvf-settings-option.active {
2528
+ color: var(--uvf-accent-1);
2529
+ background: rgba(255,255,255,0.08);
2530
+ font-weight: 600;
2531
+ }
2532
+
2533
+ .uvf-accordion-content .uvf-settings-option.active::after {
2534
+ content: '✓';
2535
+ font-size: 12px;
2536
+ opacity: 0.8;
2477
2537
  }
2478
2538
 
2479
2539
  .uvf-settings-empty {
@@ -4677,7 +4737,7 @@ export class WebPlayer extends BasePlayer {
4677
4737
  settingsMenu.id = 'uvf-settings-menu';
4678
4738
  // Initially empty - will be populated by updateSettingsMenu method
4679
4739
  settingsMenu.innerHTML = '';
4680
- settingsMenu.style.display = 'none';
4740
+ // CSS handles initial hidden state
4681
4741
  settingsContainer.appendChild(settingsMenu);
4682
4742
  rightControls.appendChild(settingsContainer);
4683
4743
 
@@ -5126,22 +5186,29 @@ export class WebPlayer extends BasePlayer {
5126
5186
 
5127
5187
  settingsMenu?.classList.toggle('active');
5128
5188
 
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');
5189
+ // Force visibility if menu is active, hide if not active
5190
+ if (settingsMenu) {
5191
+ if (settingsMenu.classList.contains('active')) {
5192
+ settingsMenu.style.display = 'block';
5193
+ settingsMenu.style.visibility = 'visible';
5194
+ settingsMenu.style.opacity = '1';
5195
+ settingsMenu.style.transform = 'translateY(0)';
5196
+ settingsMenu.style.zIndex = '9999';
5197
+ settingsMenu.style.position = 'absolute';
5198
+ settingsMenu.style.bottom = '50px';
5199
+ settingsMenu.style.right = '0';
5200
+ settingsMenu.style.background = 'rgba(0,0,0,0.9)';
5201
+ settingsMenu.style.border = '1px solid rgba(255,255,255,0.2)';
5202
+ settingsMenu.style.borderRadius = '8px';
5203
+ settingsMenu.style.minWidth = '200px';
5204
+ settingsMenu.style.padding = '10px 0';
5205
+ this.debugLog('Applied fallback styles to show menu');
5206
+ } else {
5207
+ settingsMenu.style.display = 'none';
5208
+ settingsMenu.style.visibility = 'hidden';
5209
+ settingsMenu.style.opacity = '0';
5210
+ this.debugLog('Applied fallback styles to hide menu');
5211
+ }
5145
5212
  }
5146
5213
 
5147
5214
  this.debugLog('Settings menu classes after toggle:', Array.from(settingsMenu?.classList || []).join(' '));
@@ -5172,11 +5239,26 @@ export class WebPlayer extends BasePlayer {
5172
5239
  stopCastBtn?.addEventListener('click', () => this.stopCasting());
5173
5240
  shareBtn?.addEventListener('click', () => this.shareVideo());
5174
5241
 
5175
- // Hide settings menu when clicking outside
5242
+ // Hide settings menu when clicking outside or pressing Escape
5176
5243
  document.addEventListener('click', (e) => {
5177
5244
  if (!(e.target as HTMLElement).closest('#uvf-settings-btn') &&
5178
5245
  !(e.target as HTMLElement).closest('#uvf-settings-menu')) {
5179
5246
  settingsMenu?.classList.remove('active');
5247
+ // Also close any expanded accordions
5248
+ settingsMenu?.querySelectorAll('.uvf-accordion-item.expanded').forEach(item => {
5249
+ item.classList.remove('expanded');
5250
+ });
5251
+ }
5252
+ });
5253
+
5254
+ // Add Escape key handler for settings menu
5255
+ document.addEventListener('keydown', (e) => {
5256
+ if (e.key === 'Escape' && settingsMenu?.classList.contains('active')) {
5257
+ settingsMenu.classList.remove('active');
5258
+ // Also close any expanded accordions
5259
+ settingsMenu.querySelectorAll('.uvf-accordion-item.expanded').forEach(item => {
5260
+ item.classList.remove('expanded');
5261
+ });
5180
5262
  }
5181
5263
  });
5182
5264
  }
@@ -6439,7 +6521,11 @@ export class WebPlayer extends BasePlayer {
6439
6521
  <div class="uvf-accordion-item">
6440
6522
  <div class="uvf-accordion-header" data-section="speed">
6441
6523
  <div class="uvf-accordion-title">
6442
- <span class="uvf-accordion-icon">⚡</span>
6524
+ <span class="uvf-accordion-icon">
6525
+ <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor">
6526
+ <path d="M13,24l11-12L13,0V7.5C5.7,7.5,0,13.2,0,20.5C0,22.4,0.6,24.2,1.6,25.7C4.8,21.8,8.7,19.5,13,19.5V24z"/>
6527
+ </svg>
6528
+ </span>
6443
6529
  <span>Playback Speed</span>
6444
6530
  </div>
6445
6531
  <div class="uvf-accordion-current">${currentSpeedLabel}</div>
@@ -6467,7 +6553,11 @@ export class WebPlayer extends BasePlayer {
6467
6553
  <div class="uvf-accordion-item">
6468
6554
  <div class="uvf-accordion-header" data-section="quality">
6469
6555
  <div class="uvf-accordion-title">
6470
- <span class="uvf-accordion-icon">🎬</span>
6556
+ <span class="uvf-accordion-icon">
6557
+ <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor">
6558
+ <path d="M9,4v3h5V4h4V16H15v-3H9v3H5V4H9z M8,5H6v10h2V11h6v4h2V5h-2v4H8V5z"/>
6559
+ </svg>
6560
+ </span>
6471
6561
  <span>Quality</span>
6472
6562
  </div>
6473
6563
  <div class="uvf-accordion-current">${currentQualityLabel}</div>
@@ -6492,7 +6582,11 @@ export class WebPlayer extends BasePlayer {
6492
6582
  <div class="uvf-accordion-item">
6493
6583
  <div class="uvf-accordion-header" data-section="subtitles">
6494
6584
  <div class="uvf-accordion-title">
6495
- <span class="uvf-accordion-icon">💬</span>
6585
+ <span class="uvf-accordion-icon">
6586
+ <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor">
6587
+ <path d="M20,4H4C2.89,4 2,4.89 2,6V18C2,19.11 2.89,20 4,20H20C21.11,20 22,19.11 22,18V6C22,4.89 21.11,4 20,4M20,18H4V6H20V18M6,10H8V12H6V10M6,14H14V16H6V14M16,14H18V16H16V14M10,10H18V12H10V10Z"/>
6588
+ </svg>
6589
+ </span>
6496
6590
  <span>Subtitles</span>
6497
6591
  </div>
6498
6592
  <div class="uvf-accordion-current">${currentSubtitleLabel}</div>
@@ -6659,41 +6753,35 @@ export class WebPlayer extends BasePlayer {
6659
6753
  private toggleAccordionSection(accordionItem: Element, section: string): void {
6660
6754
  const isExpanded = accordionItem.classList.contains('expanded');
6661
6755
 
6662
- // Close all other sections
6756
+ // If clicking the same section that's already expanded, just close it
6757
+ if (isExpanded) {
6758
+ accordionItem.classList.remove('expanded');
6759
+ return;
6760
+ }
6761
+
6762
+ // Otherwise, close all sections and open the clicked one
6663
6763
  const settingsMenu = document.getElementById('uvf-settings-menu');
6664
6764
  if (settingsMenu) {
6665
6765
  settingsMenu.querySelectorAll('.uvf-accordion-item.expanded').forEach(item => {
6666
- if (item !== accordionItem) {
6667
- item.classList.remove('expanded');
6668
- }
6766
+ item.classList.remove('expanded');
6669
6767
  });
6670
6768
  }
6671
6769
 
6672
- // Toggle current section
6673
- if (isExpanded) {
6674
- accordionItem.classList.remove('expanded');
6675
- } else {
6676
- accordionItem.classList.add('expanded');
6677
- }
6770
+ // Open the clicked section
6771
+ accordionItem.classList.add('expanded');
6678
6772
  }
6679
6773
 
6680
6774
  /**
6681
6775
  * Update accordion after user makes a selection
6682
6776
  */
6683
6777
  private updateAccordionAfterSelection(section: string): void {
6684
- // Close the accordion section after selection
6778
+ // Just update the current values without closing
6779
+ // User can manually close or it will close when they click outside
6685
6780
  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
6781
  // Refresh the menu to update current values
6694
6782
  this.generateAccordionMenu();
6695
6783
  this.setupSettingsEventListeners();
6696
- }, 300);
6784
+ }, 100);
6697
6785
  }
6698
6786
 
6699
6787
  /**