@quicktvui/web-renderer 1.0.0

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.
Files changed (56) hide show
  1. package/package.json +24 -0
  2. package/src/adapters/es3-video-player.js +828 -0
  3. package/src/components/Modal.js +119 -0
  4. package/src/components/QtAnimationView.js +678 -0
  5. package/src/components/QtBaseComponent.js +165 -0
  6. package/src/components/QtFastListView.js +1920 -0
  7. package/src/components/QtFlexView.js +799 -0
  8. package/src/components/QtImage.js +203 -0
  9. package/src/components/QtItemFrame.js +239 -0
  10. package/src/components/QtItemStoreView.js +93 -0
  11. package/src/components/QtItemView.js +125 -0
  12. package/src/components/QtListView.js +331 -0
  13. package/src/components/QtLoadingView.js +55 -0
  14. package/src/components/QtPageRootView.js +19 -0
  15. package/src/components/QtPlayMark.js +168 -0
  16. package/src/components/QtProgressBar.js +199 -0
  17. package/src/components/QtQRCode.js +78 -0
  18. package/src/components/QtReplaceChild.js +149 -0
  19. package/src/components/QtRippleView.js +166 -0
  20. package/src/components/QtSeekBar.js +409 -0
  21. package/src/components/QtText.js +679 -0
  22. package/src/components/QtTransitionImage.js +170 -0
  23. package/src/components/QtView.js +706 -0
  24. package/src/components/QtWebView.js +613 -0
  25. package/src/components/TabsView.js +420 -0
  26. package/src/components/ViewPager.js +206 -0
  27. package/src/components/index.js +24 -0
  28. package/src/components/plugins/TextV2Component.js +70 -0
  29. package/src/components/plugins/index.js +7 -0
  30. package/src/core/SceneBuilder.js +58 -0
  31. package/src/core/TVFocusManager.js +2014 -0
  32. package/src/core/asyncLocalStorage.js +175 -0
  33. package/src/core/autoProxy.js +165 -0
  34. package/src/core/componentRegistry.js +84 -0
  35. package/src/core/constants.js +6 -0
  36. package/src/core/index.js +8 -0
  37. package/src/core/moduleUtils.js +36 -0
  38. package/src/core/patches.js +958 -0
  39. package/src/core/templateBinding.js +666 -0
  40. package/src/index.js +246 -0
  41. package/src/modules/AndroidDevelopModule.js +101 -0
  42. package/src/modules/AndroidDeviceModule.js +341 -0
  43. package/src/modules/AndroidNetworkModule.js +178 -0
  44. package/src/modules/AndroidSharedPreferencesModule.js +100 -0
  45. package/src/modules/ESDeviceInfoModule.js +450 -0
  46. package/src/modules/ESGroupDataModule.js +195 -0
  47. package/src/modules/ESIJKAudioPlayerModule.js +477 -0
  48. package/src/modules/ESLocalStorageModule.js +100 -0
  49. package/src/modules/ESLogModule.js +65 -0
  50. package/src/modules/ESModule.js +106 -0
  51. package/src/modules/ESNetworkSpeedModule.js +117 -0
  52. package/src/modules/ESToastModule.js +172 -0
  53. package/src/modules/EsNativeModule.js +117 -0
  54. package/src/modules/FastListModule.js +101 -0
  55. package/src/modules/FocusModule.js +145 -0
  56. package/src/modules/RuntimeDeviceModule.js +176 -0
@@ -0,0 +1,409 @@
1
+ import { QtBaseComponent } from './QtBaseComponent'
2
+
3
+ window.__HIPPY_COMPONENT_REGISTRY__ = window.__HIPPY_COMPONENT_REGISTRY__ || new Map()
4
+
5
+ /**
6
+ * QtSeekBar Component for web platform
7
+ * Supports single and range seek bar with draggable thumb
8
+ */
9
+ export class QtSeekBar extends QtBaseComponent {
10
+ constructor(context, id, pId) {
11
+ super(context, id, pId)
12
+ this.tagName = 'TVSeekBarViewComponent'
13
+ this.dom = document.createElement('div')
14
+ this.dom.style.display = 'block'
15
+ this.dom.style.position = 'relative'
16
+ this.dom.style.cursor = 'pointer'
17
+ window.__HIPPY_COMPONENT_REGISTRY__.set(this.dom, this)
18
+
19
+ // Properties
20
+ this._progress = 0
21
+ this._maxProgress = 100
22
+ this._minProgress = 0
23
+ this._progressHeight = 10
24
+ this._progressRadius = 5
25
+ this._progressColor = '#FF0000'
26
+ this._progressDefaultColor = '#CCCCCC'
27
+ this._seekBarMode = 0 // 0: single, 1: range
28
+ this._gravity = 1 // 0: top, 1: center, 2: bottom
29
+
30
+ // Range mode
31
+ this._leftProgress = 0
32
+ this._rightProgress = 100
33
+
34
+ // Thumb
35
+ this._thumbWidth = 30
36
+ this._thumbHeight = 30
37
+ this._thumbColor = '#FFFFFF'
38
+
39
+ // DOM elements
40
+ this._trackEl = null
41
+ this._progressEl = null
42
+ this._thumbEl = null
43
+ this._leftThumbEl = null
44
+ this._rightThumbEl = null
45
+
46
+ // State
47
+ this._isDragging = false
48
+ this._draggingThumb = null // 'main', 'left', 'right'
49
+
50
+ this._initDOM()
51
+ this._bindEvents()
52
+ }
53
+
54
+ _initDOM() {
55
+ // Track (background) - pointer-events: none to allow click to pass through
56
+ this._trackEl = document.createElement('div')
57
+ this._trackEl.style.position = 'absolute'
58
+ this._trackEl.style.left = '0'
59
+ this._trackEl.style.width = '100%'
60
+ this._trackEl.style.boxSizing = 'border-box'
61
+ this._trackEl.style.pointerEvents = 'none'
62
+ this.dom.appendChild(this._trackEl)
63
+
64
+ // Progress
65
+ this._progressEl = document.createElement('div')
66
+ this._progressEl.style.position = 'absolute'
67
+ this._progressEl.style.left = '0'
68
+ this._progressEl.style.boxSizing = 'border-box'
69
+ this._progressEl.style.pointerEvents = 'none'
70
+ this.dom.appendChild(this._progressEl)
71
+
72
+ // Main thumb (single mode)
73
+ this._thumbEl = document.createElement('div')
74
+ this._thumbEl.style.position = 'absolute'
75
+ this._thumbEl.style.boxSizing = 'border-box'
76
+ this._thumbEl.style.borderRadius = '50%'
77
+ this._thumbEl.style.display = 'none'
78
+ this._thumbEl.style.zIndex = '10'
79
+ this._thumbEl.style.pointerEvents = 'none'
80
+ this.dom.appendChild(this._thumbEl)
81
+
82
+ // Left thumb (range mode)
83
+ this._leftThumbEl = document.createElement('div')
84
+ this._leftThumbEl.style.position = 'absolute'
85
+ this._leftThumbEl.style.boxSizing = 'border-box'
86
+ this._leftThumbEl.style.borderRadius = '50%'
87
+ this._leftThumbEl.style.display = 'none'
88
+ this._leftThumbEl.style.zIndex = '10'
89
+ this._leftThumbEl.style.pointerEvents = 'none'
90
+ this.dom.appendChild(this._leftThumbEl)
91
+
92
+ // Right thumb (range mode)
93
+ this._rightThumbEl = document.createElement('div')
94
+ this._rightThumbEl.style.position = 'absolute'
95
+ this._rightThumbEl.style.boxSizing = 'border-box'
96
+ this._rightThumbEl.style.borderRadius = '50%'
97
+ this._rightThumbEl.style.display = 'none'
98
+ this._rightThumbEl.style.zIndex = '10'
99
+ this._rightThumbEl.style.pointerEvents = 'none'
100
+ this.dom.appendChild(this._rightThumbEl)
101
+ }
102
+
103
+ _bindEvents() {
104
+ const onPointerDown = (e) => {
105
+ this._isDragging = true
106
+ this._handlePointerEvent(e)
107
+ document.addEventListener('pointermove', onPointerMove)
108
+ document.addEventListener('pointerup', onPointerUp)
109
+ }
110
+
111
+ const onPointerMove = (e) => {
112
+ if (this._isDragging) {
113
+ this._handlePointerEvent(e)
114
+ }
115
+ }
116
+
117
+ const onPointerUp = () => {
118
+ this._isDragging = false
119
+ this._draggingThumb = null
120
+ document.removeEventListener('pointermove', onPointerMove)
121
+ document.removeEventListener('pointerup', onPointerUp)
122
+ }
123
+
124
+ this.dom.addEventListener('pointerdown', onPointerDown)
125
+ }
126
+
127
+ _handlePointerEvent(e) {
128
+ const rect = this.dom.getBoundingClientRect()
129
+ const x = e.clientX - rect.left
130
+ const percentage = Math.max(0, Math.min(1, x / rect.width))
131
+
132
+ if (this._seekBarMode === 1) {
133
+ // Range mode - determine which thumb to move
134
+ const leftPercent = this._leftProgress / this._maxProgress
135
+ const rightPercent = this._rightProgress / this._maxProgress
136
+
137
+ if (!this._draggingThumb) {
138
+ const distToLeft = Math.abs(percentage - leftPercent)
139
+ const distToRight = Math.abs(percentage - rightPercent)
140
+ this._draggingThumb = distToLeft < distToRight ? 'left' : 'right'
141
+ }
142
+
143
+ if (this._draggingThumb === 'left') {
144
+ this._leftProgress = Math.min(percentage * this._maxProgress, this._rightProgress - 1)
145
+ } else {
146
+ this._rightProgress = Math.max(percentage * this._maxProgress, this._leftProgress + 1)
147
+ }
148
+ } else {
149
+ // Single mode
150
+ this._progress = percentage * this._maxProgress
151
+ }
152
+
153
+ this._updateStyles()
154
+ this._dispatchChangeEvent()
155
+ }
156
+
157
+ _dispatchChangeEvent() {
158
+ const event = new CustomEvent('onSeekBarChange', {
159
+ detail: {
160
+ progress: this._progress,
161
+ leftProgress: this._leftProgress,
162
+ rightProgress: this._rightProgress,
163
+ fromUser: true,
164
+ },
165
+ })
166
+ this.dom.dispatchEvent(event)
167
+ }
168
+
169
+ _updateStyles() {
170
+ if (!this._trackEl || !this._progressEl) {
171
+ console.warn('[QtSeekBar] _updateStyles called before DOM elements ready')
172
+ return
173
+ }
174
+
175
+ const height = this._progressHeight
176
+ const radius = this._progressRadius + 'px'
177
+ const rect = this.dom.getBoundingClientRect()
178
+ const containerHeight = rect.height || 200
179
+ console.log(
180
+ '[QtSeekBar] _updateStyles - containerHeight:',
181
+ containerHeight,
182
+ 'rect:',
183
+ rect.width,
184
+ 'x',
185
+ rect.height
186
+ )
187
+
188
+ // Calculate vertical position based on gravity
189
+ let top
190
+ if (this._gravity === 0) {
191
+ top = 0
192
+ } else if (this._gravity === 2) {
193
+ top = containerHeight - height
194
+ } else {
195
+ top = (containerHeight - height) / 2
196
+ }
197
+
198
+ // Track
199
+ this._trackEl.style.top = top + 'px'
200
+ this._trackEl.style.height = height + 'px'
201
+ this._trackEl.style.borderRadius = radius
202
+ this._trackEl.style.backgroundColor = this._progressDefaultColor
203
+
204
+ // Progress
205
+ this._progressEl.style.top = top + 'px'
206
+ this._progressEl.style.height = height + 'px'
207
+ this._progressEl.style.borderRadius = radius
208
+ this._progressEl.style.backgroundColor = this._progressColor
209
+
210
+ if (this._seekBarMode === 1) {
211
+ // Range mode
212
+ const leftPercent = (this._leftProgress / this._maxProgress) * 100
213
+ const rightPercent = (this._rightProgress / this._maxProgress) * 100
214
+ console.log(
215
+ '[QtSeekBar] _updateStyles RANGE mode - leftPercent:',
216
+ leftPercent,
217
+ 'rightPercent:',
218
+ rightPercent
219
+ )
220
+
221
+ this._progressEl.style.left = leftPercent + '%'
222
+ this._progressEl.style.width = rightPercent - leftPercent + '%'
223
+
224
+ // Hide main thumb
225
+ this._thumbEl.style.display = 'none'
226
+
227
+ // Left thumb
228
+ this._leftThumbEl.style.display = 'block'
229
+ this._leftThumbEl.style.width = this._thumbWidth + 'px'
230
+ this._leftThumbEl.style.height = this._thumbHeight + 'px'
231
+ this._leftThumbEl.style.backgroundColor = this._thumbColor
232
+ this._leftThumbEl.style.left = `calc(${leftPercent}% - ${this._thumbWidth / 2}px)`
233
+ this._leftThumbEl.style.top = top + height / 2 - this._thumbHeight / 2 + 'px'
234
+
235
+ // Right thumb
236
+ this._rightThumbEl.style.display = 'block'
237
+ this._rightThumbEl.style.width = this._thumbWidth + 'px'
238
+ this._rightThumbEl.style.height = this._thumbHeight + 'px'
239
+ this._rightThumbEl.style.backgroundColor = this._thumbColor
240
+ this._rightThumbEl.style.left = `calc(${rightPercent}% - ${this._thumbWidth / 2}px)`
241
+ this._rightThumbEl.style.top = top + height / 2 - this._thumbHeight / 2 + 'px'
242
+ } else {
243
+ // Single mode
244
+ const percent = Math.min(100, (this._progress / this._maxProgress) * 100)
245
+ console.log(
246
+ '[QtSeekBar] _updateStyles - progress:',
247
+ this._progress,
248
+ 'maxProgress:',
249
+ this._maxProgress,
250
+ 'percent:',
251
+ percent
252
+ )
253
+
254
+ this._progressEl.style.left = '0'
255
+ this._progressEl.style.width = percent + '%'
256
+
257
+ // Show main thumb
258
+ this._thumbEl.style.display = 'block'
259
+ this._thumbEl.style.width = this._thumbWidth + 'px'
260
+ this._thumbEl.style.height = this._thumbHeight + 'px'
261
+ this._thumbEl.style.backgroundColor = this._thumbColor
262
+ this._thumbEl.style.left = `calc(${percent}% - ${this._thumbWidth / 2}px)`
263
+ this._thumbEl.style.top = top + height / 2 - this._thumbHeight / 2 + 'px'
264
+
265
+ // Hide range thumbs
266
+ this._leftThumbEl.style.display = 'none'
267
+ this._rightThumbEl.style.display = 'none'
268
+ }
269
+ }
270
+
271
+ updateProperty(key, value) {
272
+ switch (key) {
273
+ case 'progress':
274
+ this._progress = value || 0
275
+ this._updateStyles()
276
+ break
277
+ case 'maxProgress':
278
+ case 'max-progress':
279
+ this._maxProgress = value || 100
280
+ this._updateStyles()
281
+ break
282
+ case 'progressHeight':
283
+ case 'progress-height':
284
+ this._progressHeight = value || 10
285
+ this._updateStyles()
286
+ break
287
+ case 'progressRadius':
288
+ case 'progress-radius':
289
+ this._progressRadius = value || 5
290
+ this._updateStyles()
291
+ break
292
+ case 'progressColor':
293
+ case 'progress-color':
294
+ this._progressColor = value || '#FF0000'
295
+ this._updateStyles()
296
+ break
297
+ case 'progressDefaultColor':
298
+ case 'progress-default-color':
299
+ this._progressDefaultColor = value || '#CCCCCC'
300
+ this._updateStyles()
301
+ break
302
+ case 'seekBarMode':
303
+ case 'seek-bar-mode':
304
+ this._seekBarMode = value || 0
305
+ this._updateStyles()
306
+ break
307
+ case 'gravity':
308
+ this._gravity = value || 1
309
+ this._updateStyles()
310
+ break
311
+ case 'thumbWidth':
312
+ case 'thumb-width':
313
+ this._thumbWidth = value || 30
314
+ this._updateStyles()
315
+ break
316
+ case 'thumbHeight':
317
+ case 'thumb-height':
318
+ this._thumbHeight = value || 30
319
+ this._updateStyles()
320
+ break
321
+ default:
322
+ super.updateProperty(key, value)
323
+ }
324
+ }
325
+
326
+ // API methods (called via callUIFunction with params array)
327
+ setProgress(params) {
328
+ const value = params[0]
329
+ console.log('[QtSeekBar] setProgress called with:', value, 'params:', params)
330
+ this._progress = value || 0
331
+ // In range mode, also update right progress
332
+ if (this._seekBarMode === 1) {
333
+ this._rightProgress = this._progress
334
+ }
335
+ this._updateStyles()
336
+ }
337
+
338
+ setMaxProgress(params) {
339
+ this._maxProgress = params[0] || 100
340
+ this._updateStyles()
341
+ }
342
+
343
+ setProgressHeight(params) {
344
+ this._progressHeight = params[0] || 10
345
+ this._updateStyles()
346
+ }
347
+
348
+ setProgressRadius(params) {
349
+ this._progressRadius = params[0] || 5
350
+ this._updateStyles()
351
+ }
352
+
353
+ setProgressColor(params) {
354
+ this._progressColor = params[0] || '#FF0000'
355
+ this._updateStyles()
356
+ }
357
+
358
+ setProgressDefaultColor(params) {
359
+ this._progressDefaultColor = params[0] || '#CCCCCC'
360
+ this._updateStyles()
361
+ }
362
+
363
+ setSeekBarMode(params) {
364
+ this._seekBarMode = params[0] || 0
365
+ this._updateStyles()
366
+ }
367
+
368
+ setGravity(params) {
369
+ this._gravity = params[0] || 1
370
+ this._updateStyles()
371
+ }
372
+
373
+ setRangeProgress(params) {
374
+ this._leftProgress = params[0] || 0
375
+ this._rightProgress = params[1] || 100
376
+ this._updateStyles()
377
+ }
378
+
379
+ setRange(params) {
380
+ this._minProgress = params[0] || 0
381
+ this._maxProgress = params[1] || 100
382
+ // params[2] is minInterval
383
+ this._updateStyles()
384
+ }
385
+
386
+ resetSeekbar() {
387
+ this._progress = 0
388
+ this._leftProgress = 0
389
+ this._rightProgress = this._maxProgress
390
+ this._updateStyles()
391
+ }
392
+
393
+ init(props) {
394
+ super.init(props)
395
+
396
+ if (props.progress !== undefined) this._progress = props.progress
397
+ if (props.maxProgress !== undefined) this._maxProgress = props.maxProgress
398
+ if (props.progressHeight !== undefined) this._progressHeight = props.progressHeight
399
+ if (props.progressRadius !== undefined) this._progressRadius = props.progressRadius
400
+ if (props.progressColor !== undefined) this._progressColor = props.progressColor
401
+ if (props.progressDefaultColor !== undefined)
402
+ this._progressDefaultColor = props.progressDefaultColor
403
+ if (props.seekBarMode !== undefined) this._seekBarMode = props.seekBarMode
404
+ if (props.gravity !== undefined) this._gravity = props.gravity
405
+
406
+ // Delayed render to ensure container has dimensions
407
+ requestAnimationFrame(() => this._updateStyles())
408
+ }
409
+ }