@applicaster/zapp-react-dom-app 16.0.0-alpha.3439504142 → 16.0.0-alpha.3502052160

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.
@@ -65,6 +65,9 @@ export const PLATFORMS = {
65
65
  mobile: "Mobile",
66
66
  vizio: "VIZIO",
67
67
  vidaa: "VIDAA",
68
+ // VIDAA U3 and earlier (2019 and earlier) carry no "VIDAA" token at all —
69
+ // "Hisense" is the only signal on those models. See isVidaaPlatform().
70
+ hisense: "Hisense",
68
71
  smartcast: "SmartCast",
69
72
  conjure: "Conjure",
70
73
  };
@@ -68,6 +68,10 @@ export const isSamsungPlatform = () => {
68
68
  export const isVizioPlatform = () => {
69
69
  const userAgent = getUserAgent();
70
70
 
71
+ if (!userAgent) {
72
+ return false;
73
+ }
74
+
71
75
  return (
72
76
  userAgent.includes(PLATFORMS.vizio) ||
73
77
  userAgent.includes(PLATFORMS.smartcast) ||
@@ -76,13 +80,37 @@ export const isVizioPlatform = () => {
76
80
  };
77
81
 
78
82
  /**
79
- * Checks if the platform is Vida.
80
- * @returns {boolean} True if the platform is Vida, false otherwise.
83
+ * Checks if the platform is VIDAA.
84
+ *
85
+ * Two tokens are needed because the userAgent format changed with VIDAA U4:
86
+ * - 2020 and later (U4/U5/U6/U7): always carries a "VIDAA" token, e.g.
87
+ * `Model/Hisense-MT9602 VIDAA/5.0(Hisense;SmartTV;50A53FSV;...)`
88
+ * - 2019 and earlier (U3 and prior): carries NO "VIDAA" token at all — the only
89
+ * signal is "Hisense", e.g. `Model/Hisense-MSD6586 (Hisense;HE50N3050UWTS;...)`
90
+ *
91
+ * Matching "VIDAA" alone silently misses every U3-and-earlier device, which the
92
+ * VIDAA JS SDK still supports (getDeviceID/getBrand/config are all U3U4U5+).
93
+ *
94
+ * Caveat: "Hisense" also appears in the userAgent of Hisense-branded Android TV
95
+ * models, which are not VIDAA. That is tolerable here because this is only
96
+ * consulted on a VIDAA-targeted build (see getDeviceType), but it is why the
97
+ * vendor docs warn against using "Hisense" as a general-purpose signal. A
98
+ * stricter check would test for the native `Hisense_GetDeviceID` global, which
99
+ * VIDAA exposes from U3 onwards and Android TV does not.
100
+ *
101
+ * @see https://partner-doc.vidaa.com/vdocs/development/open-capacity.html
102
+ * @returns {boolean} True if the platform is VIDAA, false otherwise.
81
103
  */
82
104
  export const isVidaaPlatform = () => {
83
105
  const userAgent = getUserAgent();
84
106
 
85
- return userAgent.includes(PLATFORMS.vidaa);
107
+ if (!userAgent) {
108
+ return false;
109
+ }
110
+
111
+ return (
112
+ userAgent.includes(PLATFORMS.vidaa) || userAgent.includes(PLATFORMS.hisense)
113
+ );
86
114
  };
87
115
 
88
116
  /**
@@ -96,6 +124,133 @@ export const hasVizioAPIs = () => {
96
124
  );
97
125
  };
98
126
 
127
+ /**
128
+ * Checks if the VIDAA JS SDK has finished loading.
129
+ * @returns {boolean} True if the `vidaatv` object is available.
130
+ */
131
+ export const hasVidaaAPIs = () => typeof window?.vidaatv !== "undefined";
132
+
133
+ /** How long to wait for the VIDAA SDK before giving up, in ms. */
134
+ const VIDAA_SDK_TIMEOUT_MS = 3000;
135
+
136
+ /** How often to re-check for the VIDAA SDK while waiting, in ms. */
137
+ const VIDAA_SDK_POLL_MS = 50;
138
+
139
+ /**
140
+ * The value the VIDAA SDK returns for APIs the current platform version does
141
+ * not implement, per the vendor docs ("For features Not Supported by the
142
+ * platform, the interface returns `Not Supported`"). Treated as absent.
143
+ */
144
+ const VIDAA_NOT_SUPPORTED = "Not Supported";
145
+
146
+ /**
147
+ * Waits for the VIDAA JS SDK to become available on `window`.
148
+ *
149
+ * The SDK is injected by loader.js as a dynamically-created <script>, which is
150
+ * async by default and fetched from the VIDAA CDN. The app bundle is served
151
+ * locally and can therefore boot before that request completes, so reading
152
+ * `window.vidaatv` directly at startup is a race. This resolves as soon as the
153
+ * SDK appears, or with `null` once the timeout elapses.
154
+ *
155
+ * Resolves rather than rejects on timeout so a missing SDK degrades to partial
156
+ * device data instead of failing the whole `getDeviceData` call.
157
+ *
158
+ * @param {number} [timeout=VIDAA_SDK_TIMEOUT_MS] Milliseconds to wait.
159
+ * @returns {Promise<object|null>} The `vidaatv` object, or null if it never arrived.
160
+ */
161
+ export const waitForVidaaAPIs = (timeout = VIDAA_SDK_TIMEOUT_MS) => {
162
+ return new Promise((resolve) => {
163
+ if (hasVidaaAPIs()) {
164
+ resolve(window.vidaatv);
165
+
166
+ return;
167
+ }
168
+
169
+ const startedAt = Date.now();
170
+
171
+ const intervalId = setInterval(() => {
172
+ if (hasVidaaAPIs()) {
173
+ clearInterval(intervalId);
174
+ resolve(window.vidaatv);
175
+
176
+ return;
177
+ }
178
+
179
+ if (Date.now() - startedAt >= timeout) {
180
+ clearInterval(intervalId);
181
+ console.warn(
182
+ `waitForVidaaAPIs: VIDAA SDK did not load within ${timeout}ms`
183
+ );
184
+ resolve(null);
185
+ }
186
+ }, VIDAA_SDK_POLL_MS);
187
+ });
188
+ };
189
+
190
+ /**
191
+ * Reads a single value from the VIDAA SDK, tolerating APIs that the current
192
+ * platform version does not implement.
193
+ *
194
+ * Every accessor is optional: older platforms omit the method entirely, and
195
+ * supported-but-unavailable values come back as the string "Not Supported".
196
+ *
197
+ * @param {object} sdk The `vidaatv` object.
198
+ * @param {string} method The accessor name, e.g. "getModelName".
199
+ * @returns {string|null} The value, or null when unavailable.
200
+ */
201
+ const readVidaaValue = (sdk, method) => {
202
+ try {
203
+ if (typeof sdk?.[method] !== "function") {
204
+ return null;
205
+ }
206
+
207
+ const value = sdk[method]();
208
+
209
+ return value && value !== VIDAA_NOT_SUPPORTED ? value : null;
210
+ } catch (error) {
211
+ console.warn(`readVidaaValue: ${method} threw`, error);
212
+
213
+ return null;
214
+ }
215
+ };
216
+
217
+ /**
218
+ * Gets device info from the VIDAA JS SDK.
219
+ *
220
+ * Field availability varies by VIDAA version, so each value is read
221
+ * defensively and omitted when unavailable:
222
+ * - getBrand / getModelName / getFirmWareVersion / getCountryCode are U3+
223
+ * - getOSVersion / getNetType are U4+, hence the firmware fallback for
224
+ * osVersion so pre-2020 models still report something
225
+ *
226
+ * @returns {Promise<object|null>} Device info, or null if the SDK never loaded.
227
+ */
228
+ export const getVidaaInfo = async () => {
229
+ const sdk = await waitForVidaaAPIs();
230
+
231
+ if (!sdk) {
232
+ return null;
233
+ }
234
+
235
+ const modelName = readVidaaValue(sdk, "getModelName");
236
+ const brand = readVidaaValue(sdk, "getBrand");
237
+ const networkType = readVidaaValue(sdk, "getNetType");
238
+ const countryCode = readVidaaValue(sdk, "getCountryCode");
239
+
240
+ // getOSVersion is U4+; fall back to the firmware version, which is U3+.
241
+ const osVersion =
242
+ readVidaaValue(sdk, "getOSVersion") ||
243
+ readVidaaValue(sdk, "getFirmWareVersion");
244
+
245
+ return {
246
+ ...(modelName ? { modelName } : {}),
247
+ ...(brand ? { deviceMake: brand } : {}),
248
+ ...(osVersion ? { osVersion } : {}),
249
+ ...(networkType ? { networkType } : {}),
250
+ ...(countryCode ? { countryCode } : {}),
251
+ };
252
+ };
253
+
99
254
  /**
100
255
  * Determines the device type based on the platform.
101
256
  * @returns {DeviceType} The device type ("tv", "web", or "other").
@@ -322,6 +477,20 @@ export const getDeviceData = async () => {
322
477
 
323
478
  deviceData.deviceModel = window.VIZIO.deviceModel;
324
479
  }
480
+ } else if (isVidaaPlatform()) {
481
+ // Waits for the VIDAA SDK, which loader.js loads asynchronously from the
482
+ // VIDAA CDN. Resolves to null on timeout, leaving the static fields below.
483
+ const vidaaInfo = await getVidaaInfo();
484
+
485
+ deviceData = {
486
+ ...vidaaInfo,
487
+ platform: "vidaa",
488
+ // Brand is read from the SDK rather than hardcoded: VIDAA ships on
489
+ // OEM sets beyond Hisense, so getBrand() is the accurate source.
490
+ deviceMake: vidaaInfo?.deviceMake || "Hisense",
491
+ deviceType: getDeviceType(),
492
+ ...deviceDimensions,
493
+ };
325
494
  }
326
495
 
327
496
  return deviceData;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-dom-app",
3
- "version": "16.0.0-alpha.3439504142",
3
+ "version": "16.0.0-alpha.3502052160",
4
4
  "description": "Zapp App Component for Applicaster's Quick Brick React Native App",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,11 +22,11 @@
22
22
  },
23
23
  "homepage": "https://github.com/applicaster/zapp-react-dom-app#readme",
24
24
  "dependencies": {
25
- "@applicaster/zapp-react-dom-ui-components": "16.0.0-alpha.3439504142",
26
- "@applicaster/zapp-react-native-bridge": "16.0.0-alpha.3439504142",
27
- "@applicaster/zapp-react-native-redux": "16.0.0-alpha.3439504142",
28
- "@applicaster/zapp-react-native-ui-components": "16.0.0-alpha.3439504142",
29
- "@applicaster/zapp-react-native-utils": "16.0.0-alpha.3439504142",
25
+ "@applicaster/zapp-react-dom-ui-components": "16.0.0-alpha.3502052160",
26
+ "@applicaster/zapp-react-native-bridge": "16.0.0-alpha.3502052160",
27
+ "@applicaster/zapp-react-native-redux": "16.0.0-alpha.3502052160",
28
+ "@applicaster/zapp-react-native-ui-components": "16.0.0-alpha.3502052160",
29
+ "@applicaster/zapp-react-native-utils": "16.0.0-alpha.3502052160",
30
30
  "abortcontroller-polyfill": "^1.7.5",
31
31
  "typeface-montserrat": "^0.0.54",
32
32
  "video.js": "7.14.3",