@applicaster/zapp-react-native-utils 13.0.7-alpha.2991546311 → 13.0.7-alpha.7163853950
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect, useMemo } from "react";
|
|
1
|
+
import { useEffect, useMemo, useState } from "react";
|
|
2
2
|
import { AccessibilityManager } from "./index";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -38,3 +38,37 @@ export const useAccessibilityManager = (
|
|
|
38
38
|
|
|
39
39
|
return accessibilityManager;
|
|
40
40
|
};
|
|
41
|
+
|
|
42
|
+
export const useInitialAnnouncementReady = (
|
|
43
|
+
accessibilityManager: AccessibilityManager
|
|
44
|
+
) => {
|
|
45
|
+
const [isReady, setIsReady] = useState(
|
|
46
|
+
accessibilityManager.isInitialPlayerAnnouncementReady
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
const subscription = accessibilityManager
|
|
51
|
+
.getInitialAnnouncementReadyObservable()
|
|
52
|
+
.subscribe(setIsReady);
|
|
53
|
+
|
|
54
|
+
return () => subscription.unsubscribe();
|
|
55
|
+
}, [accessibilityManager]);
|
|
56
|
+
|
|
57
|
+
return isReady;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const useAnnouncementActive = (
|
|
61
|
+
accessibilityManager: AccessibilityManager
|
|
62
|
+
) => {
|
|
63
|
+
const [isActive, setIsActive] = useState(false);
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
const subscription = accessibilityManager
|
|
67
|
+
.getTTSStateObservable()
|
|
68
|
+
.subscribe(setIsActive);
|
|
69
|
+
|
|
70
|
+
return () => subscription.unsubscribe();
|
|
71
|
+
}, [accessibilityManager]);
|
|
72
|
+
|
|
73
|
+
return isActive;
|
|
74
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as R from "ramda";
|
|
1
2
|
import { BehaviorSubject } from "rxjs";
|
|
2
3
|
import { accessibilityManagerLogger as logger } from "./logger";
|
|
3
4
|
import { TTSManager } from "../platform/platformUtils";
|
|
@@ -30,6 +31,9 @@ export class AccessibilityManager {
|
|
|
30
31
|
private currentFocusId: string | null = null;
|
|
31
32
|
private headingFocusMap: Map<string, string> = new Map();
|
|
32
33
|
private pendingFocusId: string | null = null;
|
|
34
|
+
private isInitialPlayerAnnouncementReady$ = new BehaviorSubject<boolean>(
|
|
35
|
+
false
|
|
36
|
+
);
|
|
33
37
|
|
|
34
38
|
private constructor() {}
|
|
35
39
|
|
|
@@ -41,6 +45,26 @@ export class AccessibilityManager {
|
|
|
41
45
|
return AccessibilityManager._instance;
|
|
42
46
|
}
|
|
43
47
|
|
|
48
|
+
public get isInitialPlayerAnnouncementReady(): boolean {
|
|
49
|
+
return this.isInitialPlayerAnnouncementReady$.getValue();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public setInitialPlayerAnnouncementReady(): void {
|
|
53
|
+
this.isInitialPlayerAnnouncementReady$.next(true);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public resetInitialPlayerAnnouncementReady(): void {
|
|
57
|
+
this.isInitialPlayerAnnouncementReady$.next(false);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public getInitialAnnouncementReadyObservable() {
|
|
61
|
+
return this.isInitialPlayerAnnouncementReady$.asObservable();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public getTTSStateObservable() {
|
|
65
|
+
return this.ttsManager.getStateAsObservable();
|
|
66
|
+
}
|
|
67
|
+
|
|
44
68
|
/**
|
|
45
69
|
* The method now accepts any object with localizations using a flattened structure
|
|
46
70
|
*
|
|
@@ -51,7 +75,9 @@ export class AccessibilityManager {
|
|
|
51
75
|
* i.e. localizations: [{ en: { accessibility_close_label: "Close", accessibility_close_hint: "Press here to close" } }]
|
|
52
76
|
*/
|
|
53
77
|
public updateLocalizations(localizations: { [key: string]: string }) {
|
|
54
|
-
|
|
78
|
+
if (!R.isEmpty(localizations)) {
|
|
79
|
+
this.localizations = localizations;
|
|
80
|
+
}
|
|
55
81
|
}
|
|
56
82
|
|
|
57
83
|
public getState(): AccessibilityState {
|
|
@@ -212,11 +212,16 @@ export class TTSManager {
|
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
readText(text: string) {
|
|
215
|
+
this.ttsState$.next(true);
|
|
216
|
+
|
|
215
217
|
if (isSamsungPlatform() && window.speechSynthesis) {
|
|
216
218
|
const utterance = new SpeechSynthesisUtterance(text);
|
|
217
219
|
|
|
218
220
|
window.speechSynthesis.cancel(); // Cancel previous speech before speaking new text
|
|
219
221
|
window.speechSynthesis.speak(utterance);
|
|
222
|
+
|
|
223
|
+
// Estimate reading time and set inactive when done
|
|
224
|
+
this.scheduleTTSComplete(text);
|
|
220
225
|
}
|
|
221
226
|
|
|
222
227
|
if (isLgPlatform() && window.webOS?.service) {
|
|
@@ -227,24 +232,47 @@ export class TTSManager {
|
|
|
227
232
|
log_debug("There was a failure setting up webOS TTS service", {
|
|
228
233
|
error,
|
|
229
234
|
});
|
|
235
|
+
|
|
236
|
+
this.ttsState$.next(false);
|
|
230
237
|
},
|
|
231
238
|
onSuccess(response: any) {
|
|
232
239
|
log_debug("webOS TTS service is configured successfully", {
|
|
233
240
|
response,
|
|
234
241
|
});
|
|
242
|
+
|
|
243
|
+
// Estimate reading time and set inactive when done
|
|
244
|
+
this.scheduleTTSComplete(text);
|
|
235
245
|
},
|
|
236
246
|
parameters: {
|
|
237
247
|
text,
|
|
238
|
-
clear: true, // Clear any
|
|
248
|
+
clear: true, // Clear any previous speech before speaking new text
|
|
239
249
|
},
|
|
240
250
|
});
|
|
241
251
|
} catch (error) {
|
|
242
252
|
log_debug("webOS TTS service error", { error });
|
|
253
|
+
this.ttsState$.next(false);
|
|
243
254
|
}
|
|
244
255
|
}
|
|
245
256
|
|
|
246
|
-
if (!window.VIZIO?.Chromevox)
|
|
257
|
+
if (!window.VIZIO?.Chromevox) {
|
|
258
|
+
// For platforms without TTS, estimate reading time
|
|
259
|
+
this.scheduleTTSComplete(text);
|
|
260
|
+
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
247
263
|
|
|
248
264
|
window.VIZIO.Chromevox.play(text);
|
|
265
|
+
// Estimate reading time and set inactive when done
|
|
266
|
+
this.scheduleTTSComplete(text);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
private scheduleTTSComplete(text: string) {
|
|
270
|
+
// Estimate reading time based on word count (160 words per minute)
|
|
271
|
+
const words = text.trim().split(/\s+/).length;
|
|
272
|
+
const readingTime = Math.max(500, (words / 160) * 60 * 1000) + 300;
|
|
273
|
+
|
|
274
|
+
setTimeout(() => {
|
|
275
|
+
this.ttsState$.next(false);
|
|
276
|
+
}, readingTime);
|
|
249
277
|
}
|
|
250
278
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-utils",
|
|
3
|
-
"version": "13.0.7-alpha.
|
|
3
|
+
"version": "13.0.7-alpha.7163853950",
|
|
4
4
|
"description": "Applicaster Zapp React Native utilities package",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@applicaster/applicaster-types": "13.0.7-alpha.
|
|
30
|
+
"@applicaster/applicaster-types": "13.0.7-alpha.7163853950",
|
|
31
31
|
"buffer": "^5.2.1",
|
|
32
32
|
"camelize": "^1.0.0",
|
|
33
33
|
"dayjs": "^1.11.10",
|
|
@@ -141,6 +141,7 @@ export class PlayerTTS {
|
|
|
141
141
|
`${this.secondsToTime(timeRemaining, "standard")} remaining.`
|
|
142
142
|
);
|
|
143
143
|
|
|
144
|
+
this.accessibilityManager.setInitialPlayerAnnouncementReady();
|
|
144
145
|
this.isInitialPlayerOpen = false;
|
|
145
146
|
}
|
|
146
147
|
};
|
|
@@ -184,6 +185,19 @@ export class PlayerTTS {
|
|
|
184
185
|
this.isSeeking = true;
|
|
185
186
|
};
|
|
186
187
|
|
|
188
|
+
private handlePlayerClose = () => {
|
|
189
|
+
this.isInitialPlayerOpen = true;
|
|
190
|
+
this.accessibilityManager.resetInitialPlayerAnnouncementReady();
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
private announceAdBegin = (event: any) => {
|
|
194
|
+
if (event?.ad?.data?.duration) {
|
|
195
|
+
this.accessibilityManager.readText({
|
|
196
|
+
text: `Sponsored. Ends in ${this.secondsToTime(event.ad.data.duration, "standard")}`,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
|
|
187
201
|
public init(): () => void {
|
|
188
202
|
if (!this.player) {
|
|
189
203
|
return () => {};
|
|
@@ -199,6 +213,8 @@ export class PlayerTTS {
|
|
|
199
213
|
onVideoProgress: this.handleVideoProgress,
|
|
200
214
|
onPlayerSeekStart: this.handleSeekStart,
|
|
201
215
|
onPlayerSeekComplete: this.handleSeekComplete,
|
|
216
|
+
onPlayerClose: this.handlePlayerClose,
|
|
217
|
+
onAdBegin: this.announceAdBegin,
|
|
202
218
|
},
|
|
203
219
|
});
|
|
204
220
|
}
|
|
@@ -209,5 +225,6 @@ export class PlayerTTS {
|
|
|
209
225
|
}
|
|
210
226
|
|
|
211
227
|
this.seekStartPosition = null;
|
|
228
|
+
this.handlePlayerClose();
|
|
212
229
|
}
|
|
213
230
|
}
|