@applicaster/zapp-react-native-ui-components 12.0.0-rc.14 → 12.0.0-rc.140
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.
- package/Components/AudioPlayer/AudioPlayer.tsx +9 -1
- package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +5 -0
- package/Components/AudioPlayer/helpers.tsx +1 -0
- package/Components/BaseFocusable/index.tsx +3 -3
- package/Components/Cell/Cell.tsx +40 -12
- package/Components/Cell/CellWithFocusable.tsx +40 -19
- package/Components/Cell/TvOSCellComponent.tsx +5 -9
- package/Components/ErrorScreen/index.tsx +1 -1
- package/Components/Focusable/Focusable.tsx +6 -1
- package/Components/Focusable/__tests__/index.android.test.tsx +72 -0
- package/Components/Focusable/index.android.tsx +15 -9
- package/Components/FocusableCell/index.tsx +7 -7
- package/Components/FocusableGroup/index.tsx +11 -2
- package/Components/FocusableList/FocusableChild.ts +26 -16
- package/Components/FocusableList/FocusableItem.tsx +1 -1
- package/Components/FocusableList/FocusableListItemWrapper.tsx +76 -0
- package/Components/FocusableList/hooks/useCellState.android.ts +3 -1
- package/Components/FocusableList/index.tsx +37 -37
- package/Components/FocusableScrollView/index.tsx +1 -1
- package/Components/FreezeWithCallback/Freeze.tsx +31 -0
- package/Components/FreezeWithCallback/LICENSE +21 -0
- package/Components/FreezeWithCallback/Suspender.tsx +17 -0
- package/Components/FreezeWithCallback/__tests__/index.test.tsx +170 -0
- package/Components/FreezeWithCallback/index.tsx +3 -0
- package/Components/GeneralContentScreen/GeneralContentScreen.tsx +11 -8
- package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +13 -6
- package/Components/GeneralContentScreen/utils/useCurationAPI.ts +1 -1
- package/Components/HandlePlayable/HandlePlayable.tsx +4 -1
- package/Components/HookRenderer/index.tsx +1 -6
- package/Components/Image/Image.android.tsx +4 -26
- package/Components/Image/Image.tsx +18 -2
- package/Components/Image/utils/index.ts +39 -0
- package/Components/Layout/TV/ScreenContainer.tsx +79 -5
- package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +2 -2
- package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +38 -28
- package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +25 -13
- package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +10 -50
- package/Components/Layout/TV/__tests__/index.test.tsx +20 -108
- package/Components/Layout/TV/index.tsx +15 -84
- package/Components/Layout/TV/index.web.tsx +33 -0
- package/Components/Layout/index.tsx +15 -11
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +14 -7
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +86 -117
- package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +27 -9
- package/Components/MasterCell/DefaultComponents/DynamicBadge.tsx +4 -2
- package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +16 -1
- package/Components/MasterCell/DefaultComponents/Image/Image.android.tsx +9 -26
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +3 -0
- package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +2 -2
- package/Components/MasterCell/DefaultComponents/Image/hooks/useImageSize.ts +65 -0
- package/Components/MasterCell/DefaultComponents/ImageBorderContainer/index.ts +71 -0
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +5 -1
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +37 -2
- package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +3 -2
- package/Components/MasterCell/DefaultComponents/Text/index.tsx +14 -2
- package/Components/MasterCell/DefaultComponents/Toggle.tsx +5 -1
- package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +24 -9
- package/Components/MasterCell/DefaultComponents/index.ts +2 -0
- package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.android.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/tv/ButtonContainerView/index.tsx +10 -2
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +6 -10
- package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +7 -1
- package/Components/MasterCell/dataAdapter.ts +21 -7
- package/Components/MasterCell/hooks/useAsyncRendering/index.ts +1 -1
- package/Components/MasterCell/index.tsx +5 -3
- package/Components/MasterCell/utils/__tests__/insertBetween.test.js +9 -0
- package/Components/MasterCell/utils/index.ts +31 -34
- package/Components/MeasurmentsPortal/BasicMeasurementsPortal.tsx +11 -7
- package/Components/MeasurmentsPortal/MeasurementsPortal.tsx +10 -1
- package/Components/ModalComponent/BottomSheetModalContent.tsx +121 -0
- package/Components/ModalComponent/Button/Item.tsx +82 -0
- package/Components/ModalComponent/Button/ItemIcon.tsx +60 -0
- package/Components/ModalComponent/Button/ItemLabel.tsx +101 -0
- package/Components/ModalComponent/Button/assets.ts +4 -0
- package/Components/ModalComponent/Button/index.tsx +111 -0
- package/Components/ModalComponent/Header/CloseButton.tsx +59 -0
- package/Components/ModalComponent/Header/Title.tsx +70 -0
- package/Components/ModalComponent/Header/assets.ts +4 -0
- package/Components/ModalComponent/Header/index.tsx +71 -0
- package/Components/ModalComponent/Header/utils.ts +79 -0
- package/Components/ModalComponent/index.tsx +38 -0
- package/Components/ModalComponent/utils.ts +126 -0
- package/Components/Navigator/StackNavigator.tsx +57 -0
- package/Components/Navigator/index.ts +1 -0
- package/Components/PlayerContainer/PlayerContainer.tsx +80 -39
- package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -1
- package/Components/PlayerImageBackground/index.tsx +34 -8
- package/Components/River/ComponentsMap/ComponentsMap.tsx +97 -2
- package/Components/River/RefreshControl.tsx +55 -1
- package/Components/River/TV/River.tsx +2 -25
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +1 -1
- package/Components/River/__tests__/componentsMap.test.js +7 -0
- package/Components/River/useScreenConfiguration.ts +2 -2
- package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +1 -0
- package/Components/RouteManager/__tests__/routeManager.test.js +9 -2
- package/Components/RouteManager/index.tsx +4 -2
- package/Components/Screen/TV/hooks/index.ts +1 -0
- package/Components/Screen/TV/hooks/useInitialFocus.ts +70 -0
- package/Components/Screen/TV/index.web.tsx +178 -0
- package/Components/Screen/__tests__/Screen.test.tsx +43 -75
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +24 -6
- package/Components/Screen/__tests__/navigationHandler.test.ts +1 -178
- package/Components/Screen/index.tsx +104 -65
- package/Components/Screen/navigationHandler.ts +6 -85
- package/Components/Screen/orientationHandler.ts +18 -7
- package/Components/Screen/utils.ts +16 -0
- package/Components/ScreenResolver/index.tsx +10 -13
- package/Components/Tabs/TV/styles.ts +1 -1
- package/Components/TrackedView/index.tsx +6 -3
- package/Components/Transitioner/Scene.tsx +39 -26
- package/Components/Transitioner/Transitioner.tsx +56 -48
- package/Components/Transitioner/__tests__/Scene.test.js +7 -0
- package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +12 -4
- package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +2 -0
- package/Components/VideoLive/LiveImageManager.ts +65 -11
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +132 -95
- package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +45 -3
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +24 -27
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +60 -0
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +401 -0
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +172 -0
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +475 -0
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +182 -0
- package/Components/VideoModal/ModalAnimation/index.ts +15 -0
- package/Components/VideoModal/ModalAnimation/utils.ts +302 -0
- package/Components/VideoModal/PlayerDetails.tsx +21 -4
- package/Components/VideoModal/PlayerWrapper.tsx +115 -55
- package/Components/VideoModal/VideoModal.tsx +32 -43
- package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +6 -1
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +12 -1
- package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -0
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +358 -166
- package/Components/VideoModal/hooks/useModalSize.ts +10 -12
- package/Components/VideoModal/utils.ts +8 -5
- package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +26 -21
- package/Components/Viewport/ViewportTracker/ViewportTracker.tsx +31 -40
- package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +4 -5
- package/Components/Viewport/ViewportTracker/index.tsx +1 -0
- package/Components/Viewport/utils.js +1 -1
- package/Components/ZappFrameworkComponents/BarView/BarView.tsx +7 -3
- package/Components/ZappFrameworkComponents/BarView/Buttons/BackButton.tsx +7 -2
- package/Components/ZappFrameworkComponents/BarView/Buttons/CloseButton.tsx +7 -2
- package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +87 -0
- package/Components/ZappFrameworkComponents/Buttons/ActionButton.tsx +9 -4
- package/Components/ZappUIComponent/index.tsx +22 -12
- package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +4 -4
- package/Components/index.js +2 -0
- package/Contexts/CachedDimensionsContext/index.ts +13 -9
- package/Contexts/ConfirmDialogState/index.ts +1 -1
- package/Contexts/FocusableGroupContext/FocusableGroupContext.ts +3 -0
- package/Contexts/FocusableGroupContext/FocusableGroupContextProvider.tsx +16 -0
- package/Contexts/FocusableGroupContext/__tests__/FocusableGroupContextProvider.test.tsx +22 -0
- package/Contexts/FocusableGroupContext/__tests__/withFocusableContext.test.tsx +26 -0
- package/Contexts/FocusableGroupContext/index.ts +7 -0
- package/Contexts/FocusableGroupContext/withFocusableContext.tsx +17 -0
- package/Contexts/MenuToggleContext/{index.js → index.ts} +16 -0
- package/Contexts/ScreenContext/__tests__/__snapshots__/index.test.tsx.snap +3 -0
- package/Contexts/ScreenContext/__tests__/index.test.tsx +27 -0
- package/Contexts/ScreenContext/index.tsx +101 -30
- package/Contexts/ScreenDataContext/index.tsx +20 -0
- package/Contexts/ZappPipesContext/ZappPipesEntryContext.ts +1 -1
- package/Decorators/ComponentsMapWrapper/withComponentsMapProvider.tsx +7 -2
- package/const.ts +6 -0
- package/events/index.ts +1 -0
- package/index.js +3 -0
- package/package.json +5 -5
- package/Components/Layout/TV/TransitionOverlay.tsx +0 -64
- package/Components/VideoModal/hooks/usePosition.ts +0 -50
- /package/Components/FocusableGroup/{index.android.js → index.android.ts} +0 -0
- /package/Components/FocusableGroup/{index.ios.js → index.ios.ts} +0 -0
- /package/Contexts/{index.js → index.ts} +0 -0
|
@@ -1,28 +1,17 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
4
|
-
import {
|
|
5
|
-
useIsNavBarVisible,
|
|
6
|
-
useNavigation,
|
|
7
|
-
} from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
|
|
4
|
+
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
|
|
8
5
|
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
9
6
|
|
|
10
|
-
import {
|
|
11
|
-
getNavigationProps,
|
|
12
|
-
resolveNavigationPlugin,
|
|
13
|
-
routeIsPlayerScreen,
|
|
14
|
-
} from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
15
|
-
|
|
16
7
|
import { getBackgroundImageUrl } from "../utils";
|
|
17
8
|
import { LayoutContainer } from "./LayoutContainer";
|
|
18
|
-
import { NavBarContainer } from "./NavBarContainer";
|
|
19
9
|
import { ScreenContainer } from "./ScreenContainer";
|
|
20
|
-
import { TransitionOverlay } from "./TransitionOverlay";
|
|
21
10
|
|
|
22
11
|
import { ScreenLayoutContextProvider } from "./ScreenLayoutContextProvider";
|
|
23
|
-
import { isApplePlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
24
12
|
import { PathnameContext } from "../../../Contexts/PathnameContext";
|
|
25
|
-
import {
|
|
13
|
+
import { ScreenDataContext } from "../../../Contexts/ScreenDataContext";
|
|
14
|
+
import { ScreenContextProvider } from "../../../Contexts/ScreenContext";
|
|
26
15
|
|
|
27
16
|
type Components = {
|
|
28
17
|
NavBar: React.ComponentType<any>;
|
|
@@ -43,20 +32,9 @@ type Props = {
|
|
|
43
32
|
const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
|
|
44
33
|
const navigator = useNavigation();
|
|
45
34
|
const theme = useTheme();
|
|
46
|
-
const { title } = useNavbarState();
|
|
47
|
-
const { activeRiver, currentRoute } = navigator;
|
|
48
|
-
|
|
49
|
-
const {
|
|
50
|
-
appState: { appReady = false } = {},
|
|
51
|
-
remoteConfigurations,
|
|
52
|
-
plugins = [],
|
|
53
|
-
} = usePickFromState(["appState", "remoteConfigurations", "plugins"]);
|
|
54
35
|
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
title,
|
|
58
|
-
category: "menu",
|
|
59
|
-
});
|
|
36
|
+
const { appState: { appReady = false } = {}, remoteConfigurations } =
|
|
37
|
+
usePickFromState(["appState", "remoteConfigurations", "plugins"]);
|
|
60
38
|
|
|
61
39
|
const backgroundColor = React.useMemo(() => theme.app_background_color, []);
|
|
62
40
|
|
|
@@ -65,25 +43,6 @@ const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
|
|
|
65
43
|
[remoteConfigurations]
|
|
66
44
|
);
|
|
67
45
|
|
|
68
|
-
const menuPlugin = React.useMemo(
|
|
69
|
-
() =>
|
|
70
|
-
resolveNavigationPlugin({
|
|
71
|
-
category: "menu",
|
|
72
|
-
navigations: activeRiver?.navigations,
|
|
73
|
-
plugins,
|
|
74
|
-
}) as QuickBrickPlugin,
|
|
75
|
-
[]
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
const NavBar = React.useMemo(
|
|
79
|
-
() => Components.NavBar || (menuPlugin.module as React.ComponentType<any>),
|
|
80
|
-
[]
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
const navBarVisible = useIsNavBarVisible();
|
|
84
|
-
|
|
85
|
-
const [navBarReady, setNavBarReady] = React.useState(false);
|
|
86
|
-
|
|
87
46
|
if (!appReady) {
|
|
88
47
|
return null;
|
|
89
48
|
}
|
|
@@ -96,46 +55,18 @@ const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
|
|
|
96
55
|
backgroundImageUrl={backgroundImageUrl}
|
|
97
56
|
{...R.omit(["ref"])(ComponentsExtraProps?.Background)}
|
|
98
57
|
>
|
|
99
|
-
{
|
|
100
|
-
<NavBarContainer isVisible={navBarVisible} onReady={setNavBarReady}>
|
|
101
|
-
<NavBar
|
|
102
|
-
ref={ComponentsExtraProps?.NavBar?.ref}
|
|
103
|
-
isVisible={navBarVisible && !routeIsPlayerScreen(currentRoute)}
|
|
104
|
-
menuPlugin={menuPlugin}
|
|
105
|
-
navigationProps={navigationProps}
|
|
106
|
-
{...R.omit(["ref"])(ComponentsExtraProps?.NavBar)}
|
|
107
|
-
/>
|
|
108
|
-
</NavBarContainer>
|
|
109
|
-
) : null}
|
|
110
|
-
|
|
111
|
-
{navBarReady ? (
|
|
112
|
-
/**
|
|
113
|
-
Need to re-mount this component on each navigation event
|
|
114
|
-
It's a hack to work around the fact that we don't support
|
|
115
|
-
correct screen rendering in our navigator (shared currentRoute state)
|
|
116
|
-
**/
|
|
58
|
+
<ScreenDataContext.Provider value={navigator.data}>
|
|
117
59
|
<PathnameContext.Provider value={navigator.currentRoute}>
|
|
118
|
-
<
|
|
60
|
+
<ScreenContextProvider pathname={navigator.currentRoute}>
|
|
61
|
+
<ScreenContainer
|
|
62
|
+
ComponentsExtraProps={ComponentsExtraProps}
|
|
63
|
+
NavBar={Components.NavBar}
|
|
64
|
+
>
|
|
65
|
+
{children}
|
|
66
|
+
</ScreenContainer>
|
|
67
|
+
</ScreenContextProvider>
|
|
119
68
|
</PathnameContext.Provider>
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
{isApplePlatform() ? (
|
|
123
|
-
/**
|
|
124
|
-
Render NavBarContainer over ScreenContainer to let tvOS native
|
|
125
|
-
focus manager works correctly to focus nav bar items first
|
|
126
|
-
**/
|
|
127
|
-
<NavBarContainer isVisible={navBarVisible} onReady={setNavBarReady}>
|
|
128
|
-
<NavBar
|
|
129
|
-
ref={ComponentsExtraProps?.NavBar?.ref}
|
|
130
|
-
isVisible={navBarVisible && !routeIsPlayerScreen(currentRoute)}
|
|
131
|
-
menuPlugin={menuPlugin}
|
|
132
|
-
navigationProps={navigationProps}
|
|
133
|
-
{...R.omit(["ref"])(ComponentsExtraProps?.NavBar)}
|
|
134
|
-
/>
|
|
135
|
-
</NavBarContainer>
|
|
136
|
-
) : null}
|
|
137
|
-
|
|
138
|
-
<TransitionOverlay />
|
|
69
|
+
</ScreenDataContext.Provider>
|
|
139
70
|
</Components.Background>
|
|
140
71
|
</ScreenLayoutContextProvider>
|
|
141
72
|
</LayoutContainer>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { pathOr } from "ramda";
|
|
3
|
+
|
|
4
|
+
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
5
|
+
|
|
6
|
+
import { ScreenLayoutContextProvider } from "./ScreenLayoutContextProvider";
|
|
7
|
+
import { StackNavigator } from "../../Navigator";
|
|
8
|
+
|
|
9
|
+
type Components = {
|
|
10
|
+
NavBar: React.ComponentType<any>;
|
|
11
|
+
Background: React.ComponentType<any>;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type Props = {
|
|
15
|
+
Components: Components;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const Layout = ({ Components }: Props) => {
|
|
19
|
+
const { appState } = usePickFromState(["appState"]);
|
|
20
|
+
const appReady = pathOr(false, ["appReady"], appState);
|
|
21
|
+
|
|
22
|
+
if (!appReady) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<ScreenLayoutContextProvider>
|
|
28
|
+
<StackNavigator Components={Components} />
|
|
29
|
+
</ScreenLayoutContextProvider>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export default Layout;
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import {
|
|
3
|
+
isTV,
|
|
4
|
+
platformSelect,
|
|
5
|
+
} from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
5
6
|
|
|
6
7
|
import Mobile from "./Mobile";
|
|
7
|
-
import TV from "./TV";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
import TVWeb from "./TV/index.web";
|
|
10
|
+
import TVDefault from "./TV/index";
|
|
11
|
+
|
|
12
|
+
const TV = platformSelect({
|
|
13
|
+
samsung_tv: TVWeb,
|
|
14
|
+
lg_tv: TVWeb,
|
|
15
|
+
web: TVWeb,
|
|
16
|
+
default: TVDefault,
|
|
17
|
+
});
|
|
11
18
|
|
|
19
|
+
export default function Layout(props) {
|
|
12
20
|
if (isTV()) {
|
|
13
|
-
return
|
|
14
|
-
<ScreenContextProvider pathname={pathname}>
|
|
15
|
-
<TV {...props} />
|
|
16
|
-
</ScreenContextProvider>
|
|
17
|
-
);
|
|
21
|
+
return <TV {...props} />;
|
|
18
22
|
} else {
|
|
19
23
|
return <Mobile {...props} />;
|
|
20
24
|
}
|
|
@@ -25,6 +25,7 @@ type Props = {
|
|
|
25
25
|
testID?: string;
|
|
26
26
|
accessibilityLabel?: string;
|
|
27
27
|
cellUUID?: string;
|
|
28
|
+
extraProps?: Record<string, any>;
|
|
28
29
|
};
|
|
29
30
|
|
|
30
31
|
function isStringAsset(asset) {
|
|
@@ -52,6 +53,7 @@ export function ActionButton(props: Props) {
|
|
|
52
53
|
const { item, action, asset, flavour = "flavour_1", cellUUID } = props;
|
|
53
54
|
const actionContext = useActions(action?.identifier);
|
|
54
55
|
|
|
56
|
+
// TODO: add subscription API for action availability
|
|
55
57
|
const actionDisabled =
|
|
56
58
|
typeof actionContext?.isActionAvailable === "function" &&
|
|
57
59
|
!actionContext.isActionAvailable(item);
|
|
@@ -64,20 +66,24 @@ export function ActionButton(props: Props) {
|
|
|
64
66
|
);
|
|
65
67
|
|
|
66
68
|
useEffect(() => {
|
|
67
|
-
if (actionDisabled || !actionContext)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}, [actionDisabled, item?.id]);
|
|
69
|
+
if (!((actionDisabled || !actionContext) && actionState !== null)) {
|
|
70
|
+
setActionState(actionContext.initialEntryState(item));
|
|
71
|
+
}
|
|
72
|
+
}, [actionDisabled, item?.id, actionContext, action]);
|
|
71
73
|
|
|
72
74
|
const onPress = useCallback(() => {
|
|
73
75
|
actionContext.invokeAction(item, {
|
|
74
|
-
updateState:
|
|
76
|
+
updateState: (state) => {
|
|
77
|
+
setActionState(state);
|
|
78
|
+
},
|
|
75
79
|
});
|
|
76
|
-
}, [actionState, actionContext?.state,
|
|
80
|
+
}, [actionState, actionContext?.state, item?.id]);
|
|
77
81
|
|
|
78
82
|
useEffect(() => {
|
|
79
83
|
if (typeof actionContext?.addListener === "function") {
|
|
80
|
-
return actionContext?.addListener(item.id
|
|
84
|
+
return actionContext?.addListener(String(item.id), (state) => {
|
|
85
|
+
setActionState(state);
|
|
86
|
+
});
|
|
81
87
|
}
|
|
82
88
|
}, [item?.id]);
|
|
83
89
|
|
|
@@ -108,6 +114,7 @@ export function ActionButton(props: Props) {
|
|
|
108
114
|
flavour={flavour}
|
|
109
115
|
asset={getAssetValue(asset, flavour)}
|
|
110
116
|
cellUUID={cellUUID}
|
|
117
|
+
{...(props?.extraProps ?? {})}
|
|
111
118
|
/>
|
|
112
119
|
)}
|
|
113
120
|
</TouchableOpacity>
|
|
@@ -7,50 +7,28 @@ type BorderPosition = "inside" | "outside" | "center";
|
|
|
7
7
|
interface Props {
|
|
8
8
|
style: ImageStyle | ViewStyle;
|
|
9
9
|
borderPosition: BorderPosition;
|
|
10
|
+
borderPaddingTop: number;
|
|
11
|
+
borderPaddingRight: number;
|
|
12
|
+
borderPaddingBottom: number;
|
|
13
|
+
borderPaddingLeft: number;
|
|
10
14
|
children: React.ReactNode;
|
|
11
15
|
}
|
|
12
16
|
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
if (typeof value === "string" && value.endsWith("%")) {
|
|
29
|
-
return true;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return false;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const calculateContainerSpacing = ({
|
|
36
|
-
spacingKey,
|
|
37
|
-
style,
|
|
38
|
-
additionalSpacing,
|
|
39
|
-
}: {
|
|
40
|
-
spacingKey: typeof MARGINS[number] | typeof PADDINGS[number];
|
|
41
|
-
style: ImageStyle | ViewStyle;
|
|
42
|
-
additionalSpacing: number;
|
|
43
|
-
}) => {
|
|
44
|
-
return {
|
|
45
|
-
[spacingKey]:
|
|
46
|
-
toNumberWithDefaultZero(style[spacingKey]) + additionalSpacing,
|
|
47
|
-
};
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const getContainerBorderWidth = (
|
|
51
|
-
borderPosition: BorderPosition,
|
|
52
|
-
borderWidth
|
|
53
|
-
) => {
|
|
17
|
+
const COLOR_TRANSPARENT = "transparent";
|
|
18
|
+
|
|
19
|
+
const styles = StyleSheet.create({
|
|
20
|
+
container: {
|
|
21
|
+
overflow: "visible",
|
|
22
|
+
borderWidth: 0,
|
|
23
|
+
borderColor: COLOR_TRANSPARENT,
|
|
24
|
+
},
|
|
25
|
+
border: {
|
|
26
|
+
...StyleSheet.absoluteFillObject,
|
|
27
|
+
zIndex: 1,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const getBorderPadding = (borderPosition: BorderPosition, borderWidth) => {
|
|
54
32
|
switch (borderPosition) {
|
|
55
33
|
case "inside":
|
|
56
34
|
return 0;
|
|
@@ -63,105 +41,96 @@ const getContainerBorderWidth = (
|
|
|
63
41
|
}
|
|
64
42
|
};
|
|
65
43
|
|
|
66
|
-
const
|
|
67
|
-
switch (borderPosition) {
|
|
68
|
-
case "inside":
|
|
69
|
-
return borderWidth;
|
|
70
|
-
case "center":
|
|
71
|
-
return borderWidth / 2;
|
|
72
|
-
case "outside":
|
|
73
|
-
return 0;
|
|
74
|
-
default:
|
|
75
|
-
return 0;
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const InsideBorder = ({
|
|
44
|
+
const Border = ({
|
|
80
45
|
style,
|
|
46
|
+
padding,
|
|
81
47
|
borderPosition,
|
|
82
48
|
}: {
|
|
83
49
|
style: ViewStyle;
|
|
50
|
+
padding: ViewStyle;
|
|
84
51
|
borderPosition: BorderPosition;
|
|
85
52
|
}) => {
|
|
86
|
-
if (borderPosition
|
|
53
|
+
if (!borderPosition) {
|
|
87
54
|
return null;
|
|
88
55
|
}
|
|
89
56
|
|
|
90
|
-
const
|
|
91
|
-
|
|
57
|
+
const borderWidth = toNumberWithDefaultZero(style.borderWidth);
|
|
58
|
+
const containerPadding = getBorderPadding(borderPosition, borderWidth);
|
|
59
|
+
|
|
60
|
+
const initialBorderRadius = toNumberWithDefaultZero(style.borderRadius);
|
|
61
|
+
const paddingTop = toNumberWithDefaultZero(padding.paddingTop);
|
|
62
|
+
const paddingRight = toNumberWithDefaultZero(padding.paddingRight);
|
|
63
|
+
const paddingBottom = toNumberWithDefaultZero(padding.paddingBottom);
|
|
64
|
+
const paddingLeft = toNumberWithDefaultZero(padding.paddingLeft);
|
|
65
|
+
|
|
66
|
+
const borderRadiusStyle = initialBorderRadius
|
|
67
|
+
? {
|
|
68
|
+
borderTopLeftRadius:
|
|
69
|
+
initialBorderRadius +
|
|
70
|
+
containerPadding +
|
|
71
|
+
Math.min(paddingTop, paddingLeft),
|
|
72
|
+
borderTopRightRadius:
|
|
73
|
+
initialBorderRadius +
|
|
74
|
+
containerPadding +
|
|
75
|
+
Math.min(paddingTop, paddingRight),
|
|
76
|
+
borderBottomLeftRadius:
|
|
77
|
+
initialBorderRadius +
|
|
78
|
+
containerPadding +
|
|
79
|
+
Math.min(paddingBottom, paddingLeft),
|
|
80
|
+
borderBottomRightRadius:
|
|
81
|
+
initialBorderRadius +
|
|
82
|
+
containerPadding +
|
|
83
|
+
Math.min(paddingBottom, paddingRight),
|
|
84
|
+
}
|
|
85
|
+
: {
|
|
86
|
+
borderTopLeftRadius: 0,
|
|
87
|
+
borderTopRightRadius: 0,
|
|
88
|
+
borderBottomLeftRadius: 0,
|
|
89
|
+
borderBottomRightRadius: 0,
|
|
90
|
+
};
|
|
92
91
|
|
|
93
92
|
return (
|
|
94
93
|
<View
|
|
94
|
+
pointerEvents="none"
|
|
95
95
|
style={{
|
|
96
|
-
...
|
|
97
|
-
|
|
96
|
+
...styles.border,
|
|
97
|
+
right: -containerPadding - paddingRight,
|
|
98
|
+
bottom: -containerPadding - paddingBottom,
|
|
99
|
+
left: -containerPadding - paddingLeft,
|
|
100
|
+
top: -containerPadding - paddingTop,
|
|
101
|
+
borderWidth,
|
|
98
102
|
borderColor: style.borderColor,
|
|
99
|
-
|
|
103
|
+
...borderRadiusStyle,
|
|
100
104
|
}}
|
|
101
105
|
/>
|
|
102
106
|
);
|
|
103
107
|
};
|
|
104
108
|
|
|
105
109
|
export const BorderContainerView = (props: Props) => {
|
|
106
|
-
const {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const updatedPaddings = PADDINGS.reduce((acc, padding) => {
|
|
127
|
-
const paddingValue = calculateContainerSpacing({
|
|
128
|
-
spacingKey: padding,
|
|
129
|
-
style,
|
|
130
|
-
additionalSpacing: spacing,
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
return { ...acc, ...paddingValue };
|
|
134
|
-
}, {});
|
|
135
|
-
|
|
136
|
-
const updatedWidth = style.width
|
|
137
|
-
? isPercentageValue(style.width)
|
|
138
|
-
? style.width
|
|
139
|
-
: toNumberWithDefaultZero(style.width) - spacing * 2
|
|
140
|
-
: undefined;
|
|
141
|
-
|
|
142
|
-
const updatedHeight = style.height
|
|
143
|
-
? isPercentageValue(style.height)
|
|
144
|
-
? style.height
|
|
145
|
-
: toNumberWithDefaultZero(style.height) - spacing * 2
|
|
146
|
-
: undefined;
|
|
147
|
-
|
|
148
|
-
const containerStyle = {
|
|
149
|
-
borderWidth: getContainerBorderWidth(borderPosition, borderWidth),
|
|
150
|
-
padding: spacing,
|
|
151
|
-
...updatedMargins,
|
|
152
|
-
...updatedPaddings,
|
|
153
|
-
width: updatedWidth,
|
|
154
|
-
height: updatedHeight,
|
|
155
|
-
...borderStyleForMissingBorder,
|
|
156
|
-
};
|
|
110
|
+
const {
|
|
111
|
+
borderPosition,
|
|
112
|
+
borderPaddingTop,
|
|
113
|
+
borderPaddingRight,
|
|
114
|
+
borderPaddingBottom,
|
|
115
|
+
borderPaddingLeft,
|
|
116
|
+
style,
|
|
117
|
+
children,
|
|
118
|
+
} = props;
|
|
119
|
+
|
|
120
|
+
const padding =
|
|
121
|
+
borderPosition === "outside"
|
|
122
|
+
? {
|
|
123
|
+
paddingTop: borderPaddingTop,
|
|
124
|
+
paddingRight: borderPaddingRight,
|
|
125
|
+
paddingBottom: borderPaddingBottom,
|
|
126
|
+
paddingLeft: borderPaddingLeft,
|
|
127
|
+
}
|
|
128
|
+
: {};
|
|
157
129
|
|
|
158
130
|
return (
|
|
159
|
-
<View {...props} style={[style,
|
|
131
|
+
<View pointerEvents="box-none" {...props} style={[style, styles.container]}>
|
|
132
|
+
<Border style={style} padding={padding} borderPosition={borderPosition} />
|
|
160
133
|
{children}
|
|
161
|
-
<InsideBorder
|
|
162
|
-
style={{ ...style, ...borderStyleForMissingBorder }}
|
|
163
|
-
borderPosition={borderPosition}
|
|
164
|
-
/>
|
|
165
134
|
</View>
|
|
166
135
|
);
|
|
167
136
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
compact,
|
|
3
3
|
ifElseFocusedSelected,
|
|
4
|
+
ifElseSelected,
|
|
4
5
|
} from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
6
|
+
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
5
7
|
|
|
6
8
|
import { getPositionStyles } from "./utils";
|
|
7
9
|
|
|
@@ -12,9 +14,15 @@ type Props = {
|
|
|
12
14
|
value: Function;
|
|
13
15
|
state: string;
|
|
14
16
|
visible?: Boolean;
|
|
17
|
+
isMobile?: Boolean;
|
|
15
18
|
};
|
|
16
19
|
|
|
17
|
-
export const CellBadge = ({
|
|
20
|
+
export const CellBadge = ({
|
|
21
|
+
value,
|
|
22
|
+
state,
|
|
23
|
+
visible = true,
|
|
24
|
+
isMobile = false,
|
|
25
|
+
}: Props) => {
|
|
18
26
|
if (!value("cell_badge_switch") || !visible) {
|
|
19
27
|
return null;
|
|
20
28
|
}
|
|
@@ -24,7 +32,11 @@ export const CellBadge = ({ value, state, visible = true }: Props) => {
|
|
|
24
32
|
return {
|
|
25
33
|
type: View, // Cell badge view
|
|
26
34
|
style: {
|
|
27
|
-
flex:
|
|
35
|
+
flex: platformSelect({
|
|
36
|
+
tvos: 0,
|
|
37
|
+
android_tv: 0,
|
|
38
|
+
default: 1,
|
|
39
|
+
}),
|
|
28
40
|
position: "absolute",
|
|
29
41
|
...getPositionStyles(position, {
|
|
30
42
|
width: value("cell_badge_width"),
|
|
@@ -45,13 +57,19 @@ export const CellBadge = ({ value, state, visible = true }: Props) => {
|
|
|
45
57
|
data: [
|
|
46
58
|
{
|
|
47
59
|
func: () => {
|
|
48
|
-
return
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
return isMobile
|
|
61
|
+
? ifElseSelected(
|
|
62
|
+
state,
|
|
63
|
+
value("cell_badge_selected"),
|
|
64
|
+
value("cell_badge_default")
|
|
65
|
+
)
|
|
66
|
+
: ifElseFocusedSelected(
|
|
67
|
+
state,
|
|
68
|
+
value("cell_badge_focused"),
|
|
69
|
+
value("cell_badge_selected"),
|
|
70
|
+
value("cell_badge_focused_selected"),
|
|
71
|
+
value("cell_badge_default")
|
|
72
|
+
);
|
|
55
73
|
},
|
|
56
74
|
args: [],
|
|
57
75
|
propName: "uri",
|
|
@@ -4,6 +4,7 @@ import { usePlayer } from "@applicaster/zapp-react-native-utils/appUtils/playerM
|
|
|
4
4
|
|
|
5
5
|
type DynamicBadgeProps = {
|
|
6
6
|
cellUUID?: string;
|
|
7
|
+
uri?: string;
|
|
7
8
|
};
|
|
8
9
|
|
|
9
10
|
const DynamicBadgeComponent = (props: DynamicBadgeProps) => {
|
|
@@ -12,11 +13,12 @@ const DynamicBadgeComponent = (props: DynamicBadgeProps) => {
|
|
|
12
13
|
// TODO: Initial value should depends on player state (playing or not)
|
|
13
14
|
const [showImage, setShowImage] = React.useState(true);
|
|
14
15
|
const player = usePlayer(playerId);
|
|
16
|
+
const uri = props?.uri;
|
|
15
17
|
|
|
16
18
|
React.useEffect(() => {
|
|
17
19
|
if (playerId && player) {
|
|
18
20
|
return player.addListener({
|
|
19
|
-
id:
|
|
21
|
+
id: `dynamic-badges-${uri}`,
|
|
20
22
|
listener: {
|
|
21
23
|
onPlayerClose: () => {
|
|
22
24
|
setShowImage(true);
|
|
@@ -35,7 +37,7 @@ const DynamicBadgeComponent = (props: DynamicBadgeProps) => {
|
|
|
35
37
|
} else {
|
|
36
38
|
setShowImage(true);
|
|
37
39
|
}
|
|
38
|
-
}, [player]);
|
|
40
|
+
}, [player, uri]);
|
|
39
41
|
|
|
40
42
|
if (!showImage) {
|
|
41
43
|
return null;
|
|
@@ -4,6 +4,8 @@ import { Focusable } from "@applicaster/zapp-react-native-ui-components/Componen
|
|
|
4
4
|
import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
|
|
5
5
|
import * as R from "ramda";
|
|
6
6
|
import { getXray } from "@applicaster/zapp-react-native-utils/logger";
|
|
7
|
+
import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
8
|
+
import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
|
|
7
9
|
|
|
8
10
|
const { Logger } = getXray();
|
|
9
11
|
|
|
@@ -35,12 +37,19 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
|
|
|
35
37
|
|
|
36
38
|
const focusableId = getFocusableId(prefixId, suffixId);
|
|
37
39
|
|
|
38
|
-
const focused =
|
|
40
|
+
const focused =
|
|
41
|
+
focusableId === focusedButtonId ||
|
|
42
|
+
toBooleanWithDefaultFalse(otherProps.focused);
|
|
39
43
|
|
|
40
44
|
const additionalStyles = focused ? focusedStyles : normalStyles;
|
|
41
45
|
|
|
42
46
|
const actionContext = useActions(pluginIdentifier);
|
|
43
47
|
|
|
48
|
+
const accessibilityManager = useAccessibilityManager({});
|
|
49
|
+
|
|
50
|
+
const { ttsLabel = "" } =
|
|
51
|
+
actionContext?.initialEntryState(item)?.getAccessibility?.(item) || {};
|
|
52
|
+
|
|
44
53
|
const onPress = (event) => {
|
|
45
54
|
event?.preventDefault?.();
|
|
46
55
|
|
|
@@ -85,6 +94,12 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
|
|
|
85
94
|
mouse: focusable.mouse,
|
|
86
95
|
});
|
|
87
96
|
});
|
|
97
|
+
|
|
98
|
+
if (ttsLabel) {
|
|
99
|
+
accessibilityManager.readText({
|
|
100
|
+
text: ttsLabel,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
88
103
|
};
|
|
89
104
|
|
|
90
105
|
const handleBlur = (_focusable, _direction) => {
|