@applicaster/zapp-react-native-ui-components 15.0.0-alpha.3564837831 → 15.0.0-alpha.4043532513
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/Cell/CellWithFocusable.tsx +9 -0
- package/Components/Focusable/FocusableTvOS.tsx +2 -2
- package/Components/FocusableGroup/FocusableTvOS.tsx +4 -27
- package/package.json +5 -5
- package/Components/FocusableGroup/hooks/__tests__/useIsFocusEnabled.test.ts +0 -113
- package/Components/FocusableGroup/hooks/index.ts +0 -1
- package/Components/FocusableGroup/hooks/useIsFocusEnabled.ts +0 -68
- package/Contexts/AboveTabsScreenContext/index.tsx +0 -33
|
@@ -2,6 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
|
|
3
3
|
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
4
4
|
import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
5
|
+
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
5
6
|
|
|
6
7
|
import { useCellState } from "../MasterCell/utils";
|
|
7
8
|
import { FocusableGroup } from "../FocusableGroup";
|
|
@@ -26,6 +27,13 @@ type Props = {
|
|
|
26
27
|
|
|
27
28
|
const addPrefix = (id: string) => `focusable-cell-wrapper-${id}`;
|
|
28
29
|
|
|
30
|
+
const wrapperStyles = {
|
|
31
|
+
flex: platformSelect({
|
|
32
|
+
tvos: 1,
|
|
33
|
+
default: undefined,
|
|
34
|
+
}),
|
|
35
|
+
};
|
|
36
|
+
|
|
29
37
|
export function CellWithFocusable(props: Props) {
|
|
30
38
|
const {
|
|
31
39
|
index,
|
|
@@ -94,6 +102,7 @@ export function CellWithFocusable(props: Props) {
|
|
|
94
102
|
onFocus={onGroupFocus}
|
|
95
103
|
onBlur={onGroupBlur}
|
|
96
104
|
skipFocusManagerRegistration={skipFocusManagerRegistration}
|
|
105
|
+
style={wrapperStyles}
|
|
97
106
|
>
|
|
98
107
|
<CellWrapper style={styles.cellWrapper}>
|
|
99
108
|
<CellRenderer
|
|
@@ -13,7 +13,7 @@ import { findNodeHandle, ViewStyle } from "react-native";
|
|
|
13
13
|
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
14
14
|
|
|
15
15
|
import {
|
|
16
|
-
|
|
16
|
+
emitFocused,
|
|
17
17
|
emitNativeRegistered,
|
|
18
18
|
} from "@applicaster/zapp-react-native-utils/appUtils/focusManagerAux/utils/utils.ios";
|
|
19
19
|
|
|
@@ -91,7 +91,7 @@ export class Focusable extends BaseFocusable<Props> {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
const id: string = nativeEvent.itemID;
|
|
94
|
-
|
|
94
|
+
emitFocused(id);
|
|
95
95
|
|
|
96
96
|
onFocus(nativeEvent);
|
|
97
97
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { compose } from "@applicaster/zapp-react-native-utils/utils";
|
|
3
2
|
import { FocusableGroupNative } from "@applicaster/zapp-react-native-ui-components/Components/NativeFocusables";
|
|
4
3
|
import { BaseFocusable } from "@applicaster/zapp-react-native-ui-components/Components/BaseFocusable";
|
|
5
4
|
import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
|
|
@@ -7,9 +6,6 @@ import { LayoutContext } from "@applicaster/zapp-react-native-tvos-app/Context/L
|
|
|
7
6
|
import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useRoute";
|
|
8
7
|
import { isScreenPlayable } from "@applicaster/zapp-react-native-utils/navigationUtils/itemTypes";
|
|
9
8
|
import { emitNativeRegistered } from "@applicaster/zapp-react-native-utils/appUtils/focusManagerAux/utils/utils.ios";
|
|
10
|
-
import { withAboveTabsScreenContextConsumer } from "@applicaster/zapp-react-native-ui-components/Contexts/AboveTabsScreenContext";
|
|
11
|
-
|
|
12
|
-
import { useIsFocusEnabled } from "./hooks";
|
|
13
9
|
|
|
14
10
|
const { log_verbose } = createLogger({
|
|
15
11
|
subsystem: "General",
|
|
@@ -91,8 +87,8 @@ class FocusableGroupComponent extends BaseFocusable<Props> {
|
|
|
91
87
|
}
|
|
92
88
|
}
|
|
93
89
|
|
|
94
|
-
export const
|
|
95
|
-
return function
|
|
90
|
+
export const withFocusDisabled = (Component) => {
|
|
91
|
+
return function WithFocusDisabled(props) {
|
|
96
92
|
// @ts-ignore
|
|
97
93
|
const { screenFocusBlocked } = React.useContext(LayoutContext.ReactContext);
|
|
98
94
|
|
|
@@ -102,27 +98,8 @@ export const withFocusDisabledHOC = (Component) => {
|
|
|
102
98
|
|
|
103
99
|
const blockScreenFocus = isPlayerPresented === false && screenFocusBlocked;
|
|
104
100
|
|
|
105
|
-
return
|
|
106
|
-
<Component
|
|
107
|
-
{...props}
|
|
108
|
-
isFocusDisabled={blockScreenFocus || props.isFocusDisabled}
|
|
109
|
-
/>
|
|
110
|
-
);
|
|
111
|
-
};
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const withAboveTabsScreenHOC = (Component) => {
|
|
115
|
-
return function WithAboveTabsScreenHOC(props) {
|
|
116
|
-
const { aboveTabsScreen } = props;
|
|
117
|
-
|
|
118
|
-
const isFocusEnabled = useIsFocusEnabled(aboveTabsScreen);
|
|
119
|
-
|
|
120
|
-
return <Component {...props} isFocusDisabled={!isFocusEnabled} />;
|
|
101
|
+
return <Component {...props} isFocusDisabled={blockScreenFocus} />;
|
|
121
102
|
};
|
|
122
103
|
};
|
|
123
104
|
|
|
124
|
-
export const FocusableGroup =
|
|
125
|
-
withAboveTabsScreenContextConsumer,
|
|
126
|
-
withAboveTabsScreenHOC,
|
|
127
|
-
withFocusDisabledHOC
|
|
128
|
-
)(FocusableGroupComponent);
|
|
105
|
+
export const FocusableGroup = withFocusDisabled(FocusableGroupComponent);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-ui-components",
|
|
3
|
-
"version": "15.0.0-alpha.
|
|
3
|
+
"version": "15.0.0-alpha.4043532513",
|
|
4
4
|
"description": "Applicaster Zapp React Native ui components for the Quick Brick App",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@applicaster/applicaster-types": "15.0.0-alpha.
|
|
32
|
-
"@applicaster/zapp-react-native-bridge": "15.0.0-alpha.
|
|
33
|
-
"@applicaster/zapp-react-native-redux": "15.0.0-alpha.
|
|
34
|
-
"@applicaster/zapp-react-native-utils": "15.0.0-alpha.
|
|
31
|
+
"@applicaster/applicaster-types": "15.0.0-alpha.4043532513",
|
|
32
|
+
"@applicaster/zapp-react-native-bridge": "15.0.0-alpha.4043532513",
|
|
33
|
+
"@applicaster/zapp-react-native-redux": "15.0.0-alpha.4043532513",
|
|
34
|
+
"@applicaster/zapp-react-native-utils": "15.0.0-alpha.4043532513",
|
|
35
35
|
"fast-json-stable-stringify": "^2.1.0",
|
|
36
36
|
"promise": "^8.3.0",
|
|
37
37
|
"url": "^0.11.0",
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { act, renderHook } from "@testing-library/react-native";
|
|
2
|
-
|
|
3
|
-
import { useIsFocusEnabled } from "../useIsFocusEnabled";
|
|
4
|
-
|
|
5
|
-
// ----------------- MOCKS -----------------
|
|
6
|
-
jest.mock(
|
|
7
|
-
"@applicaster/zapp-react-native-utils/appUtils/focusManager/index.ios",
|
|
8
|
-
() => ({
|
|
9
|
-
focusManager: {
|
|
10
|
-
isFocusOnMenu: jest.fn(),
|
|
11
|
-
isFocusOnTabsScreen: jest.fn(),
|
|
12
|
-
},
|
|
13
|
-
})
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
jest.mock(
|
|
17
|
-
"@applicaster/zapp-react-native-utils/appUtils/focusManagerAux/utils/utils.ios",
|
|
18
|
-
() => {
|
|
19
|
-
const { Subject } = require("rxjs");
|
|
20
|
-
|
|
21
|
-
return {
|
|
22
|
-
willFocused$: new Subject<void>(),
|
|
23
|
-
didFocused$: new Subject<void>(),
|
|
24
|
-
TabsScreenScreenSelectorContainerRegistry: {
|
|
25
|
-
observable$: new Subject<string>(),
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager/index.ios";
|
|
32
|
-
import {
|
|
33
|
-
willFocused$,
|
|
34
|
-
didFocused$,
|
|
35
|
-
TabsScreenScreenSelectorContainerRegistry,
|
|
36
|
-
} from "@applicaster/zapp-react-native-utils/appUtils/focusManagerAux/utils/utils.ios";
|
|
37
|
-
|
|
38
|
-
// ----------------- TESTS -----------------
|
|
39
|
-
describe("useIsFocusEnabled", () => {
|
|
40
|
-
beforeEach(() => {
|
|
41
|
-
jest.clearAllMocks();
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it("returns true by default", () => {
|
|
45
|
-
const { result } = renderHook(() => useIsFocusEnabled(true));
|
|
46
|
-
|
|
47
|
-
expect(result.current).toBe(true);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("disables focus when focus moves to menu", () => {
|
|
51
|
-
(focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(true);
|
|
52
|
-
|
|
53
|
-
const { result } = renderHook(() => useIsFocusEnabled(true));
|
|
54
|
-
|
|
55
|
-
act(() => {
|
|
56
|
-
willFocused$.next();
|
|
57
|
-
didFocused$.next();
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
expect(result.current).toBe(false);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it("re-enables focus when focus lands on tabs screen", () => {
|
|
64
|
-
(focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(true);
|
|
65
|
-
(focusManager.isFocusOnTabsScreen as jest.Mock).mockReturnValue(true);
|
|
66
|
-
|
|
67
|
-
const { result } = renderHook(() => useIsFocusEnabled(true));
|
|
68
|
-
|
|
69
|
-
// Disable focus first
|
|
70
|
-
act(() => {
|
|
71
|
-
willFocused$.next();
|
|
72
|
-
didFocused$.next();
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
expect(result.current).toBe(false);
|
|
76
|
-
|
|
77
|
-
// Enable focus again
|
|
78
|
-
act(() => {
|
|
79
|
-
didFocused$.next();
|
|
80
|
-
TabsScreenScreenSelectorContainerRegistry.observable$.next("tabs-id");
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
expect(result.current).toBe(true);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it("does nothing when not above tabs screen", () => {
|
|
87
|
-
const { result } = renderHook(() => useIsFocusEnabled(false));
|
|
88
|
-
|
|
89
|
-
act(() => {
|
|
90
|
-
willFocused$.next();
|
|
91
|
-
didFocused$.next();
|
|
92
|
-
TabsScreenScreenSelectorContainerRegistry.observable$.next("id");
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
expect(result.current).toBe(true);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it("cleans up subscriptions on unmount", () => {
|
|
99
|
-
(focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(true);
|
|
100
|
-
|
|
101
|
-
const { unmount, result } = renderHook(() => useIsFocusEnabled(true));
|
|
102
|
-
|
|
103
|
-
unmount();
|
|
104
|
-
|
|
105
|
-
act(() => {
|
|
106
|
-
willFocused$.next();
|
|
107
|
-
didFocused$.next();
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
// State should not change after unmount
|
|
111
|
-
expect(result.current).toBe(true);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { useIsFocusEnabled } from "./useIsFocusEnabled";
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { switchMap, first, filter, repeat } from "rxjs/operators";
|
|
3
|
-
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager/index.ios";
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
willFocused$,
|
|
7
|
-
didFocused$,
|
|
8
|
-
TabsScreenScreenSelectorContainerRegistry,
|
|
9
|
-
} from "@applicaster/zapp-react-native-utils/appUtils/focusManagerAux/utils/utils.ios";
|
|
10
|
-
|
|
11
|
-
export const useIsFocusEnabled = (isAboveTabsScreen: boolean): boolean => {
|
|
12
|
-
const [isFocusEnabled, setIsFocusedEnabled] = React.useState(true);
|
|
13
|
-
|
|
14
|
-
const enableFocus = React.useCallback(() => {
|
|
15
|
-
setIsFocusedEnabled(true);
|
|
16
|
-
}, []);
|
|
17
|
-
|
|
18
|
-
const disableFocus = React.useCallback(() => {
|
|
19
|
-
setIsFocusedEnabled(false);
|
|
20
|
-
}, []);
|
|
21
|
-
|
|
22
|
-
React.useEffect(() => {
|
|
23
|
-
const subscription = didFocused$
|
|
24
|
-
.pipe(
|
|
25
|
-
filter(() => isAboveTabsScreen && !isFocusEnabled),
|
|
26
|
-
|
|
27
|
-
switchMap(() => TabsScreenScreenSelectorContainerRegistry.observable$),
|
|
28
|
-
filter((id) => id && focusManager.isFocusOnTabsScreen(id)),
|
|
29
|
-
|
|
30
|
-
// run only once, then re-subscribe on didFocused$ again
|
|
31
|
-
first(),
|
|
32
|
-
repeat()
|
|
33
|
-
)
|
|
34
|
-
.subscribe(() => {
|
|
35
|
-
enableFocus();
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
return () => {
|
|
39
|
-
subscription.unsubscribe();
|
|
40
|
-
};
|
|
41
|
-
}, [enableFocus, isFocusEnabled, isAboveTabsScreen]);
|
|
42
|
-
|
|
43
|
-
React.useEffect(() => {
|
|
44
|
-
const subscription = willFocused$
|
|
45
|
-
.pipe(
|
|
46
|
-
filter(() => isAboveTabsScreen && isFocusEnabled),
|
|
47
|
-
|
|
48
|
-
// start waiting onFocus event
|
|
49
|
-
switchMap(() => didFocused$),
|
|
50
|
-
|
|
51
|
-
// focus is landed on top-menu
|
|
52
|
-
filter(() => focusManager.isFocusOnMenu()),
|
|
53
|
-
|
|
54
|
-
// run only once, then re-subscribe on willFocused$ again
|
|
55
|
-
first(),
|
|
56
|
-
repeat()
|
|
57
|
-
)
|
|
58
|
-
.subscribe(() => {
|
|
59
|
-
disableFocus();
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
return () => {
|
|
63
|
-
subscription.unsubscribe();
|
|
64
|
-
};
|
|
65
|
-
}, [disableFocus, isFocusEnabled, isAboveTabsScreen]);
|
|
66
|
-
|
|
67
|
-
return isFocusEnabled;
|
|
68
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import React, { useMemo } from "react";
|
|
2
|
-
import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
3
|
-
|
|
4
|
-
export const AboveTabsScreenContext = React.createContext({
|
|
5
|
-
aboveTabsScreen: false,
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
export const withAboveTabsScreenContext = (Component) =>
|
|
9
|
-
function AbovetabsScreenContextProviderWrapper(props) {
|
|
10
|
-
const aboveTabsScreen = toBooleanWithDefaultFalse(
|
|
11
|
-
props?.item?.above_tabs_screen
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
const contextValue = useMemo(
|
|
15
|
-
() => ({
|
|
16
|
-
aboveTabsScreen,
|
|
17
|
-
}),
|
|
18
|
-
[aboveTabsScreen]
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<AboveTabsScreenContext.Provider value={contextValue}>
|
|
23
|
-
<Component {...props} />
|
|
24
|
-
</AboveTabsScreenContext.Provider>
|
|
25
|
-
);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export const withAboveTabsScreenContextConsumer = (Component) =>
|
|
29
|
-
function AboveTabsScreenContextConsumerWrapper(props) {
|
|
30
|
-
const { aboveTabsScreen } = React.useContext(AboveTabsScreenContext);
|
|
31
|
-
|
|
32
|
-
return <Component {...props} aboveTabsScreen={aboveTabsScreen} />;
|
|
33
|
-
};
|