@applicaster/zapp-react-native-utils 12.0.0-alpha.4536343143 → 12.0.0-alpha.4584840011

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 (34) hide show
  1. package/appUtils/accessibilityManager/const.ts +50 -0
  2. package/appUtils/accessibilityManager/hooks.ts +40 -0
  3. package/appUtils/accessibilityManager/index.ts +155 -0
  4. package/appUtils/accessibilityManager/logger.ts +5 -0
  5. package/appUtils/focusManager/index.ts +0 -1
  6. package/appUtils/focusManager/treeDataStructure/Utils/index.js +1 -1
  7. package/appUtils/index.js +2 -0
  8. package/appUtils/keyCodes/keys.web.js +8 -0
  9. package/appUtils/keyCodes/keysByPlatform.js +11 -1
  10. package/appUtils/platform/const.ts +25 -0
  11. package/appUtils/platform/index.ts +3 -0
  12. package/appUtils/platform/platformUtils.ts +185 -0
  13. package/appUtils/playerManager/conts.ts +1 -0
  14. package/appUtils/playerManager/index.ts +11 -5
  15. package/appUtils/playerManager/nativePlayerManager.ts +12 -0
  16. package/appUtils/playerManager/player.ts +9 -3
  17. package/appUtils/playerManager/playerNative.ts +4 -13
  18. package/appUtils/playerManager/usePlayerControllerSetup.tsx +1 -0
  19. package/booleanUtils/index.ts +4 -4
  20. package/cellUtils/index.ts +5 -5
  21. package/index.d.ts +15 -0
  22. package/keyboardState/index.ts +0 -0
  23. package/navigationUtils/index.ts +48 -0
  24. package/numberUtils/__tests__/toNumber.test.ts +2 -2
  25. package/package.json +2 -2
  26. package/playerUtils/imaScriptDom.ts +59 -0
  27. package/pluginUtils/index.ts +9 -0
  28. package/reactHooks/feed/__tests__/useFeedRefresh.test.tsx +6 -2
  29. package/reactHooks/feed/useFeedRefresh.tsx +9 -7
  30. package/reactHooks/navigation/index.ts +12 -2
  31. package/reactUtils/index.ts +104 -0
  32. package/appUtils/focusManager/FocusableEvents.ts +0 -8
  33. package/appUtils/focusManager/treeDataStructure/Utils/__tests__/Utils_android.test.js +0 -1094
  34. package/appUtils/focusManager/treeDataStructure/Utils/index.android.js +0 -261
@@ -0,0 +1,50 @@
1
+ export const BUTTON_ACCESSIBILITY_KEYS = {
2
+ play: {
3
+ label: "accessibility_play_label",
4
+ hint: "accessibility_play_hint",
5
+ mini: {
6
+ label: "accessibility_play_mini_label",
7
+ hint: "accessibility_play_mini_hint",
8
+ },
9
+ },
10
+ pause: {
11
+ label: "accessibility_pause_label",
12
+ hint: "accessibility_pause_hint",
13
+ mini: {
14
+ label: "accessibility_pause_mini_label",
15
+ hint: "accessibility_pause_mini_hint",
16
+ },
17
+ },
18
+ rewind: {
19
+ label: "accessibility_rewind_label",
20
+ hint: "accessibility_rewind_hint",
21
+ },
22
+ forward: {
23
+ label: "accessibility_forward_label",
24
+ hint: "accessibility_forward_hint",
25
+ },
26
+ close: {
27
+ label: "accessibility_close_label",
28
+ hint: "accessibility_close_hint",
29
+ mini: {
30
+ label: "accessibility_close_mini_label",
31
+ hint: "accessibility_close_mini_hint",
32
+ },
33
+ },
34
+ maximize: {
35
+ label: "accessibility_maximize_label",
36
+ hint: "accessibility_maximize_hint",
37
+ },
38
+ subtitles: {
39
+ label: "accessibility_subtitle_label",
40
+ hint: "accessibility_subtitle_hint",
41
+ },
42
+ back: {
43
+ label: "accessibility_back_label",
44
+ hint: "accessibility_back_hint",
45
+ },
46
+ fullscreen: {
47
+ label: "accessibility_fullscreen_label",
48
+ hint: "accessibility_fullscreen_hint",
49
+ },
50
+ } as const;
@@ -0,0 +1,40 @@
1
+ import { useEffect, useMemo } from "react";
2
+ import { AccessibilityManager } from "./index";
3
+
4
+ /**
5
+ * This hook is used to instantiate the accessibility manager and update localizations used by the class.
6
+ * If the plugin config is not provided or it does not contain any localizations, the accessibility manager will not be updated.
7
+ * We use the plugin configuration because it offers a flattened structure where we can easily access the accessibility labels and hints
8
+ * i.e. pluginConfiguration = {
9
+ * accessibility_close_label: "Close",
10
+ * accessibility_close_hint: "Press here to close",
11
+ * }
12
+ */
13
+ export const useAccessibilityManager = (
14
+ pluginConfiguration: Record<string, any> = {}
15
+ ) => {
16
+ const accessibilityManager = useMemo(() => {
17
+ return AccessibilityManager.getInstance();
18
+ }, []);
19
+
20
+ useEffect(() => {
21
+ if (pluginConfiguration) {
22
+ accessibilityManager.updateLocalizations(pluginConfiguration);
23
+ }
24
+ }, [pluginConfiguration, accessibilityManager]);
25
+
26
+ useEffect(() => {
27
+ const subscription = accessibilityManager.getStateAsObservable().subscribe({
28
+ next: () => {
29
+ // TODO: handle accessibility states
30
+ // screenReaderEnabled: false
31
+ // reduceMotionEnabled: false
32
+ // boldTextEnabled: false
33
+ },
34
+ });
35
+
36
+ return () => subscription.unsubscribe();
37
+ }, [accessibilityManager]);
38
+
39
+ return accessibilityManager;
40
+ };
@@ -0,0 +1,155 @@
1
+ import { BehaviorSubject } from "rxjs";
2
+ import { accessibilityManagerLogger as logger } from "./logger";
3
+ import { TTSManager } from "../platform/platformUtils";
4
+ import { BUTTON_ACCESSIBILITY_KEYS } from "./const";
5
+ import { AccessibilityRole } from "react-native";
6
+
7
+ export class AccessibilityManager {
8
+ private static _instance: AccessibilityManager | null = null;
9
+ private state$ = new BehaviorSubject<AccessibilityState>({
10
+ screenReaderEnabled: false,
11
+ reduceMotionEnabled: false,
12
+ boldTextEnabled: false,
13
+ });
14
+
15
+ private announcements$ = new BehaviorSubject<{
16
+ message: string;
17
+ localizedMessage?: string | undefined;
18
+ timestamp: number;
19
+ } | null>(null);
20
+
21
+ private ttsManager = TTSManager.getInstance();
22
+ private localizations: { [key: string]: string } = {};
23
+
24
+ private constructor() {}
25
+
26
+ public static getInstance(): AccessibilityManager {
27
+ if (!AccessibilityManager._instance) {
28
+ AccessibilityManager._instance = new AccessibilityManager();
29
+ }
30
+
31
+ return AccessibilityManager._instance;
32
+ }
33
+
34
+ /**
35
+ * The method now accepts any object with localizations using a flattened structure
36
+ *
37
+ * i.e. { accessibility_close_label: "Close", accessibility_close_hint: "Press here to close" }
38
+ *
39
+ * No longer accepts:
40
+ *
41
+ * i.e. localizations: [{ en: { accessibility_close_label: "Close", accessibility_close_hint: "Press here to close" } }]
42
+ */
43
+ public updateLocalizations(localizations: { [key: string]: string }) {
44
+ this.localizations = localizations;
45
+ }
46
+
47
+ public getState(): AccessibilityState {
48
+ return this.state$.getValue();
49
+ }
50
+
51
+ public getStateAsObservable() {
52
+ return this.state$.asObservable();
53
+ }
54
+
55
+ /**
56
+ * text you want to be read, if you want to use localized text pass keyOfLocalizedText instead
57
+ * keyOfLocalizedText is the key to the localized text
58
+ */
59
+ public readText({
60
+ text,
61
+ keyOfLocalizedText,
62
+ }: {
63
+ text: string;
64
+ keyOfLocalizedText?: string;
65
+ }) {
66
+ let textToRead = text;
67
+
68
+ if (keyOfLocalizedText) {
69
+ if (!this.localizations) {
70
+ logger.error(
71
+ "Attempting to use localized key without initialized localizations"
72
+ );
73
+
74
+ return;
75
+ }
76
+
77
+ const localizedMessage = this.getLocalizedMessage(keyOfLocalizedText);
78
+
79
+ if (!localizedMessage) {
80
+ logger.warn(`No localization found for key: ${keyOfLocalizedText}`);
81
+
82
+ return;
83
+ }
84
+
85
+ textToRead = localizedMessage;
86
+ }
87
+
88
+ if (this.ttsManager) {
89
+ logger.debug({
90
+ message: `Reading text: ${textToRead}`,
91
+ data: {
92
+ textToRead,
93
+ text,
94
+ keyOfLocalizedText,
95
+ },
96
+ });
97
+
98
+ this.ttsManager.readText(textToRead);
99
+ }
100
+
101
+ this.announcements$.next({
102
+ message: textToRead,
103
+ localizedMessage: keyOfLocalizedText ? textToRead : undefined,
104
+ timestamp: Date.now(),
105
+ });
106
+ }
107
+
108
+ public getButtonAccessibilityProps(buttonName: string): AccessibilityProps {
109
+ const buttonConfig = BUTTON_ACCESSIBILITY_KEYS[buttonName];
110
+
111
+ if (!buttonConfig) {
112
+ return {
113
+ accessibilityLabel: buttonName,
114
+ accessibilityHint: `Press button to perform action on ${buttonName}`,
115
+ "aria-label": buttonName,
116
+ "aria-description": `Press button to perform action on ${buttonName}`,
117
+ accessibilityRole: "button" as AccessibilityRole,
118
+ "aria-role": "button",
119
+ };
120
+ }
121
+
122
+ const labelKey = buttonConfig.label;
123
+ const hintKey = buttonConfig.hint;
124
+
125
+ const label = this.getLocalizedMessage(labelKey) || buttonName;
126
+
127
+ const hint =
128
+ this.getLocalizedMessage(hintKey) ||
129
+ `Press button to perform action on ${buttonName}`;
130
+
131
+ return {
132
+ accessibilityLabel: label,
133
+ accessibilityHint: hint,
134
+ "aria-label": label,
135
+ "aria-description": hint,
136
+ accessibilityRole: "button" as AccessibilityRole,
137
+ "aria-role": "button",
138
+ };
139
+ }
140
+
141
+ public getLocalizedMessage(key: string): string | void {
142
+ if (!key) return;
143
+
144
+ if (!this.localizations) {
145
+ logger.error(
146
+ "Attempting to use localized key without initialized localizations",
147
+ { key }
148
+ );
149
+
150
+ return;
151
+ }
152
+
153
+ return this.localizations[key];
154
+ }
155
+ }
@@ -0,0 +1,5 @@
1
+ import { utilsLogger } from "../../logger";
2
+
3
+ export const accessibilityManagerLogger = utilsLogger.addSubsystem(
4
+ "accessibilityManager"
5
+ );
@@ -13,7 +13,6 @@ import {
13
13
  import { subscriber } from "../../functionUtils";
14
14
  import * as FOCUS_EVENTS from "./events";
15
15
  import { coreLogger } from "../../logger";
16
-
17
16
  const logger = coreLogger.addSubsystem("focusManager");
18
17
 
19
18
  const isFocusEnabled = (focusableItem): boolean => {
@@ -206,7 +206,7 @@ export function getTargetInDirection(
206
206
  const overrideTarget = currentNode?.component?.props[overridePropName];
207
207
 
208
208
  if (overrideTarget) {
209
- const target = targetNodes.find((n) => n.id === overrideTarget);
209
+ const target = targetNodes.find((n) => n?.id === overrideTarget);
210
210
 
211
211
  if (target) return target;
212
212
  }
package/appUtils/index.js CHANGED
@@ -9,6 +9,8 @@ export { KEYS, ARROW_KEYS } from "./keyCodes/keys";
9
9
 
10
10
  export { playerManager } from "./playerManager";
11
11
 
12
+ export { accessibilityManager } from "./accessibilityManager";
13
+
12
14
  export function deprecationMessage(fn, replacement) {
13
15
  if (__DEV__ && process.env.NODE_ENV !== "test") {
14
16
  console.warn("/** DEPRECATION WARNING **/");
@@ -1,6 +1,7 @@
1
1
  /* global tizen */
2
2
  const isTizen = typeof tizen !== "undefined";
3
3
 
4
+ import { isVizioPlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
4
5
  import * as platformKeys from "./keysByPlatform";
5
6
  import { Platform } from "react-native";
6
7
 
@@ -21,6 +22,13 @@ export const ARROW_KEYS = [
21
22
  KEYS.ArrowRight,
22
23
  ];
23
24
 
25
+ /**
26
+ * Platform.OS currently identifies Vizio as LG_TV, therefore we are using isVizioPlatform to identify platform and add keys.
27
+ */
28
+ if (isVizioPlatform()) {
29
+ Object.assign(KEYS, platformKeys.vizio);
30
+ }
31
+
24
32
  /**
25
33
  * In TizenOS we need to register all of the keys that we are going to use.
26
34
  * You need to register using the name Tizen has for the key.
@@ -102,4 +102,14 @@ const tvos = {
102
102
  Menu: { code: "Menu", eventType: "menu" },
103
103
  };
104
104
 
105
- export { lg_tv, samsung_tv, web, tvos, android_tv };
105
+ const vizio = {
106
+ ...samsung_tv,
107
+ Exit: { code: "Exit", keyCode: 27 },
108
+ PageUp: { code: "PageUp", keyCode: 33 },
109
+ PageDown: { code: "PageDown", keyCode: 34 },
110
+ MediaTrackNext: { code: "MediaTrackNext", keyCode: 418 },
111
+ MediaTrackPrevious: { code: "MediaTrackPrevious", keyCode: 419 },
112
+ PrevCh: { code: "PrevCh", keyCode: 500 },
113
+ };
114
+
115
+ export { lg_tv, samsung_tv, web, tvos, android_tv, vizio };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Platforms found in userAgent string, please note that simulators
3
+ * might not have the same agents that the devices have
4
+ */
5
+ export const PLATFORMS = {
6
+ webos: "Web0S",
7
+ tizen: "Tizen",
8
+ samsung: "SMART-TV",
9
+ mac: "Mac",
10
+ win: "Win",
11
+ linux: "Linux",
12
+ iphone: "iPhone",
13
+ android: "Android",
14
+ mobile: "Mobile",
15
+ vizio: "VIZIO",
16
+ smartcast: "SmartCast",
17
+ conjure: "Conjure",
18
+ };
19
+
20
+ /**
21
+ * Keys used to store the platform / device state in the session storage
22
+ */
23
+ export const PLATFORM_KEYS = {
24
+ deviceClosedCaptioningEnabled: "device_closed_captioning_enabled",
25
+ };
@@ -0,0 +1,3 @@
1
+ export * from "./platformUtils";
2
+
3
+ export * from "./const";
@@ -0,0 +1,185 @@
1
+ import { BehaviorSubject } from "rxjs";
2
+
3
+ import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
4
+
5
+ import { PLATFORM_KEYS, PLATFORMS } from "./const";
6
+ import { createLogger, utilsLogger } from "../../logger";
7
+
8
+ declare global {
9
+ interface Window {
10
+ VIZIO?: {
11
+ exitApplication: () => void;
12
+ Chromevox: {
13
+ play: (text: string) => void;
14
+ };
15
+ setClosedCaptionHandler: (
16
+ callback: (isCCEnabled: boolean) => void
17
+ ) => void;
18
+ };
19
+ }
20
+ }
21
+
22
+ const { log_debug } = createLogger({
23
+ category: "General",
24
+ subsystem: "PlatformUtils",
25
+ parent: utilsLogger,
26
+ });
27
+
28
+ export const getUserAgent = () =>
29
+ window?.navigator?.userAgent || global?.navigator?.userAgent;
30
+
31
+ /** VIZIO UTILS */
32
+
33
+ /**
34
+ * Checks if we are on the Vizio platform by using the userAgent string
35
+ *
36
+ * Use this method when you need to identify the platform on runtime
37
+ * before the VIZIO Companion Library has loaded
38
+ */
39
+ export const isVizioPlatform = () => {
40
+ const userAgent = getUserAgent();
41
+
42
+ const isVizioAgent =
43
+ userAgent.includes(PLATFORMS.vizio) ||
44
+ userAgent.includes(PLATFORMS.smartcast) ||
45
+ userAgent.includes(PLATFORMS.conjure);
46
+
47
+ return isVizioAgent;
48
+ };
49
+
50
+ /**
51
+ * Checks if we are on the Vizio platform by checking for the global VIZIO object
52
+ * and the VIZIO Companion Library. This method does not use the userAgent string,
53
+ * because it mainly checks whether we have access to apis, which may not be available yet
54
+ */
55
+ export const hasVizioAPIs = () => {
56
+ const hasAPIs =
57
+ typeof window.VIZIO !== "undefined" &&
58
+ window?.applicaster?.vizioLibraryDidLoad;
59
+
60
+ return hasAPIs;
61
+ };
62
+
63
+ /**
64
+ * Manages device based closed captioning state
65
+ * Returns an observable that emits the current state and updates whenever it changes
66
+ */
67
+ export class ClosedCaptioningManager {
68
+ private ccState$ = new BehaviorSubject<boolean>(false);
69
+ private static ccManagerInstance: ClosedCaptioningManager;
70
+
71
+ private constructor() {
72
+ this.initialize();
73
+ }
74
+
75
+ static getInstance(): ClosedCaptioningManager {
76
+ if (!ClosedCaptioningManager.ccManagerInstance) {
77
+ ClosedCaptioningManager.ccManagerInstance = new ClosedCaptioningManager();
78
+ }
79
+
80
+ return ClosedCaptioningManager.ccManagerInstance;
81
+ }
82
+
83
+ async initialize() {
84
+ const existingState = await sessionStorage.getItem(
85
+ PLATFORM_KEYS.deviceClosedCaptioningEnabled
86
+ );
87
+
88
+ log_debug("Initializing closed captioning manager", { existingState });
89
+
90
+ if (existingState !== null) {
91
+ this.ccState$.next(existingState === "true" || existingState === true);
92
+ }
93
+
94
+ if (hasVizioAPIs()) {
95
+ window.VIZIO!.setClosedCaptionHandler((isCCEnabled) => {
96
+ log_debug("CC state changed", { isCCEnabled });
97
+
98
+ sessionStorage.setItem(
99
+ PLATFORM_KEYS.deviceClosedCaptioningEnabled,
100
+ isCCEnabled
101
+ );
102
+
103
+ this.ccState$.next(isCCEnabled);
104
+ });
105
+ }
106
+ }
107
+
108
+ getCurrentState(): boolean {
109
+ return this.ccState$.getValue();
110
+ }
111
+
112
+ getStateAsObservable() {
113
+ return this.ccState$.asObservable();
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Subscribe to closed captioning state changes
119
+ * @returns Observable<boolean>
120
+ * @example
121
+ * const subscription = getClosedCaptionState().subscribe(
122
+ * isEnabled => setClosedCaptionState(isEnabled)
123
+ * );
124
+ * subscription.unsubscribe(), []);
125
+ */
126
+ export const getClosedCaptionState = () => {
127
+ const ccManager = ClosedCaptioningManager.getInstance();
128
+
129
+ return ccManager.getStateAsObservable();
130
+ };
131
+
132
+ /**
133
+ * Manages device based closed captioning state
134
+ * Returns an observable that emits the current state and updates whenever it changes
135
+ */
136
+ export class TTSManager {
137
+ private ttsState$ = new BehaviorSubject<boolean>(false);
138
+ private static ttsManagerInstance: TTSManager;
139
+
140
+ private constructor() {
141
+ this.initialize();
142
+ }
143
+
144
+ static getInstance(): TTSManager {
145
+ if (!TTSManager.ttsManagerInstance) {
146
+ TTSManager.ttsManagerInstance = new TTSManager();
147
+ }
148
+
149
+ return TTSManager.ttsManagerInstance;
150
+ }
151
+
152
+ async initialize() {
153
+ if (!isVizioPlatform()) return;
154
+
155
+ document.addEventListener(
156
+ "VIZIO_TTS_ENABLED",
157
+ () => {
158
+ this.ttsState$.next(true);
159
+ },
160
+ false
161
+ );
162
+
163
+ document.addEventListener(
164
+ "VIZIO_TTS_DISABLED",
165
+ () => {
166
+ this.ttsState$.next(false);
167
+ },
168
+ false
169
+ );
170
+ }
171
+
172
+ getCurrentState(): boolean {
173
+ return this.ttsState$.getValue();
174
+ }
175
+
176
+ getStateAsObservable() {
177
+ return this.ttsState$.asObservable();
178
+ }
179
+
180
+ readText(text: string) {
181
+ if (!window.VIZIO?.Chromevox) return;
182
+
183
+ window.VIZIO.Chromevox.play(text);
184
+ }
185
+ }
@@ -7,6 +7,7 @@ export enum SharedPlayerCallBacksKeys {
7
7
  OnPlayerPause = "onPlayerPause",
8
8
  OnLoad = "onLoad",
9
9
  OnError = "onError",
10
+ OnVideoError = "onVideoError",
10
11
  OnVideoEnd = "onVideoEnd",
11
12
  OnPlaybackRateChange = "onPlaybackRateChange",
12
13
  OnVideoLoad = "onVideoLoad",
@@ -11,6 +11,7 @@ import {
11
11
  } from "@applicaster/quick-brick-core/App/NetworkStatusProvider/utils";
12
12
  import { setUserLanguagePreference } from "./userLanguagePreference";
13
13
  import { PlayerRole } from "./conts";
14
+ import { RNPlayerManager } from "./nativePlayerManager";
14
15
 
15
16
  const { log_error, log_debug, log_warning } = createLogger({
16
17
  category: "General",
@@ -164,6 +165,10 @@ export class PlayerManager {
164
165
  this.addPlayer(id, playerController);
165
166
 
166
167
  if (playerController.playerRole === PlayerRole.Primary) {
168
+ if (playerController.playerPluginId !== "QuickBrickPlayerPlugin") {
169
+ RNPlayerManager?.["QuickBrickPlayerPlugin"]?.stopBackgroundPlayback?.();
170
+ }
171
+
167
172
  playerController.addListener({
168
173
  id: this.getPlayerListenerId(id),
169
174
  listener: {
@@ -361,9 +366,9 @@ export class PlayerManager {
361
366
  // TODO: Remove
362
367
  if (this.castingReceiver) {
363
368
  this.castingReceiver.rewind(deltaTime);
369
+ } else {
370
+ this.getActivePlayer()?.rewind(deltaTime);
364
371
  }
365
-
366
- this.getActivePlayer()?.rewind(deltaTime);
367
372
  }
368
373
 
369
374
  public forward(deltaTime = null) {
@@ -371,9 +376,9 @@ export class PlayerManager {
371
376
 
372
377
  if (this.castingReceiver) {
373
378
  this.castingReceiver.forward(deltaTime);
379
+ } else {
380
+ this.getActivePlayer()?.forward(deltaTime);
374
381
  }
375
-
376
- this.getActivePlayer()?.forward(deltaTime);
377
382
  }
378
383
 
379
384
  public seeking(time) {
@@ -436,7 +441,7 @@ export class PlayerManager {
436
441
  }
437
442
 
438
443
  // Call method on player just in case
439
- return this.getActivePlayer()?.setLanguage(track);
444
+ return this.getActivePlayer()?.selectTrack(track);
440
445
  }
441
446
 
442
447
  public isRegistered() {
@@ -461,6 +466,7 @@ export class PlayerManager {
461
466
  if (this.castingReceiver) {
462
467
  this.castingReceiver.closeNativePlayer();
463
468
  } else {
469
+ this.getActivePlayer().closeNativePlayer();
464
470
  this.invokeHandler("close");
465
471
  }
466
472
  }
@@ -0,0 +1,12 @@
1
+ import { NativeModules } from "react-native";
2
+ import { isApplePlatform } from "../../reactUtils";
3
+
4
+ export const RNPlayerManager = {
5
+ QuickBrickPlayerPlugin: isApplePlatform()
6
+ ? NativeModules.PlayerModule
7
+ : NativeModules.QuickBrickDefaultPlayerModule,
8
+ KalturaPlayerPlugin: isApplePlatform()
9
+ ? NativeModules.KalturaPlayerModule
10
+ : NativeModules.QBKalturaPlayerModule,
11
+ "quick-brick-player-brightcove": NativeModules.BrightcovePlayerModule,
12
+ };
@@ -359,6 +359,13 @@ export class Player {
359
359
  });
360
360
  };
361
361
 
362
+ onVideoError = (error: Error) => {
363
+ this.invokeListenersUpdate({
364
+ callbackName: SharedPlayerCallBacksKeys.OnVideoError,
365
+ event: error,
366
+ });
367
+ };
368
+
362
369
  onError = (error: Error) => {
363
370
  this.invokeListenersUpdate({
364
371
  callbackName: SharedPlayerCallBacksKeys.OnError,
@@ -650,6 +657,7 @@ export class Player {
650
657
  onPlayerSeekComplete: this.onSeekComplete,
651
658
  onVideoEnd: this.onVideoEnd,
652
659
  onError: this.onError,
660
+ onVideoError: this.onVideoError,
653
661
  onLoad: this.onLoad,
654
662
  onPlayerPause: this.onPlayerPause,
655
663
  onPlayerResume: this.onPlayerResume,
@@ -684,9 +692,6 @@ export class Player {
684
692
  play = () => {};
685
693
  pause = () => {};
686
694
  disableBufferAnimation = (): boolean => true;
687
- setLanguage = (
688
- _selected?: QuickBrickPlayer.TextTrack | QuickBrickPlayer.AudioTrack
689
- ) => {};
690
695
 
691
696
  setPlaybackRate = (_rate) => {};
692
697
  startSleepTimer = (_timestamp) => {};
@@ -728,4 +733,5 @@ export class Player {
728
733
 
729
734
  public supportsNativeControls = (): boolean => false;
730
735
  public supportNativeCast = (): boolean => false;
736
+ public destroy = () => {};
731
737
  }
@@ -2,19 +2,10 @@ import * as R from "ramda";
2
2
  import { isEmptyOrNil } from "@applicaster/zapp-react-native-utils/cellUtils";
3
3
  import { createLogger, utilsLogger } from "../../logger";
4
4
  import { Player } from "./player";
5
- import { findNodeHandle, NativeModules } from "react-native";
6
- import { isApplePlatform } from "../../reactUtils";
5
+ import { findNodeHandle } from "react-native";
7
6
  import { PlayerRole } from "./conts";
8
7
  import { toBooleanWithDefaultFalse } from "../../booleanUtils";
9
-
10
- const RNPlayerManager = {
11
- QuickBrickPlayerPlugin: isApplePlatform()
12
- ? NativeModules.PlayerModule
13
- : NativeModules.QuickBrickDefaultPlayerModule,
14
- KalturaPlayerPlugin: isApplePlatform()
15
- ? NativeModules.KalturaPlayerModule
16
- : NativeModules.QBKalturaPlayerModule,
17
- };
8
+ import { RNPlayerManager } from "./nativePlayerManager";
18
9
 
19
10
  const logger = createLogger({
20
11
  category: "PlayerNativeController",
@@ -197,10 +188,10 @@ export class PlayerNative extends Player {
197
188
 
198
189
  disableBufferAnimation = (): boolean => false;
199
190
 
200
- setLanguage = (
191
+ selectTrack = (
201
192
  selected: QuickBrickPlayer.TextTrack | QuickBrickPlayer.AudioTrack
202
193
  ) => {
203
- this.currentPlayerComponent()?.["setLanguage"]?.(selected);
194
+ this.currentPlayerComponent()?.["selectTrack"]?.(selected);
204
195
  };
205
196
 
206
197
  setPlaybackRate = (rate: number) => {