unified-video-framework 1.4.100 → 1.4.102

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.
@@ -1890,8 +1890,8 @@ export class WebPlayer extends BasePlayer {
1890
1890
 
1891
1891
  /* Center Play Button */
1892
1892
  .uvf-center-play-btn {
1893
- width: clamp(64px, 14vw, 96px);
1894
- height: clamp(64px, 14vw, 96px);
1893
+ width: clamp(50px, 14vw, 96px);
1894
+ height: clamp(50px, 14vw, 96px);
1895
1895
  background: linear-gradient(135deg, var(--uvf-accent-1), var(--uvf-accent-2));
1896
1896
  border: 0;
1897
1897
  border-radius: 50%;
@@ -1981,22 +1981,24 @@ export class WebPlayer extends BasePlayer {
1981
1981
 
1982
1982
  /* Progress Bar */
1983
1983
  .uvf-progress-section {
1984
+ width: 100%;
1984
1985
  margin-bottom: 15px;
1985
1986
  }
1986
1987
 
1987
1988
  .uvf-progress-bar-wrapper {
1988
- position: relative;
1989
1989
  width: 100%;
1990
- height: 6px;
1991
- background: rgba(255,255,255,0.1);
1992
- border-radius: 3px;
1990
+ height: 4px;
1991
+ position: relative;
1992
+ background: rgba(255,255,255,0.15);
1993
+ border-radius: 2px;
1993
1994
  cursor: pointer;
1995
+ padding: 12px 0;
1994
1996
  overflow: visible;
1995
- transition: transform 0.2s ease;
1997
+ transition: height 0.2s ease;
1996
1998
  }
1997
1999
 
1998
2000
  .uvf-progress-bar-wrapper:hover {
1999
- transform: scaleY(1.5);
2001
+ height: 6px;
2000
2002
  }
2001
2003
 
2002
2004
  .uvf-progress-buffered {
@@ -2004,39 +2006,134 @@ export class WebPlayer extends BasePlayer {
2004
2006
  top: 0;
2005
2007
  left: 0;
2006
2008
  height: 100%;
2007
- background: rgba(255,255,255,0.2);
2008
- border-radius: 3px;
2009
+ background: rgba(255,255,255,0.35);
2010
+ border-radius: 2px;
2009
2011
  pointer-events: none;
2012
+ transition: width 0.2s ease;
2013
+ z-index: 1;
2010
2014
  }
2011
2015
 
2012
2016
  .uvf-progress-filled {
2013
- position: absolute;
2014
- top: 0;
2015
- left: 0;
2017
+ position: relative;
2016
2018
  height: 100%;
2017
- background: linear-gradient(90deg, var(--uvf-accent-1), var(--uvf-accent-2));
2018
- border-radius: 3px;
2019
+ background: linear-gradient(90deg, #ff5722, #ff7043);
2020
+ border-radius: 2px;
2019
2021
  pointer-events: none;
2020
- box-shadow: 0 0 10px var(--uvf-accent-1-20);
2022
+ transition: width 0.2s ease;
2023
+ z-index: 2;
2021
2024
  }
2022
2025
 
2023
2026
  .uvf-progress-handle {
2024
2027
  position: absolute;
2025
- top: 50%;
2026
- transform: translate(-50%, -50%) scale(0);
2027
- width: 16px;
2028
- height: 16px;
2029
- background: #fff;
2028
+ width: 12px;
2029
+ height: 12px;
2030
+ background: #ffffff;
2031
+ border: 2px solid #ff5722;
2030
2032
  border-radius: 50%;
2031
- box-shadow: 0 0 15px rgba(255,255,255,0.5);
2032
- transition: transform 0.2s ease;
2033
- pointer-events: none;
2033
+ top: 50%;
2034
+ left: 100%;
2035
+ margin-left: -6px;
2036
+ transform: translateY(-50%);
2037
+ opacity: 0;
2038
+ transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
2039
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
2040
+ cursor: grab;
2041
+ z-index: 3;
2034
2042
  }
2035
2043
 
2036
2044
  .uvf-progress-bar-wrapper:hover .uvf-progress-handle {
2037
- transform: translate(-50%, -50%) scale(1);
2045
+ opacity: 1;
2046
+ transform: translateY(-50%) scale(1);
2047
+ }
2048
+
2049
+ .uvf-progress-handle:hover {
2050
+ transform: translateY(-50%) scale(1.15);
2051
+ box-shadow: 0 3px 12px rgba(255, 87, 34, 0.4);
2052
+ }
2053
+
2054
+ .uvf-progress-handle:active,
2055
+ .uvf-progress-handle.dragging {
2056
+ cursor: grabbing;
2057
+ transform: translateY(-50%) scale(1.3);
2058
+ box-shadow: 0 4px 16px rgba(255, 87, 34, 0.6);
2059
+ }
2060
+
2061
+ .uvf-time-tooltip {
2062
+ position: absolute;
2063
+ bottom: 24px;
2064
+ left: 50%;
2065
+ transform: translateX(-50%);
2066
+ background: rgba(0, 0, 0, 0.95);
2067
+ color: #ffffff;
2068
+ padding: 8px 14px;
2069
+ border-radius: 8px;
2070
+ font-size: 13px;
2071
+ font-weight: 600;
2072
+ white-space: nowrap;
2073
+ opacity: 0;
2074
+ transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
2075
+ pointer-events: none;
2076
+ z-index: 4;
2077
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
2078
+ backdrop-filter: blur(12px);
2079
+ border: 1px solid rgba(255, 255, 255, 0.1);
2080
+ }
2081
+
2082
+ .uvf-time-tooltip::after {
2083
+ content: '';
2084
+ position: absolute;
2085
+ bottom: -8px;
2086
+ left: 50%;
2087
+ transform: translateX(-50%);
2088
+ width: 0;
2089
+ height: 0;
2090
+ border-left: 8px solid transparent;
2091
+ border-right: 8px solid transparent;
2092
+ border-top: 8px solid rgba(0, 0, 0, 0.95);
2038
2093
  }
2039
2094
 
2095
+ .uvf-time-tooltip::before {
2096
+ content: '';
2097
+ position: absolute;
2098
+ bottom: -9px;
2099
+ left: 50%;
2100
+ transform: translateX(-50%);
2101
+ width: 0;
2102
+ height: 0;
2103
+ border-left: 9px solid transparent;
2104
+ border-right: 9px solid transparent;
2105
+ border-top: 9px solid rgba(255, 255, 255, 0.1);
2106
+ z-index: -1;
2107
+ }
2108
+
2109
+ .uvf-progress-bar-wrapper:hover .uvf-time-tooltip {
2110
+ opacity: 1;
2111
+ transform: translateX(-50%) translateY(-2px);
2112
+ }
2113
+
2114
+ /* Mobile responsive handle sizing */
2115
+ @media (max-width: 768px) {
2116
+ .uvf-progress-handle {
2117
+ width: 16px;
2118
+ height: 16px;
2119
+ margin-left: -8px;
2120
+ opacity: 0.7; /* Slightly visible always on mobile */
2121
+ }
2122
+
2123
+ .uvf-progress-bar-wrapper:hover .uvf-progress-handle,
2124
+ .uvf-progress-handle:active {
2125
+ opacity: 1;
2126
+ }
2127
+
2128
+ .uvf-progress-handle:hover {
2129
+ transform: translateY(-50%) scale(1.1);
2130
+ }
2131
+
2132
+ .uvf-progress-handle:active,
2133
+ .uvf-progress-handle.dragging {
2134
+ transform: translateY(-50%) scale(1.25);
2135
+ }
2136
+ }
2040
2137
  /* Controls Row */
2041
2138
  .uvf-controls-row {
2042
2139
  display: flex;
@@ -2352,7 +2449,8 @@ export class WebPlayer extends BasePlayer {
2352
2449
  right: 20px;
2353
2450
  z-index: 10;
2354
2451
  display: flex;
2355
- gap: 10px;
2452
+ align-items: center;
2453
+ gap: 12px;
2356
2454
  opacity: 0;
2357
2455
  transform: translateY(-10px);
2358
2456
  transition: all 0.3s ease;
@@ -2451,6 +2549,11 @@ export class WebPlayer extends BasePlayer {
2451
2549
  padding: 4px 8px;
2452
2550
  border-radius: 4px;
2453
2551
  text-transform: uppercase;
2552
+ display: none; /* Hidden by default, only shown when quality info is available */
2553
+ }
2554
+
2555
+ .uvf-quality-badge.active {
2556
+ display: inline-block;
2454
2557
  }
2455
2558
 
2456
2559
  /* Time Tooltip */
@@ -3583,8 +3686,8 @@ export class WebPlayer extends BasePlayer {
3583
3686
  }
3584
3687
 
3585
3688
  .uvf-center-play-btn {
3586
- width: clamp(90px, 14vw, 110px);
3587
- height: clamp(90px, 14vw, 110px);
3689
+ width: clamp(90px, 14vw, 60px);
3690
+ height: clamp(90px, 14vw, 60px);
3588
3691
  background: linear-gradient(135deg, var(--uvf-accent-1), var(--uvf-accent-2));
3589
3692
  border: 0;
3590
3693
  box-shadow: 0 10px 32px var(--uvf-accent-1-20);
@@ -3932,8 +4035,15 @@ export class WebPlayer extends BasePlayer {
3932
4035
  progressBar.id = 'uvf-progress-bar';
3933
4036
  progressBar.innerHTML = `
3934
4037
  <div class="uvf-progress-buffered" id="uvf-progress-buffered"></div>
3935
- <div class="uvf-progress-filled" id="uvf-progress-filled"></div>
3936
- <div class="uvf-progress-handle" id="uvf-progress-handle"></div>
4038
+ <div class="uvf-progress-filled" id="uvf-progress-filled">
4039
+ <div class="uvf-progress-handle" id="uvf-progress-handle"
4040
+ role="slider"
4041
+ tabindex="0"
4042
+ aria-label="Seek"
4043
+ aria-valuemin="0"
4044
+ aria-valuemax="100"
4045
+ aria-valuenow="0"></div>
4046
+ </div>
3937
4047
  <div class="uvf-time-tooltip" id="uvf-time-tooltip">00:00</div>
3938
4048
  `;
3939
4049
  progressSection.appendChild(progressBar);
@@ -4204,12 +4314,72 @@ export class WebPlayer extends BasePlayer {
4204
4314
  this.handleVolumeChange(e as MouseEvent);
4205
4315
  });
4206
4316
 
4317
+
4318
+ // Enhanced progress bar interactions
4319
+ const progressHandle = document.getElementById('uvf-progress-handle') as HTMLElement;
4320
+ const timeTooltip = document.getElementById('uvf-time-tooltip') as HTMLElement;
4321
+
4322
+ // Progress bar click
4323
+ progressBar?.addEventListener('click', (e) => {
4324
+ if (!this.isDragging) {
4325
+ this.handleProgressChange(e as MouseEvent);
4326
+ }
4327
+ });
4328
+
4329
+ // Handle dragging
4330
+ progressHandle?.addEventListener('mousedown', (e) => {
4331
+ e.stopPropagation();
4332
+ this.isDragging = true;
4333
+ progressHandle.classList.add('dragging');
4334
+ });
4335
+
4336
+ // Keyboard support for handle
4337
+ progressHandle?.addEventListener('keydown', (e) => {
4338
+ if (!this.video) return;
4339
+
4340
+ const step = 5; // 5 seconds
4341
+ let handled = false;
4342
+
4343
+ switch(e.key) {
4344
+ case 'ArrowLeft':
4345
+ case 'ArrowDown':
4346
+ this.seek(Math.max(0, this.video.currentTime - step));
4347
+ handled = true;
4348
+ break;
4349
+ case 'ArrowRight':
4350
+ case 'ArrowUp':
4351
+ this.seek(Math.min(this.video.duration, this.video.currentTime + step));
4352
+ handled = true;
4353
+ break;
4354
+ }
4355
+
4356
+ if (handled) {
4357
+ e.preventDefault();
4358
+ e.stopPropagation();
4359
+ }
4360
+ });
4361
+
4362
+ progressBar?.addEventListener('mousedown', (e) => {
4363
+ if (e.target === progressHandle) return;
4364
+ this.isDragging = true;
4365
+ this.handleProgressChange(e as MouseEvent);
4366
+ });
4367
+
4368
+ // Mouse move handler for progress bar tooltip and dragging
4369
+ progressBar?.addEventListener('mousemove', (e) => {
4370
+ if (!this.isDragging) {
4371
+ this.updateTimeTooltip(e as MouseEvent);
4372
+ }
4373
+ });
4374
+
4375
+ // Global mouse events for enhanced dragging
4207
4376
  document.addEventListener('mousemove', (e) => {
4208
4377
  if (this.isVolumeSliding) {
4209
4378
  this.handleVolumeChange(e);
4210
4379
  }
4211
4380
  if (this.isDragging && progressBar) {
4212
4381
  this.handleProgressChange(e);
4382
+ this.updateProgressTooltip(e);
4213
4383
  }
4214
4384
  });
4215
4385
 
@@ -4222,23 +4392,26 @@ export class WebPlayer extends BasePlayer {
4222
4392
  }
4223
4393
  }, 2000);
4224
4394
  }
4225
- this.isDragging = false;
4395
+
4396
+ if (this.isDragging) {
4397
+ this.isDragging = false;
4398
+ progressHandle?.classList.remove('dragging');
4399
+ }
4226
4400
  });
4227
4401
 
4228
- // Progress bar
4229
- progressBar?.addEventListener('click', (e) => this.handleProgressChange(e as MouseEvent));
4230
- progressBar?.addEventListener('mousedown', () => this.isDragging = true);
4231
-
4232
4402
  // Update progress bar
4233
4403
  this.video.addEventListener('timeupdate', () => {
4234
4404
  const progressFilled = document.getElementById('uvf-progress-filled') as HTMLElement;
4235
4405
  const progressHandle = document.getElementById('uvf-progress-handle') as HTMLElement;
4236
- const timeDisplay = document.getElementById('uvf-time-display');
4237
4406
 
4238
- if (this.video && progressFilled && progressHandle) {
4407
+ if (this.video && progressFilled) {
4239
4408
  const percent = (this.video.currentTime / this.video.duration) * 100;
4240
4409
  progressFilled.style.width = percent + '%';
4241
- progressHandle.style.left = percent + '%';
4410
+
4411
+ // Update handle aria-valuenow for accessibility
4412
+ if (progressHandle) {
4413
+ progressHandle.setAttribute('aria-valuenow', percent.toString());
4414
+ }
4242
4415
  }
4243
4416
 
4244
4417
  // Update time display using the dedicated method
@@ -4369,9 +4542,6 @@ export class WebPlayer extends BasePlayer {
4369
4542
  }
4370
4543
  });
4371
4544
 
4372
- // Progress bar hover tooltip
4373
- progressBar?.addEventListener('mousemove', (e) => this.updateTimeTooltip(e as MouseEvent));
4374
- progressBar?.addEventListener('mouseleave', () => this.hideTimeTooltip());
4375
4545
 
4376
4546
  // Settings menu - dynamically populated
4377
4547
  const settingsMenu = document.getElementById('uvf-settings-menu');
@@ -4992,6 +5162,21 @@ export class WebPlayer extends BasePlayer {
4992
5162
  timeTooltip.style.opacity = '0';
4993
5163
  }
4994
5164
  }
5165
+
5166
+ private updateProgressTooltip(e: MouseEvent): void {
5167
+ const progressBar = document.getElementById('uvf-progress-bar');
5168
+ const timeTooltip = document.getElementById('uvf-time-tooltip');
5169
+ if (!progressBar || !timeTooltip || !this.video) return;
5170
+
5171
+ const rect = progressBar.getBoundingClientRect();
5172
+ const position = Math.max(0, Math.min(e.clientX - rect.left, rect.width));
5173
+ const percent = (position / rect.width) * 100;
5174
+ const time = (percent / 100) * this.video.duration;
5175
+
5176
+ timeTooltip.textContent = this.formatTime(time);
5177
+ timeTooltip.style.left = percent + '%';
5178
+ timeTooltip.style.opacity = '1';
5179
+ }
4995
5180
 
4996
5181
 
4997
5182
  private showShortcutIndicator(text: string): void {