unified-video-framework 1.4.111 → 1.4.113

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.
@@ -1799,10 +1799,13 @@ export class WebPlayer extends BasePlayer {
1799
1799
  position: absolute;
1800
1800
  top: 0;
1801
1801
  left: 0;
1802
- width: 100%;
1803
- height: 100%;
1802
+ // width: 100%;
1803
+ // height: 100%;
1804
+ object-fit: cover !important; /* Will crop sides/top/bottom to fill */
1805
+ width: 100vw !important;
1806
+ height: 100vh !important;
1804
1807
  background: #000;
1805
- object-fit: contain;
1808
+ // object-fit: contain;
1806
1809
  }
1807
1810
 
1808
1811
  .uvf-watermark-layer {
@@ -1989,7 +1992,6 @@ export class WebPlayer extends BasePlayer {
1989
1992
  width: 100%;
1990
1993
  position: relative;
1991
1994
  cursor: pointer;
1992
- padding: 16px 0;
1993
1995
  overflow: visible;
1994
1996
  }
1995
1997
 
@@ -2099,157 +2101,10 @@ export class WebPlayer extends BasePlayer {
2099
2101
  box-shadow: 0 0 20px rgba(255, 87, 34, 0.5);
2100
2102
  }
2101
2103
 
2102
- .uvf-progress-handle {
2103
- position: absolute;
2104
- width: 12px;
2105
- height: 12px;
2106
- background: radial-gradient(circle,
2107
- rgba(255, 255, 255, 0.95) 0%,
2108
- rgba(255, 255, 255, 0.9) 70%,
2109
- rgba(255, 255, 255, 0.85) 100%
2110
- );
2111
- border: 2px solid rgba(255, 87, 34, 0.8);
2112
- border-radius: 50%;
2113
- top: 50%;
2114
- left: 0%;
2115
- transform: translate(-50%, -50%) scale(0);
2116
- opacity: 0;
2117
- transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
2118
- box-shadow:
2119
- 0 0 0 0 rgba(255, 87, 34, 0.4),
2120
- 0 4px 12px rgba(0, 0, 0, 0.25),
2121
- inset 0 1px 0 rgba(255, 255, 255, 0.4);
2122
- cursor: grab;
2123
- z-index: 3;
2124
- pointer-events: all;
2125
- backdrop-filter: blur(8px);
2126
- }
2127
-
2128
- .uvf-progress-bar-wrapper:hover .uvf-progress-handle {
2129
- opacity: 1;
2130
- transform: translate(-50%, -50%) scale(1);
2131
- box-shadow:
2132
- 0 0 0 4px rgba(255, 87, 34, 0.2),
2133
- 0 6px 20px rgba(0, 0, 0, 0.3),
2134
- inset 0 1px 0 rgba(255, 255, 255, 0.6);
2135
- }
2136
-
2137
- .uvf-progress-handle:hover {
2138
- transform: translate(-50%, -50%) scale(1.25);
2139
- background: radial-gradient(circle,
2140
- rgba(255, 255, 255, 1) 0%,
2141
- rgba(255, 255, 255, 0.95) 70%,
2142
- rgba(255, 255, 255, 0.9) 100%
2143
- );
2144
- border-color: rgba(255, 87, 34, 1);
2145
- box-shadow:
2146
- 0 0 0 6px rgba(255, 87, 34, 0.3),
2147
- 0 8px 25px rgba(255, 87, 34, 0.4),
2148
- inset 0 1px 0 rgba(255, 255, 255, 0.8);
2149
- }
2150
-
2151
- .uvf-progress-handle:active,
2152
- .uvf-progress-handle.dragging {
2153
- cursor: grabbing;
2154
- transform: translate(-50%, -50%) scale(1.4);
2155
- background: radial-gradient(circle,
2156
- rgba(255, 255, 255, 1) 0%,
2157
- rgba(255, 255, 255, 0.98) 50%,
2158
- rgba(255, 255, 255, 0.95) 100%
2159
- );
2160
- border-color: #ff4500;
2161
- box-shadow:
2162
- 0 0 0 8px rgba(255, 87, 34, 0.4),
2163
- 0 12px 35px rgba(255, 69, 0, 0.5),
2164
- inset 0 2px 0 rgba(255, 255, 255, 0.9);
2165
- transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1);
2166
- }
2167
2104
 
2168
- .uvf-time-tooltip {
2169
- position: absolute;
2170
- bottom: 32px;
2171
- left: 0;
2172
- transform: translateX(-50%) translateY(8px) scale(0.9);
2173
- background: linear-gradient(135deg,
2174
- rgba(0, 0, 0, 0.95) 0%,
2175
- rgba(20, 20, 20, 0.92) 50%,
2176
- rgba(0, 0, 0, 0.98) 100%
2177
- );
2178
- color: #ffffff;
2179
- padding: 10px 16px;
2180
- border-radius: 12px;
2181
- font-size: 13px;
2182
- font-weight: 600;
2183
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
2184
- letter-spacing: 0.5px;
2185
- white-space: nowrap;
2186
- opacity: 0;
2187
- transition: all 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
2188
- pointer-events: none;
2189
- z-index: 4;
2190
- box-shadow:
2191
- 0 0 0 1px rgba(255, 255, 255, 0.05),
2192
- 0 8px 32px rgba(0, 0, 0, 0.6),
2193
- 0 2px 8px rgba(0, 0, 0, 0.3),
2194
- inset 0 1px 0 rgba(255, 255, 255, 0.1);
2195
- backdrop-filter: blur(20px) saturate(1.5);
2196
- border: 1px solid rgba(255, 255, 255, 0.08);
2197
- min-width: 52px;
2198
- text-align: center;
2199
- }
2200
-
2201
- /* Glass morphism tooltip arrow with multiple layers */
2202
- .uvf-time-tooltip::after {
2203
- content: '';
2204
- position: absolute;
2205
- bottom: -10px;
2206
- left: 50%;
2207
- transform: translateX(-50%);
2208
- width: 0;
2209
- height: 0;
2210
- border-left: 10px solid transparent;
2211
- border-right: 10px solid transparent;
2212
- border-top: 10px solid rgba(0, 0, 0, 0.95);
2213
- filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
2214
- }
2215
-
2216
- .uvf-time-tooltip::before {
2217
- content: '';
2218
- position: absolute;
2219
- bottom: -11px;
2220
- left: 50%;
2221
- transform: translateX(-50%);
2222
- width: 0;
2223
- height: 0;
2224
- border-left: 11px solid transparent;
2225
- border-right: 11px solid transparent;
2226
- border-top: 11px solid rgba(255, 255, 255, 0.08);
2227
- z-index: -1;
2228
- }
2229
-
2230
- /* Enhanced tooltip animations - Only show via JavaScript, not CSS hover */
2231
- .uvf-time-tooltip.show {
2232
- opacity: 1 !important;
2233
- transform: translateX(-50%) translateY(-2px) scale(1) !important;
2234
- }
2235
-
2236
- /* Tooltip pulse animation on first hover */
2237
- @keyframes tooltipPulse {
2238
- 0% { transform: translateX(-50%) translateY(-2px) scale(1); }
2239
- 50% { transform: translateX(-50%) translateY(-4px) scale(1.05); }
2240
- 100% { transform: translateX(-50%) translateY(-2px) scale(1); }
2241
- }
2242
-
2243
- .uvf-time-tooltip.pulse {
2244
- animation: tooltipPulse 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) once;
2245
- }
2246
2105
 
2247
2106
  /* Mobile responsive design with enhanced touch targets */
2248
2107
  @media (max-width: 768px) {
2249
- .uvf-progress-bar-wrapper {
2250
- padding: 20px 0; /* Larger touch area */
2251
- }
2252
-
2253
2108
  .uvf-progress-bar {
2254
2109
  height: 3px; /* Slightly thicker on mobile */
2255
2110
  }
@@ -2258,51 +2113,8 @@ export class WebPlayer extends BasePlayer {
2258
2113
  height: 5px;
2259
2114
  }
2260
2115
 
2261
- .uvf-progress-handle {
2262
- width: 18px;
2263
- height: 18px;
2264
- opacity: 0.8; /* More visible on mobile for discoverability */
2265
- border-width: 3px;
2266
- box-shadow:
2267
- 0 0 0 2px rgba(255, 87, 34, 0.3),
2268
- 0 6px 16px rgba(0, 0, 0, 0.3),
2269
- inset 0 1px 0 rgba(255, 255, 255, 0.5);
2270
- }
2271
-
2272
- .uvf-progress-bar-wrapper:hover .uvf-progress-handle,
2273
- .uvf-progress-handle:active {
2274
- opacity: 1;
2275
- transform: translate(-50%, -50%) scale(1);
2276
- }
2277
-
2278
- .uvf-progress-handle:hover {
2279
- transform: translate(-50%, -50%) scale(1.15);
2280
- box-shadow:
2281
- 0 0 0 4px rgba(255, 87, 34, 0.4),
2282
- 0 8px 20px rgba(255, 87, 34, 0.35),
2283
- inset 0 2px 0 rgba(255, 255, 255, 0.7);
2284
- }
2285
-
2286
- .uvf-progress-handle:active,
2287
- .uvf-progress-handle.dragging {
2288
- transform: translate(-50%, -50%) scale(1.3);
2289
- box-shadow:
2290
- 0 0 0 6px rgba(255, 87, 34, 0.5),
2291
- 0 10px 25px rgba(255, 69, 0, 0.4),
2292
- inset 0 2px 0 rgba(255, 255, 255, 0.8);
2293
- }
2294
2116
  }
2295
2117
 
2296
- /* High DPI displays optimization */
2297
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
2298
- .uvf-progress-handle {
2299
- background: radial-gradient(circle,
2300
- rgba(255, 255, 255, 0.98) 0%,
2301
- rgba(255, 255, 255, 0.92) 70%,
2302
- rgba(255, 255, 255, 0.88) 100%
2303
- );
2304
- }
2305
- }
2306
2118
  /* Controls Row */
2307
2119
  .uvf-controls-row {
2308
2120
  display: flex;
@@ -4204,15 +4016,7 @@ export class WebPlayer extends BasePlayer {
4204
4016
  <div class="uvf-progress-bar">
4205
4017
  <div class="uvf-progress-buffered" id="uvf-progress-buffered"></div>
4206
4018
  <div class="uvf-progress-filled" id="uvf-progress-filled"></div>
4207
- <div class="uvf-progress-handle" id="uvf-progress-handle"
4208
- role="slider"
4209
- tabindex="0"
4210
- aria-label="Seek"
4211
- aria-valuemin="0"
4212
- aria-valuemax="100"
4213
- aria-valuenow="0"></div>
4214
4019
  </div>
4215
- <div class="uvf-time-tooltip" id="uvf-time-tooltip">00:00</div>
4216
4020
  `;
4217
4021
  progressSection.appendChild(progressBar);
4218
4022
 
@@ -4483,77 +4287,16 @@ export class WebPlayer extends BasePlayer {
4483
4287
  });
4484
4288
 
4485
4289
 
4486
- // Enhanced progress bar interactions
4487
- const progressHandle = document.getElementById('uvf-progress-handle') as HTMLElement;
4488
- const timeTooltip = document.getElementById('uvf-time-tooltip') as HTMLElement;
4489
-
4490
4290
  // Progress bar click
4491
4291
  progressBar?.addEventListener('click', (e) => {
4492
- if (!this.isDragging) {
4493
- this.handleProgressChange(e as MouseEvent);
4494
- }
4495
- });
4496
-
4497
- // Handle dragging
4498
- progressHandle?.addEventListener('mousedown', (e) => {
4499
- e.stopPropagation();
4500
- this.isDragging = true;
4501
- progressHandle.classList.add('dragging');
4502
- });
4503
-
4504
- // Keyboard support for handle
4505
- progressHandle?.addEventListener('keydown', (e) => {
4506
- if (!this.video) return;
4507
-
4508
- const step = 5; // 5 seconds
4509
- let handled = false;
4510
-
4511
- switch(e.key) {
4512
- case 'ArrowLeft':
4513
- case 'ArrowDown':
4514
- this.seek(Math.max(0, this.video.currentTime - step));
4515
- handled = true;
4516
- break;
4517
- case 'ArrowRight':
4518
- case 'ArrowUp':
4519
- this.seek(Math.min(this.video.duration, this.video.currentTime + step));
4520
- handled = true;
4521
- break;
4522
- }
4523
-
4524
- if (handled) {
4525
- e.preventDefault();
4526
- e.stopPropagation();
4527
- }
4292
+ this.handleProgressChange(e as MouseEvent);
4528
4293
  });
4529
4294
 
4530
4295
  progressBar?.addEventListener('mousedown', (e) => {
4531
- if (e.target === progressHandle) return;
4532
4296
  this.isDragging = true;
4533
4297
  this.handleProgressChange(e as MouseEvent);
4534
4298
  });
4535
4299
 
4536
- // Progress bar hover events for tooltip
4537
- progressBar?.addEventListener('mouseenter', () => {
4538
- const timeTooltip = document.getElementById('uvf-time-tooltip');
4539
- if (timeTooltip) {
4540
- timeTooltip.classList.add('show');
4541
- }
4542
- });
4543
-
4544
- progressBar?.addEventListener('mouseleave', () => {
4545
- if (!this.isDragging) {
4546
- this.hideTimeTooltip();
4547
- }
4548
- });
4549
-
4550
- // Mouse move handler for progress bar tooltip and dragging
4551
- progressBar?.addEventListener('mousemove', (e) => {
4552
- if (!this.isDragging) {
4553
- this.updateTimeTooltip(e as MouseEvent);
4554
- }
4555
- });
4556
-
4557
4300
  // Global mouse events for enhanced dragging
4558
4301
  document.addEventListener('mousemove', (e) => {
4559
4302
  if (this.isVolumeSliding) {
@@ -4561,7 +4304,6 @@ export class WebPlayer extends BasePlayer {
4561
4304
  }
4562
4305
  if (this.isDragging && progressBar) {
4563
4306
  this.handleProgressChange(e);
4564
- this.updateProgressTooltip(e);
4565
4307
  }
4566
4308
  });
4567
4309
 
@@ -4577,26 +4319,16 @@ export class WebPlayer extends BasePlayer {
4577
4319
 
4578
4320
  if (this.isDragging) {
4579
4321
  this.isDragging = false;
4580
- progressHandle?.classList.remove('dragging');
4581
- // Hide tooltip after dragging ends
4582
- this.hideTimeTooltip();
4583
4322
  }
4584
4323
  });
4585
4324
 
4586
4325
  // Update progress bar
4587
4326
  this.video.addEventListener('timeupdate', () => {
4588
4327
  const progressFilled = document.getElementById('uvf-progress-filled') as HTMLElement;
4589
- const progressHandle = document.getElementById('uvf-progress-handle') as HTMLElement;
4590
4328
 
4591
- if (this.video && progressFilled && progressHandle) {
4329
+ if (this.video && progressFilled) {
4592
4330
  const percent = (this.video.currentTime / this.video.duration) * 100;
4593
4331
  progressFilled.style.width = percent + '%';
4594
-
4595
- // Position handle at the progress position
4596
- progressHandle.style.left = percent + '%';
4597
-
4598
- // Update handle aria-valuenow for accessibility
4599
- progressHandle.setAttribute('aria-valuenow', percent.toString());
4600
4332
  }
4601
4333
 
4602
4334
  // Update time display using the dedicated method
@@ -5338,75 +5070,6 @@ export class WebPlayer extends BasePlayer {
5338
5070
  }
5339
5071
  }
5340
5072
 
5341
- private updateTimeTooltip(e: MouseEvent): void {
5342
- const wrapper = document.getElementById('uvf-progress-bar');
5343
- const innerBar = wrapper?.querySelector('.uvf-progress-bar') as HTMLElement | null;
5344
- const timeTooltip = document.getElementById('uvf-time-tooltip');
5345
- if (!wrapper || !innerBar || !timeTooltip || !this.video) return;
5346
-
5347
- // Measure against the inner progress bar but position relative to the wrapper
5348
- const wrapperRect = wrapper.getBoundingClientRect();
5349
- const innerRect = innerBar.getBoundingClientRect();
5350
-
5351
- // X within the inner progress bar
5352
- const localX = Math.max(0, Math.min(e.clientX - innerRect.left, innerRect.width));
5353
- const percent = (localX / innerRect.width) * 100;
5354
- const time = (percent / 100) * this.video.duration;
5355
-
5356
- // Pixel position relative to wrapper's left edge
5357
- const leftPx = (innerRect.left - wrapperRect.left) + localX;
5358
-
5359
- // Update tooltip content and position
5360
- timeTooltip.textContent = this.formatTime(time);
5361
- timeTooltip.style.left = `${leftPx}px`;
5362
- timeTooltip.classList.add('show');
5363
-
5364
- // Add pulse animation on first hover
5365
- if (!timeTooltip.classList.contains('pulse') && timeTooltip.classList.contains('show')) {
5366
- timeTooltip.classList.add('pulse');
5367
- setTimeout(() => {
5368
- timeTooltip.classList.remove('pulse');
5369
- }, 600);
5370
- }
5371
- }
5372
-
5373
- private hideTimeTooltip(): void {
5374
- const timeTooltip = document.getElementById('uvf-time-tooltip');
5375
- if (timeTooltip) {
5376
- timeTooltip.classList.remove('show');
5377
- // Remove any inline opacity style to let CSS handle it
5378
- timeTooltip.style.removeProperty('opacity');
5379
- }
5380
- }
5381
-
5382
- private updateProgressTooltip(e: MouseEvent): void {
5383
- const wrapper = document.getElementById('uvf-progress-bar');
5384
- const innerBar = wrapper?.querySelector('.uvf-progress-bar') as HTMLElement | null;
5385
- const timeTooltip = document.getElementById('uvf-time-tooltip');
5386
- const progressHandle = document.getElementById('uvf-progress-handle');
5387
- if (!wrapper || !innerBar || !timeTooltip || !this.video) return;
5388
-
5389
- // Measure against the inner progress bar but position relative to the wrapper
5390
- const wrapperRect = wrapper.getBoundingClientRect();
5391
- const innerRect = innerBar.getBoundingClientRect();
5392
-
5393
- const localX = Math.max(0, Math.min(e.clientX - innerRect.left, innerRect.width));
5394
- const percent = (localX / innerRect.width) * 100;
5395
- const time = (percent / 100) * this.video.duration;
5396
-
5397
- const leftPx = (innerRect.left - wrapperRect.left) + localX;
5398
-
5399
- // Update tooltip content and position
5400
- timeTooltip.textContent = this.formatTime(time);
5401
- timeTooltip.style.left = `${leftPx}px`;
5402
- timeTooltip.classList.add('show');
5403
-
5404
- // Add visual feedback during dragging
5405
- if (progressHandle && this.isDragging) {
5406
- progressHandle.style.transform = 'translate(-50%, -50%) scale(1.4)';
5407
- progressHandle.classList.add('dragging');
5408
- }
5409
- }
5410
5073
 
5411
5074
 
5412
5075
  private showShortcutIndicator(text: string): void {