@applicaster/zapp-react-native-ui-components 12.0.0-rc.6 → 12.0.0-rc.60

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 (108) hide show
  1. package/Components/AudioPlayer/AudioPlayer.tsx +9 -1
  2. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +5 -0
  3. package/Components/AudioPlayer/helpers.tsx +1 -0
  4. package/Components/Cell/Cell.tsx +2 -2
  5. package/Components/Cell/CellWithFocusable.tsx +21 -14
  6. package/Components/Cell/TvOSCellComponent.tsx +2 -2
  7. package/Components/ErrorScreen/index.tsx +1 -1
  8. package/Components/FocusableCell/index.tsx +7 -7
  9. package/Components/FocusableList/FocusableChild.ts +24 -14
  10. package/Components/FocusableList/FocusableItem.tsx +1 -1
  11. package/Components/FocusableList/FocusableListItemWrapper.tsx +76 -0
  12. package/Components/FocusableList/hooks/useCellState.android.ts +3 -1
  13. package/Components/FocusableList/index.tsx +26 -25
  14. package/Components/GeneralContentScreen/GeneralContentScreen.tsx +11 -8
  15. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +13 -6
  16. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +1 -1
  17. package/Components/HandlePlayable/HandlePlayable.tsx +1 -1
  18. package/Components/HookRenderer/index.tsx +1 -6
  19. package/Components/Image/Image.android.tsx +3 -26
  20. package/Components/Image/Image.tsx +18 -2
  21. package/Components/Image/utils/index.ts +39 -0
  22. package/Components/Layout/TV/__tests__/index.test.tsx +1 -34
  23. package/Components/Layout/TV/index.tsx +20 -36
  24. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +0 -1
  25. package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +21 -8
  26. package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +9 -26
  27. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +5 -3
  28. package/Components/MasterCell/DefaultComponents/Image/hooks/useImageSize.ts +65 -0
  29. package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +5 -1
  30. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +17 -2
  31. package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +3 -2
  32. package/Components/MasterCell/DefaultComponents/Toggle.tsx +5 -1
  33. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
  34. package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +6 -10
  35. package/Components/MasterCell/hooks/useAsyncRendering/index.ts +1 -1
  36. package/Components/MasterCell/utils/index.ts +16 -5
  37. package/Components/ModalComponent/BottomSheetModalContent.tsx +121 -0
  38. package/Components/ModalComponent/Button/Item.tsx +82 -0
  39. package/Components/ModalComponent/Button/ItemIcon.tsx +60 -0
  40. package/Components/ModalComponent/Button/ItemLabel.tsx +101 -0
  41. package/Components/ModalComponent/Button/assets.ts +4 -0
  42. package/Components/ModalComponent/Button/index.tsx +111 -0
  43. package/Components/ModalComponent/Header/CloseButton.tsx +59 -0
  44. package/Components/ModalComponent/Header/Title.tsx +70 -0
  45. package/Components/ModalComponent/Header/assets.ts +4 -0
  46. package/Components/ModalComponent/Header/index.tsx +71 -0
  47. package/Components/ModalComponent/Header/utils.ts +79 -0
  48. package/Components/ModalComponent/index.tsx +38 -0
  49. package/Components/ModalComponent/utils.ts +126 -0
  50. package/Components/PlayerContainer/PlayerContainer.tsx +61 -30
  51. package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -1
  52. package/Components/PlayerImageBackground/index.tsx +34 -8
  53. package/Components/River/ComponentsMap/ComponentsMap.tsx +91 -2
  54. package/Components/River/RefreshControl.tsx +55 -1
  55. package/Components/River/River.tsx +8 -5
  56. package/Components/River/TV/River.tsx +2 -2
  57. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +1 -1
  58. package/Components/River/__tests__/componentsMap.test.js +7 -0
  59. package/Components/River/useScreenConfiguration.ts +5 -6
  60. package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +1 -0
  61. package/Components/RouteManager/__tests__/routeManager.test.js +9 -2
  62. package/Components/RouteManager/index.tsx +5 -3
  63. package/Components/Screen/__tests__/Screen.test.tsx +48 -36
  64. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +24 -6
  65. package/Components/Screen/__tests__/navigationHandler.test.ts +1 -178
  66. package/Components/Screen/index.tsx +103 -44
  67. package/Components/Screen/navigationHandler.ts +0 -82
  68. package/Components/Screen/orientationHandler.ts +1 -1
  69. package/Components/ScreenResolver/index.tsx +1 -1
  70. package/Components/Tabs/TV/styles.ts +1 -1
  71. package/Components/TrackedView/index.tsx +6 -3
  72. package/Components/VideoLive/LiveImageManager.ts +42 -13
  73. package/Components/VideoLive/PlayerLiveImageComponent.tsx +81 -72
  74. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +45 -3
  75. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +18 -28
  76. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +78 -0
  77. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +342 -0
  78. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +151 -0
  79. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +438 -0
  80. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +154 -0
  81. package/Components/VideoModal/ModalAnimation/index.ts +15 -0
  82. package/Components/VideoModal/ModalAnimation/utils.ts +299 -0
  83. package/Components/VideoModal/PlayerDetails.tsx +3 -0
  84. package/Components/VideoModal/PlayerWrapper.tsx +69 -44
  85. package/Components/VideoModal/VideoModal.tsx +25 -42
  86. package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +0 -2
  87. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +5 -1
  88. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +246 -166
  89. package/Components/VideoModal/hooks/useModalSize.ts +13 -4
  90. package/Components/VideoModal/utils.ts +3 -3
  91. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +26 -21
  92. package/Components/Viewport/ViewportTracker/ViewportTracker.tsx +1 -1
  93. package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +4 -5
  94. package/Components/Viewport/ViewportTracker/index.tsx +1 -0
  95. package/Components/Viewport/utils.js +1 -1
  96. package/Components/ZappUIComponent/index.tsx +22 -12
  97. package/Components/index.js +2 -0
  98. package/Contexts/MenuToggleContext/{index.js → index.ts} +16 -0
  99. package/Contexts/ScreenContext/__tests__/__snapshots__/index.test.tsx.snap +3 -0
  100. package/Contexts/ScreenContext/__tests__/index.test.tsx +27 -0
  101. package/Contexts/ScreenContext/index.tsx +95 -29
  102. package/Decorators/ComponentsMapWrapper/withComponentsMapProvider.tsx +7 -2
  103. package/Decorators/RiverResolver/index.tsx +0 -4
  104. package/Decorators/index.tsx +0 -4
  105. package/events/index.ts +1 -0
  106. package/package.json +5 -6
  107. package/Components/VideoModal/hooks/usePosition.ts +0 -50
  108. /package/Contexts/{index.js → index.ts} +0 -0
@@ -1,36 +1,40 @@
1
1
  /// <reference types="@applicaster/applicaster-types" />
2
- import React, { useMemo } from "react";
2
+ import React from "react";
3
3
  import * as R from "ramda";
4
4
  import { View } from "react-native";
5
- import { RouteManager } from "../RouteManager";
6
- import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
7
- import { useScreenOrientationHandler } from "./orientationHandler";
8
- import { useScreenConfiguration } from "../River/useScreenConfiguration";
9
- import { useCurrentScreenData } from "@applicaster/zapp-react-native-utils/reactHooks/screen";
10
- import type { ZappNavigationProps } from "@applicaster/zapp-react-native-flow-types/index";
11
5
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
6
+
7
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
8
+ import { getComponentModule } from "@applicaster/zapp-react-native-utils/pluginUtils";
9
+ import {
10
+ getNavigationPropsV2,
11
+ resolveNavigationPlugin,
12
+ } from "@applicaster/zapp-react-native-utils/navigationUtils";
13
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
14
+ import {
15
+ useDimensions,
16
+ useRoute,
17
+ useCurrentScreenData,
18
+ useNavbarState,
19
+ useScreenData,
20
+ useNavigation,
21
+ } from "@applicaster/zapp-react-native-utils/reactHooks";
22
+ import { getNavigationPluginModule } from "@applicaster/zapp-react-native-app/App/Layout/layoutHelpers";
23
+
12
24
  import { ScreenContextProvider } from "../../Contexts/ScreenContext";
25
+ import { RouteManager } from "../RouteManager";
26
+ import { useScreenConfiguration } from "../River/useScreenConfiguration";
27
+ import { useScreenOrientationHandler } from "./orientationHandler";
13
28
 
14
- type Props = {
15
- pathname: string;
16
- screenData: Record<string, any>;
17
- NavBar: ZappPlugin;
18
- Menu: ZappPlugin;
19
- navBarProps: Record<string, any>;
20
- isNavBarVisible: boolean;
21
- menuProps: {
22
- setToggleMenu: () => void;
23
- toggleMenu: () => void;
24
- openMenu: () => void;
25
- setOpenMenu: () => void;
26
- closeMenu: () => void;
27
- setCloseMenu: () => void;
28
- dimensions: { window: number };
29
- navigator: ZappNavigationProps;
30
- bottomTabBarHeight: number;
31
- isRTL: boolean;
32
- category: string;
33
- } & QuickBrickAppNavigator;
29
+ const getScreenId = (
30
+ screenData: LegacyNavigationScreenData,
31
+ fallbackRiver: ZappRiver
32
+ ) => {
33
+ return screenData?.targetScreen
34
+ ? screenData?.targetScreen?.id ?? fallbackRiver.id
35
+ : "screen_id" in screenData
36
+ ? screenData.screen_id
37
+ : fallbackRiver.id;
34
38
  };
35
39
 
36
40
  function colorIsNotTransparent(color) {
@@ -50,25 +54,75 @@ function isValidColor(string) {
50
54
  return string && string !== "transparent" && colorIsNotTransparent(string);
51
55
  }
52
56
 
53
- export function Screen(props: Props) {
54
- const { pathname, screenData, NavBar } = props;
57
+ type Props = {
58
+ pathname: unknown;
59
+ screenData: unknown;
60
+ };
61
+
62
+ export function Screen(_props: Props) {
63
+ const theme = useTheme<BaseThemePropertiesMobile>();
64
+ const navigation = useNavigation();
55
65
  const { plugins } = usePickFromState(["plugins"]);
56
66
 
57
- const offlinePlugin = useMemo(
67
+ // Gets the data for the current screen configuration
68
+ const currentScreenData = useCurrentScreenData();
69
+ const { backgroundColor } = useScreenConfiguration(currentScreenData.id);
70
+ const insets = useSafeAreaInsets();
71
+
72
+ const { width: screenWidth } = useDimensions("screen", {
73
+ fullDimensions: true,
74
+ });
75
+
76
+ const { screenData, pathname } = useRoute();
77
+
78
+ const currentRiver = useScreenData(
79
+ getScreenId(screenData, navigation.activeRiver)
80
+ );
81
+
82
+ const { title } = useNavbarState();
83
+
84
+ const hasMenu =
85
+ resolveNavigationPlugin({
86
+ category: "menu",
87
+ navigations: currentRiver.navigations,
88
+ plugins,
89
+ })?.identifier === "quick_brick_side_menu";
90
+
91
+ const navBarProps = React.useMemo<MobileNavBarPluginProps | null>(() => {
92
+ const props = getNavigationPropsV2({
93
+ currentRiver,
94
+ title,
95
+ category: "nav_bar",
96
+ });
97
+
98
+ if (props) {
99
+ return {
100
+ ...props,
101
+ id: pathname,
102
+ pathname: pathname,
103
+ };
104
+ }
105
+
106
+ return null;
107
+ }, [currentRiver, pathname]);
108
+
109
+ const NavBar = React.useMemo(
58
110
  () =>
59
- R.compose(
60
- R.prop("module"),
61
- R.find(R.propEq("identifier", "offline-experience"))
62
- )(plugins),
63
- [plugins]
111
+ getNavigationPluginModule(
112
+ "nav_bar",
113
+ currentRiver,
114
+ plugins
115
+ ) as React.ComponentType<MobileNavBarPluginProps & { hasMenu: boolean }>,
116
+ []
64
117
  );
65
118
 
66
- const { OfflineFallbackScreen } = offlinePlugin;
119
+ const offlinePlugin = getComponentModule({
120
+ plugins,
121
+ components: {},
122
+ componentType: "offline-experience",
123
+ });
67
124
 
68
- // Gets the data for the current screen configuration
69
- const currentScreenData = useCurrentScreenData();
70
- const theme = useTheme();
71
- const { backgroundColor } = useScreenConfiguration(currentScreenData.id);
125
+ const { OfflineFallbackScreen } = offlinePlugin;
72
126
 
73
127
  const style = React.useMemo(
74
128
  () => ({
@@ -76,21 +130,26 @@ export function Screen(props: Props) {
76
130
  backgroundColor: isValidColor(backgroundColor)
77
131
  ? backgroundColor
78
132
  : theme.app_background_color,
133
+ paddingTop: 0,
134
+ // paddingBottom: insets.bottom, // Should be applied directly by UI plugin
135
+ // paddingLeft: insets.left, // Should be applied directly by UI plugin
136
+ // paddingRight: insets.right, // Should be applied directly by UI plugin
79
137
  }),
80
- [theme.app_background_color, backgroundColor]
138
+ [insets, screenWidth, theme.app_background_color, backgroundColor]
81
139
  );
82
140
 
83
141
  const targetScreenData =
84
- currentScreenData || screenData?.targetScreen || screenData;
142
+ currentScreenData || (screenData as any)?.targetScreen || screenData;
85
143
 
86
144
  useScreenOrientationHandler({ screenData: targetScreenData });
87
145
 
88
146
  return (
89
147
  <ScreenContextProvider pathname={pathname}>
90
148
  <View style={style}>
91
- <NavBar key={pathname} {...props.navBarProps} />
149
+ {navBarProps && <NavBar {...navBarProps} hasMenu={hasMenu} />}
92
150
 
93
- <OfflineFallbackScreen screenData={screenData}>
151
+ <OfflineFallbackScreen screenData={targetScreenData}>
152
+ {/* @TODO RouteManager doesn't use props, can they be removed ? */}
94
153
  <RouteManager pathname={pathname} screenData={screenData} />
95
154
  </OfflineFallbackScreen>
96
155
  </View>
@@ -1,85 +1,3 @@
1
- import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
2
-
3
- /**
4
- * This function helps to decide wether the navbar should be presented on the screen
5
- * based on route and / or screen Data
6
- *
7
- * Currently the scenarios include
8
- * - players => false
9
- * - search screen plugin => false
10
- * - hooks with `showNavBar: true` or `presentFullScreen` not set to true, defaults to no navbar for hook screens
11
- * - screens with `allow_screen_plugin_presentation` in general property => false
12
- *
13
- * @param {String} route current route of the screen
14
- * @param {Object} screenData payload associated with the currently presented screen
15
- * @returns {Boolean}
16
- */
17
- export function isNavBarVisible(
18
- route,
19
- screenData,
20
- showNavBar,
21
- canGoBack,
22
- videoModalState: QuickBrickVideoModalState | null = null
23
- ) {
24
- /* screenData is not actual navigator.data
25
- * or navigator.screenData,
26
- * but navigator.data.screen */
27
- if (route.includes("playable")) {
28
- return false;
29
- }
30
-
31
- if (
32
- videoModalState?.mode === "FULLSCREEN" &&
33
- videoModalState?.visible === true
34
- ) {
35
- return false;
36
- }
37
-
38
- if (screenData?.type === "qb_search_screen" && !isTV()) {
39
- return false;
40
- }
41
-
42
- /* Match if screen is Hook */
43
- if (route.startsWith("/hooks/")) {
44
- const module = screenData?.module;
45
-
46
- if (module?.presentFullScreen) {
47
- return false;
48
- }
49
-
50
- return module?.showNavBar ?? false;
51
- }
52
-
53
- if (screenData?.hookPlugin) {
54
- const hookPlugin = screenData?.hookPlugin?.module;
55
-
56
- return (
57
- hookPlugin?.showNavBar || hookPlugin?.presentFullScreen !== true || false
58
- );
59
- }
60
-
61
- if (
62
- screenData?.general?.allow_screen_plugin_presentation ||
63
- screenData?.general?.hide_app_nav_bar
64
- ) {
65
- return false;
66
- }
67
-
68
- const hideSecondaryLevel = screenData?.navigations?.some(
69
- (navigation) => navigation.styles?.hide_secondary_level_menu
70
- );
71
-
72
- if (canGoBack && hideSecondaryLevel) {
73
- return false;
74
- }
75
-
76
- if (typeof showNavBar === "boolean" && !showNavBar) {
77
- return false;
78
- }
79
-
80
- return true;
81
- }
82
-
83
1
  /**
84
2
  * This function helps to decide wether the menu should be presented on the screen
85
3
  * based on route and / or screen Data
@@ -8,7 +8,7 @@ import {
8
8
 
9
9
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
10
10
  import { findPluginByType } from "@applicaster/zapp-react-native-utils/pluginUtils";
11
- import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks/device/useIsTablet";
11
+ import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
12
12
  import { ZappHookModalContext } from "../../Contexts";
13
13
  import { HookModalContextT } from "../../Contexts/ZappHookModalContext";
14
14
 
@@ -91,7 +91,7 @@ export function ScreenResolverComponent(props: Props) {
91
91
  <HookRenderer
92
92
  screenData={screenData}
93
93
  focused={props.focused}
94
- parentFocus={props.parentFocus}
94
+ parentFocus={props.parentFocus as ParentFocus}
95
95
  />
96
96
  )
97
97
  );
@@ -78,7 +78,7 @@ export const getStyles = (config): Partial<TVTabsStyles> => {
78
78
  },
79
79
  tvos: {
80
80
  marginTop: -1,
81
- }
81
+ },
82
82
  }),
83
83
  },
84
84
  tabsBackground: {
@@ -17,9 +17,12 @@ type TrackedViewProps = {
17
17
  export const TrackedView = memo(function TrackedView(props: TrackedViewProps) {
18
18
  const children = props.children;
19
19
 
20
- const onPositionUpdated = useCallback((event: TrackedViewNativeProps) => {
21
- props?.onPositionUpdated(event.nativeEvent);
22
- }, []);
20
+ const onPositionUpdated = useCallback(
21
+ (event: TrackedViewNativeProps) => {
22
+ props.onPositionUpdated(event.nativeEvent);
23
+ },
24
+ [props.onPositionUpdated]
25
+ );
23
26
 
24
27
  if (isTV()) {
25
28
  return <View {...(props as any)}>{children}</View>;
@@ -6,6 +6,7 @@ import {
6
6
  import { setUserCellPlayerMutedPreference } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/userCellPlayerMutedPreference";
7
7
  import { loggerLiveImageManager } from "./loggerHelper";
8
8
  import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
9
+ import { Component } from "react";
9
10
 
10
11
  const { log_debug, log_info, log_error } = loggerLiveImageManager;
11
12
 
@@ -36,7 +37,8 @@ type Position = {
36
37
  type LiveImageProps = {
37
38
  player: Player;
38
39
  playerId: string;
39
- setMode: (type: LiveImageType) => void;
40
+ setMode?: (type: LiveImageType) => void;
41
+ component: Component;
40
42
  // TODO: ...primary, powerCell, tvGallery, etc.
41
43
  // type: string;
42
44
  };
@@ -164,7 +166,7 @@ export class LiveImageManager implements PlayerLifecycleListener {
164
166
 
165
167
  // Fake close event, because we unmount native view
166
168
  item.player?.onPlayerClose();
167
- item.setMode(LiveImageType.Image);
169
+ item.setMode?.(LiveImageType.Image);
168
170
 
169
171
  if (item === this.currentlyPlaying) {
170
172
  this.currentlyPlaying = null;
@@ -191,8 +193,7 @@ export class LiveImageManager implements PlayerLifecycleListener {
191
193
  }
192
194
 
193
195
  this.currentlyPlaying = item;
194
-
195
- item.setMode(LiveImageType.Video);
196
+ item.setMode?.(LiveImageType.Video);
196
197
 
197
198
  if (item.player.playerState.isReadyToPlay) {
198
199
  item.player.play();
@@ -209,6 +210,11 @@ export class LiveImageManager implements PlayerLifecycleListener {
209
210
  this.pauseItem(item);
210
211
  };
211
212
 
213
+ public onLiveImageCompleted = (_item: LiveImage) => {
214
+ // TODO: Notify listeners that player has died
215
+ // Do not try look for new playable, otherwise you will restart video finish to play
216
+ };
217
+
212
218
  public muteAll = () => {
213
219
  log_debug("muteAll");
214
220
 
@@ -235,6 +241,14 @@ export class LiveImageManager implements PlayerLifecycleListener {
235
241
  const playerItem = this.findNextPlayableItem();
236
242
 
237
243
  if (playerItem) {
244
+ if (!playerItem.isFullyVisible) {
245
+ log_error(
246
+ `checkPlayerPosition: trying to start playback currently invisible item: ${playerInfo(
247
+ playerItem.player
248
+ )}`
249
+ );
250
+ }
251
+
238
252
  // Will also check if it's item that already playing
239
253
  this.playLiveImage(playerItem);
240
254
  }
@@ -242,7 +256,6 @@ export class LiveImageManager implements PlayerLifecycleListener {
242
256
 
243
257
  onPrimaryPlayerClosed = () => {
244
258
  const playerItem = this.findNextPlayableItem();
245
-
246
259
  log_info("onPrimaryPlayerClosed: starting to play visible live-image");
247
260
 
248
261
  this.currentlyPlaying = null;
@@ -356,12 +369,12 @@ export class LiveImageManager implements PlayerLifecycleListener {
356
369
  // TODO: This branch was used when we had play button to toggle replay.
357
370
  // Now we mute button instead but we keep it just in case.
358
371
  if (IS_ALLOWED_REPLAY && !isTV() && isCurrentItemEnded) {
359
- this.currentlyPlaying.player.seekTo(0);
360
- this.currentlyPlaying.player.pause();
372
+ this.currentlyPlaying?.player.seekTo(0);
373
+ this.currentlyPlaying?.player.pause();
361
374
 
362
375
  // TODO: ...Maybe player some other item
363
376
  } else {
364
- item.setMode(LiveImageType.Image);
377
+ item.setMode?.(LiveImageType.Image);
365
378
  }
366
379
 
367
380
  // Prevent receiving onEnd event from both `close` and `end` player events
@@ -377,10 +390,25 @@ export class LiveImageManager implements PlayerLifecycleListener {
377
390
  };
378
391
 
379
392
  onLiveImageError = (item: LiveImage, error: Error) => {
380
- item.setMode(LiveImageType.Image);
393
+ item.setMode?.(LiveImageType.Image);
381
394
 
382
- if (this.currentlyPlaying === item) {
395
+ const currentItem = this.currentlyPlaying;
396
+
397
+ log_debug(
398
+ `onLiveImageError: error: ${error.message}, live-image ${playerInfo(
399
+ item.player
400
+ )}, currentPlayingId: ${
401
+ this.currentlyPlaying?.playerId
402
+ }, primaryPlayerId: ${this.primaryPlayer?.playerId}`
403
+ );
404
+
405
+ if (currentItem === item) {
383
406
  this.currentlyPlaying = null;
407
+
408
+ log_debug(
409
+ `onLiveImageError: currentitem: ${currentItem.playerId} was removed`
410
+ );
411
+
384
412
  // TODO: ...Maybe player some other item
385
413
  }
386
414
 
@@ -389,8 +417,8 @@ export class LiveImageManager implements PlayerLifecycleListener {
389
417
  event: {
390
418
  item,
391
419
  error,
392
- playerId: this.currentlyPlaying?.playerId,
393
- primaryPlayerId: this.primaryPlayer?.playerId,
420
+ playerId: currentItem?.playerId,
421
+ primaryPlayerId: currentItem?.playerId,
394
422
  },
395
423
  });
396
424
  };
@@ -446,12 +474,13 @@ export class LiveImage implements QuickBrickPlayer.SharedPlayerCallBacks {
446
474
  };
447
475
 
448
476
  readonly playerId: string;
477
+ readonly component: Component;
449
478
 
450
479
  constructor(props: LiveImageProps) {
451
480
  this.player = props.player;
452
481
  this.setMode = props.setMode;
453
482
  this.playerId = this.player.playerId;
454
-
483
+ this.component = props.component;
455
484
  this.player.addListener({ id: "live-image", listener: this });
456
485
  }
457
486