@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,106 @@
1
+ import { resolveAddon, createModuleInit } from '../core/moduleUtils'
2
+
3
+ export class ESModule {
4
+ constructor(context) {
5
+ this.context = context
6
+ this.name = ''
7
+ this.mode = 'normal'
8
+ }
9
+
10
+ async getDeviceInfo(...args) {
11
+ return resolveAddon(args, {})
12
+ }
13
+
14
+ async getESSDKInfo(...args) {
15
+ const result = {
16
+ eskit_ver_code: 2.8, // ES_SDK_VERSION_28
17
+ }
18
+ // 设置全局变量,供 main-web.js 检查初始化状态
19
+ global.__ES_LAST_SDK_INFO__ = result
20
+ return resolveAddon(args, result)
21
+ }
22
+
23
+ async getESSDKVersionCode(...args) {
24
+ return resolveAddon(args, 2.8)
25
+ }
26
+
27
+ async getESSDKVersionName(...args) {
28
+ return resolveAddon(args, 'web')
29
+ }
30
+
31
+ async getESPackageName(...args) {
32
+ const g = globalThis
33
+ const pkg = g && g.__CONFIG__ && g.__CONFIG__.packageName ? g.__CONFIG__.packageName : 'web'
34
+ return resolveAddon(args, pkg)
35
+ }
36
+
37
+ async getESMiniProgramPath(...args) {
38
+ return resolveAddon(args, '')
39
+ }
40
+
41
+ async getESAppFilePath(...args) {
42
+ return resolveAddon(args, '')
43
+ }
44
+
45
+ async getESAppRuntimePath(...args) {
46
+ return resolveAddon(args, '')
47
+ }
48
+
49
+ async getSupportSchemes(...args) {
50
+ return resolveAddon(args, [])
51
+ }
52
+
53
+ sendESNativeMapEventTop(...args) {
54
+ return resolveAddon(args, null)
55
+ }
56
+
57
+ sendESNativeArrayEventTop(...args) {
58
+ return resolveAddon(args, null)
59
+ }
60
+
61
+ sendESNativeMapEventAll(...args) {
62
+ return resolveAddon(args, null)
63
+ }
64
+
65
+ sendESNativeArrayEventAll(...args) {
66
+ return resolveAddon(args, null)
67
+ }
68
+
69
+ launchESPageByArgs(...args) {
70
+ return resolveAddon(args, null)
71
+ }
72
+
73
+ async launchESPage(...args) {
74
+ return resolveAddon(args, null)
75
+ }
76
+
77
+ launchNativeApp(...args) {
78
+ return resolveAddon(args, null)
79
+ }
80
+
81
+ launchNativeAppWithPackage(...args) {
82
+ return resolveAddon(args, null)
83
+ }
84
+
85
+ finish(...args) {
86
+ return resolveAddon(args, null)
87
+ }
88
+
89
+ finishAll(...args) {
90
+ return resolveAddon(args, null)
91
+ }
92
+
93
+ async isModuleRegistered(...args) {
94
+ return resolveAddon(args, false)
95
+ }
96
+
97
+ async isComponentRegistered(...args) {
98
+ return resolveAddon(args, false)
99
+ }
100
+
101
+ async init(...args) {
102
+ return createModuleInit(args)
103
+ }
104
+
105
+ destroy() {}
106
+ }
@@ -0,0 +1,117 @@
1
+ // ESNetworkSpeedModule - Web adapter for Network Speed display
2
+ // Simulates network speed display for web browser
3
+
4
+ let speedInterval = null
5
+ let isRunning = false
6
+
7
+ /**
8
+ * Get EventBus instance
9
+ * @private
10
+ */
11
+ function getEventBus() {
12
+ try {
13
+ const { EventBus } = require('@extscreen/es3-vue')
14
+ return EventBus
15
+ } catch (e) {
16
+ console.warn('[ESNetworkSpeedModule] EventBus not available:', e.message)
17
+ return null
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Generate simulated network speed data
23
+ * @private
24
+ */
25
+ function generateSpeedData() {
26
+ // Simulate varying network speed (100KB/s - 5MB/s)
27
+ const speedKbps = Math.floor(Math.random() * 5000) + 100 // 100-5100 KB/s
28
+ const speedMbps = speedKbps / 1024
29
+
30
+ return {
31
+ speedKbps: speedKbps,
32
+ speedMbps: speedMbps.toFixed(2),
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Emit NetSpeed event via EventBus
38
+ * @private
39
+ */
40
+ function emitNetSpeedEvent() {
41
+ const EventBus = getEventBus()
42
+ if (!EventBus || !EventBus.$emit) {
43
+ return
44
+ }
45
+
46
+ const speedData = generateSpeedData()
47
+ EventBus.$emit('NetSpeed', speedData)
48
+ }
49
+
50
+ export class ESNetworkSpeedModuleClass {
51
+ constructor(context) {
52
+ this.context = context
53
+ this.name = 'ESNetworkSpeedModule'
54
+ }
55
+
56
+ /**
57
+ * Start showing network speed
58
+ * Begins emitting NetSpeed events periodically
59
+ */
60
+ showNetSpeed() {
61
+ if (isRunning) {
62
+ console.log('[ESNetworkSpeedModule] Already running')
63
+ return
64
+ }
65
+
66
+ isRunning = true
67
+ console.log('[ESNetworkSpeedModule] Starting network speed display')
68
+
69
+ // Emit immediately
70
+ emitNetSpeedEvent()
71
+
72
+ // Then emit every 500ms (simulating real-time speed updates)
73
+ speedInterval = setInterval(() => {
74
+ emitNetSpeedEvent()
75
+ }, 500)
76
+ }
77
+
78
+ /**
79
+ * Stop showing network speed
80
+ * Stops emitting NetSpeed events
81
+ */
82
+ stopNetSpeed() {
83
+ if (!isRunning) {
84
+ console.log('[ESNetworkSpeedModule] Not running')
85
+ return
86
+ }
87
+
88
+ console.log('[ESNetworkSpeedModule] Stopping network speed display')
89
+
90
+ if (speedInterval) {
91
+ clearInterval(speedInterval)
92
+ speedInterval = null
93
+ }
94
+ isRunning = false
95
+ }
96
+
97
+ /**
98
+ * Check if speed display is running
99
+ */
100
+ isShowing() {
101
+ return isRunning
102
+ }
103
+
104
+ destroy() {
105
+ this.stopNetSpeed()
106
+ }
107
+
108
+ init() {
109
+ return Promise.resolve(true)
110
+ }
111
+ }
112
+
113
+ // Export class for HippyWebEngine
114
+ export { ESNetworkSpeedModuleClass as ESNetworkSpeedModule }
115
+
116
+ // Export singleton instance for patches.js
117
+ export const esNetworkSpeedModuleInstance = new ESNetworkSpeedModuleClass()
@@ -0,0 +1,172 @@
1
+ // ESToastModule - Web adapter for Toast
2
+ // Displays Android-style toast messages in web browser
3
+
4
+ // Toast container and state
5
+ let toastContainer = null
6
+ let currentToast = null
7
+ let toastQueue = []
8
+ let isShowing = false
9
+
10
+ // Toast duration constants (ms)
11
+ const SHORT_DURATION = 2000
12
+ const LONG_DURATION = 3500
13
+
14
+ // Default toast styles (Android-like)
15
+ const TOAST_STYLES = `
16
+ position: fixed;
17
+ bottom: 80px;
18
+ left: 50%;
19
+ transform: translateX(-50%);
20
+ background-color: rgba(0, 0, 0, 0.8);
21
+ color: #ffffff;
22
+ padding: 12px 24px;
23
+ border-radius: 8px;
24
+ font-size: 14px;
25
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
26
+ max-width: 80%;
27
+ text-align: center;
28
+ z-index: 99999;
29
+ pointer-events: none;
30
+ opacity: 0;
31
+ transition: opacity 200ms ease-in-out;
32
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
33
+ `
34
+
35
+ /**
36
+ * Create or get toast container
37
+ * @private
38
+ */
39
+ function getToastContainer() {
40
+ if (!toastContainer) {
41
+ toastContainer = document.createElement('div')
42
+ toastContainer.id = '__es_toast_container__'
43
+ toastContainer.style.cssText = `
44
+ position: fixed;
45
+ top: 0;
46
+ left: 0;
47
+ width: 100%;
48
+ height: 100%;
49
+ pointer-events: none;
50
+ z-index: 99998;
51
+ `
52
+ document.body.appendChild(toastContainer)
53
+ }
54
+ return toastContainer
55
+ }
56
+
57
+ /**
58
+ * Show a toast message
59
+ * @private
60
+ */
61
+ function showToastMessage(message, duration) {
62
+ const container = getToastContainer()
63
+
64
+ // Queue the toast
65
+ toastQueue.push({ message, duration })
66
+
67
+ // Process queue
68
+ processQueue()
69
+ }
70
+
71
+ /**
72
+ * Process toast queue
73
+ * @private
74
+ */
75
+ function processQueue() {
76
+ if (isShowing || toastQueue.length === 0) {
77
+ return
78
+ }
79
+
80
+ isShowing = true
81
+ const { message, duration } = toastQueue.shift()
82
+
83
+ // Create toast element
84
+ const toast = document.createElement('div')
85
+ toast.className = '__es_toast__'
86
+ toast.textContent = message
87
+ toast.style.cssText = TOAST_STYLES
88
+
89
+ // Add to container
90
+ const container = getToastContainer()
91
+ container.appendChild(toast)
92
+
93
+ // Trigger reflow for animation
94
+ toast.offsetHeight
95
+
96
+ // Show toast
97
+ toast.style.opacity = '1'
98
+
99
+ // Hide and remove after duration
100
+ setTimeout(() => {
101
+ toast.style.opacity = '0'
102
+ setTimeout(() => {
103
+ if (toast.parentNode) {
104
+ toast.parentNode.removeChild(toast)
105
+ }
106
+ isShowing = false
107
+ processQueue()
108
+ }, 200) // Wait for fade out animation
109
+ }, duration)
110
+ }
111
+
112
+ export class ESToastModuleClass {
113
+ constructor(context) {
114
+ this.context = context
115
+ this.name = ''
116
+ this.mode = 'normal'
117
+ }
118
+
119
+ /**
120
+ * Show a toast message (default duration)
121
+ * @param {string} message
122
+ */
123
+ showToast(message) {
124
+ if (typeof message !== 'string') {
125
+ message = String(message)
126
+ }
127
+ showToastMessage(message, SHORT_DURATION)
128
+ }
129
+
130
+ /**
131
+ * Show a long toast message
132
+ * @param {string} message
133
+ */
134
+ showLongToast(message) {
135
+ if (typeof message !== 'string') {
136
+ message = String(message)
137
+ }
138
+ showToastMessage(message, LONG_DURATION)
139
+ }
140
+
141
+ /**
142
+ * Show a short toast message
143
+ * @param {string} message
144
+ */
145
+ showShortToast(message) {
146
+ if (typeof message !== 'string') {
147
+ message = String(message)
148
+ }
149
+ showToastMessage(message, SHORT_DURATION)
150
+ }
151
+
152
+ destroy() {
153
+ // Clean up container
154
+ if (toastContainer && toastContainer.parentNode) {
155
+ toastContainer.parentNode.removeChild(toastContainer)
156
+ toastContainer = null
157
+ }
158
+ toastQueue = []
159
+ isShowing = false
160
+ }
161
+
162
+ init() {
163
+ // Initialize container on demand
164
+ return Promise.resolve(true)
165
+ }
166
+ }
167
+
168
+ // Export class for HippyWebEngine
169
+ export { ESToastModuleClass as ESToastModule }
170
+
171
+ // Export singleton instance for patches.js
172
+ export const esToastModuleInstance = new ESToastModuleClass()
@@ -0,0 +1,117 @@
1
+ // ESNativeModule - Web adapter for ES native module
2
+ // Handles device info, app launching, and page navigation
3
+
4
+ import { resolveAddon, createModuleInit } from '../core/moduleUtils'
5
+
6
+ // Get browser info
7
+ function getBrowserInfo() {
8
+ const ua = navigator.userAgent
9
+ let browser = 'unknown'
10
+ let os = 'unknown'
11
+ let osVersion = ''
12
+
13
+ if (/Windows/i.test(ua)) {
14
+ os = 'windows'
15
+ const match = ua.match(/Windows NT (\d+\.?\d*)/)
16
+ osVersion = match ? match[1] : ''
17
+ } else if (/Mac/i.test(ua)) {
18
+ os = 'mac'
19
+ const match = ua.match(/Mac OS X (\d+[._]\d+[._]?\d*)/)
20
+ osVersion = match ? match[1].replace(/_/g, '.') : ''
21
+ } else if (/Linux/i.test(ua)) {
22
+ os = 'linux'
23
+ } else if (/Android/i.test(ua)) {
24
+ os = 'android'
25
+ const match = ua.match(/Android (\d+\.?\d*\.?\d*)/)
26
+ osVersion = match ? match[1] : ''
27
+ } else if (/iOS|iPhone|iPad/i.test(ua)) {
28
+ os = 'ios'
29
+ const match = ua.match(/OS (\d+_\d+_?\d*)/)
30
+ osVersion = match ? match[1].replace(/_/g, '.') : ''
31
+ }
32
+
33
+ if (/Chrome/i.test(ua) && !/Edge|Edg/i.test(ua)) {
34
+ browser = 'chrome'
35
+ } else if (/Safari/i.test(ua) && !/Chrome/i.test(ua)) {
36
+ browser = 'safari'
37
+ } else if (/Firefox/i.test(ua)) {
38
+ browser = 'firefox'
39
+ } else if (/Edge|Edg/i.test(ua)) {
40
+ browser = 'edge'
41
+ }
42
+
43
+ return { browser, os, osVersion }
44
+ }
45
+
46
+ export class EsNativeModule {
47
+ constructor(context) {
48
+ this.context = context
49
+ this.name = ''
50
+ this.mode = 'normal'
51
+ }
52
+
53
+ async getDeviceInfo(...args) {
54
+ const { browser, os, osVersion } = getBrowserInfo()
55
+ const deviceInfo = {
56
+ deviceType: 'web',
57
+ deviceModel: browser,
58
+ deviceBrand: 'web',
59
+ osName: os,
60
+ osVersion: osVersion,
61
+ screenWidth: window.screen.width || 0,
62
+ screenHeight: window.screen.height || 0,
63
+ screenDensity: window.devicePixelRatio || 1,
64
+ platform: 'web',
65
+ }
66
+ return resolveAddon(args, deviceInfo)
67
+ }
68
+
69
+ async getSupportSchemes(...args) {
70
+ return resolveAddon(args, [])
71
+ }
72
+
73
+ async getVisiblePageSize(...args) {
74
+ return resolveAddon(args, { width: window.innerWidth, height: window.innerHeight })
75
+ }
76
+
77
+ async launchEsPage(...args) {
78
+ console.log('[ESNativeModule] launchEsPage called (web - no-op)')
79
+ return resolveAddon(args, null)
80
+ }
81
+
82
+ async launchNativeApp(...args) {
83
+ console.log('[ESNativeModule] launchNativeApp called (web - no-op)')
84
+ return resolveAddon(args, null)
85
+ }
86
+
87
+ launchNativeAppWithPackage(...args) {
88
+ console.log('[ESNativeModule] launchNativeAppWithPackage called (web - no-op)')
89
+ return resolveAddon(args, null)
90
+ }
91
+
92
+ startService(...args) {
93
+ console.log('[ESNativeModule] startService called (web - no-op)')
94
+ return resolveAddon(args, null)
95
+ }
96
+
97
+ finish(...args) {
98
+ console.log('[ESNativeModule] finish called (web - no-op)')
99
+ return resolveAddon(args, null)
100
+ }
101
+
102
+ finishAll(...args) {
103
+ console.log('[ESNativeModule] finishAll called (web - no-op)')
104
+ return resolveAddon(args, null)
105
+ }
106
+
107
+ async callReflect(...args) {
108
+ console.log('[ESNativeModule] callReflect called (web - no-op)')
109
+ return resolveAddon(args, null)
110
+ }
111
+
112
+ async init(...args) {
113
+ return createModuleInit(args)
114
+ }
115
+
116
+ destroy() {}
117
+ }
@@ -0,0 +1,101 @@
1
+ // FastListModule - Web adapter for FastList animations
2
+ // Provides fade in/out effects for list items
3
+
4
+ import { resolveAddon } from '../core/moduleUtils'
5
+
6
+ // Global fade configuration
7
+ const fadeConfig = {
8
+ enabled: false,
9
+ duration: 300, // default 300ms
10
+ }
11
+
12
+ // Store all FastListView instances for updating
13
+ const fastListInstances = new Set()
14
+
15
+ /**
16
+ * Register a FastListView instance to receive fade config updates
17
+ * @param {QtFastListView} instance
18
+ */
19
+ export function registerFastListInstance(instance) {
20
+ fastListInstances.add(instance)
21
+ }
22
+
23
+ /**
24
+ * Unregister a FastListView instance
25
+ * @param {QtFastListView} instance
26
+ */
27
+ export function unregisterFastListInstance(instance) {
28
+ fastListInstances.delete(instance)
29
+ }
30
+
31
+ /**
32
+ * Get current fade configuration
33
+ * @returns {{enabled: boolean, duration: number}}
34
+ */
35
+ export function getFadeConfig() {
36
+ return { ...fadeConfig }
37
+ }
38
+
39
+ export class FastListModule {
40
+ constructor(context) {
41
+ this.context = context
42
+ this.name = ''
43
+ this.mode = 'normal'
44
+ }
45
+
46
+ /**
47
+ * Enable/disable fade animation for list items
48
+ * @param {boolean} enabled
49
+ */
50
+ setFadeEnabled(enabled, ...args) {
51
+ fadeConfig.enabled = enabled === true
52
+ console.log('[FastListModule] setFadeEnabled:', fadeConfig.enabled)
53
+
54
+ // Update all registered instances
55
+ fastListInstances.forEach((instance) => {
56
+ if (instance && typeof instance.updateFadeConfig === 'function') {
57
+ instance.updateFadeConfig(fadeConfig)
58
+ }
59
+ })
60
+
61
+ return resolveAddon(args, null)
62
+ }
63
+
64
+ /**
65
+ * Set fade animation duration in milliseconds
66
+ * @param {number} duration - duration in ms
67
+ */
68
+ setFadeDuration(duration, ...args) {
69
+ fadeConfig.duration = typeof duration === 'number' ? duration : 300
70
+ console.log('[FastListModule] setFadeDuration:', fadeConfig.duration)
71
+
72
+ // Update all registered instances
73
+ fastListInstances.forEach((instance) => {
74
+ if (instance && typeof instance.updateFadeConfig === 'function') {
75
+ instance.updateFadeConfig(fadeConfig)
76
+ }
77
+ })
78
+
79
+ return resolveAddon(args, null)
80
+ }
81
+
82
+ /**
83
+ * Get current fade configuration
84
+ */
85
+ getFadeConfig(...args) {
86
+ return resolveAddon(args, fadeConfig)
87
+ }
88
+
89
+ async init(...args) {
90
+ const addon = args && args.length ? args[args.length - 1] : null
91
+ if (addon && typeof addon.resolve === 'function') {
92
+ addon.resolve(true)
93
+ }
94
+ return Promise.resolve(true)
95
+ }
96
+
97
+ destroy() {}
98
+ }
99
+
100
+ // Export singleton instance for patches.js
101
+ export const fastListModuleInstance = new FastListModule()