@applicaster/zapp-react-native-ui-components 16.0.0-alpha.7501599877 → 16.0.0-alpha.7845362739
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/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +47 -21
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +34 -6
- package/Components/MasterCell/DefaultComponents/Image/hoc/utils/__tests__/withDimensions.test.ts +420 -125
- package/Components/MasterCell/DefaultComponents/Image/hoc/utils/index.ts +114 -19
- package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +19 -8
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +5 -3
- package/Components/MasterCell/DefaultComponents/PressableView.tsx +29 -9
- package/Components/MasterCell/DefaultComponents/Text/hooks/useText.ts +4 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ActionButton.tsx +154 -100
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/AssetComponent.tsx +15 -4
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +56 -22
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Spacer.ts +6 -4
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +3 -1
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +32 -21
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/index.test.ts +15 -4
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +23 -16
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +8 -3
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +2 -2
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/insertButtonsBetweenLabels.test.ts +45 -13
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +2 -2
- package/Components/MasterCell/contexts/PressedStateContext.ts +3 -0
- package/Components/MasterCell/hooks/index.ts +2 -0
- package/Components/MasterCell/hooks/usePressedState.ts +4 -0
- package/Components/ModalComponent/AudioPlayer/Components/Action.tsx +332 -0
- package/Components/ModalComponent/AudioPlayer/Components/Button.tsx +402 -0
- package/Components/ModalComponent/AudioPlayer/Components/Header.tsx +811 -0
- package/Components/ModalComponent/AudioPlayer/Components/Input.tsx +671 -0
- package/Components/ModalComponent/AudioPlayer/Components/Item.tsx +878 -0
- package/Components/ModalComponent/AudioPlayer/Components/index.ts +9 -0
- package/Components/ModalComponent/BottomSheetDragArea.tsx +33 -0
- package/Components/ModalComponent/BottomSheetModalContent.tsx +49 -26
- package/Components/ModalComponent/__tests__/BottomSheetDragArea.test.tsx +74 -0
- package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +4 -85
- package/Components/OfflineHandler/__tests__/index.test.tsx +78 -18
- package/Components/OfflineHandler/hooks.ts +123 -0
- package/Components/OfflineHandler/index.tsx +51 -73
- package/Components/OfflineHandler/utils/index.ts +1 -13
- package/Components/PreloaderWrapper/index.tsx +1 -1
- package/Components/ScreenFeedLoader/ScreenFeedLoader.tsx +5 -3
- package/Components/ScreenResolverFeedProvider/ScreenResolverFeedProvider.tsx +1 -1
- package/Components/TopCutoffOverlay/index.tsx +2 -2
- package/Components/Transitioner/Transitioner.tsx +28 -17
- package/package.json +5 -5
- package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +0 -112
- package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +0 -107
- package/Components/OfflineHandler/NotificationView/NotificationView.tsx +0 -153
- package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -66
- package/Components/OfflineHandler/NotificationView/utils.ts +0 -34
|
@@ -1,105 +1,83 @@
|
|
|
1
|
-
import React, { useCallback, useEffect
|
|
2
|
-
import { View, StyleSheet } from "react-native";
|
|
3
|
-
import { NotificationView as NotificationViewNative } from "./NotificationView/NotificationView";
|
|
4
|
-
import { NotificationView as NotificationViewSamsung } from "./NotificationView/NotificationView.samsung";
|
|
5
|
-
import { NotificationView as NotificationViewLG } from "./NotificationView/NotificationView.lg";
|
|
6
|
-
|
|
1
|
+
import React, { useCallback, useEffect } from "react";
|
|
7
2
|
import { useConnectionInfo } from "@applicaster/zapp-react-native-utils/reactHooks/connection";
|
|
8
3
|
import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
|
|
9
|
-
import {
|
|
4
|
+
import { useSubscriberFor } from "@applicaster/zapp-react-native-utils/reactHooks/useSubscriberFor";
|
|
10
5
|
|
|
6
|
+
import { useOfflineHandlerProps } from "./hooks";
|
|
11
7
|
import { componentsLogger } from "../../Helpers/logger";
|
|
12
8
|
import { parseConnectionInfo } from "./utils";
|
|
13
9
|
|
|
14
10
|
const logger = componentsLogger.addSubsystem("OfflineHandler");
|
|
15
11
|
|
|
12
|
+
// mirrors NOTIFICATION_TOAST_EVENTS.SHOW_TOAST in
|
|
13
|
+
// @applicaster/quick-brick-core/App/NotificationToastRenderer/NotificationToastManager
|
|
14
|
+
// (kept as a literal here since this package must not depend on quick-brick-core)
|
|
15
|
+
const SHOW_TOAST_EVENT = "showToast";
|
|
16
|
+
const OFFLINE_STATUS_TOAST_ID = "offline-status";
|
|
17
|
+
|
|
16
18
|
type Props = {
|
|
17
19
|
children?: React.ReactElement<any>;
|
|
18
20
|
};
|
|
19
21
|
|
|
20
|
-
const styles = StyleSheet.create({
|
|
21
|
-
container: {
|
|
22
|
-
flex: 1,
|
|
23
|
-
position: "relative",
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
|
|
27
22
|
const timers = {
|
|
28
23
|
goingOffline: 5000,
|
|
29
24
|
goingOnline: 2000,
|
|
30
25
|
};
|
|
31
26
|
|
|
32
|
-
export const NotificationView = platformSelect({
|
|
33
|
-
samsung_tv: NotificationViewSamsung,
|
|
34
|
-
lg_tv: NotificationViewLG,
|
|
35
|
-
default: NotificationViewNative,
|
|
36
|
-
});
|
|
37
|
-
|
|
38
27
|
export const OfflineHandler = ({ children }: Props) => {
|
|
39
28
|
const connectionInfo = useConnectionInfo(false);
|
|
40
|
-
const { online
|
|
29
|
+
const { online } = parseConnectionInfo(connectionInfo);
|
|
30
|
+
const prevOnline = usePrevious(online);
|
|
41
31
|
|
|
42
|
-
const
|
|
43
|
-
const previousOnline: boolean = usePrevious(online);
|
|
44
|
-
const timer = useRef<NodeJS.Timeout | null>(null);
|
|
45
|
-
const initialRender = useRef(false);
|
|
32
|
+
const emitShowToast = useSubscriberFor(SHOW_TOAST_EVENT);
|
|
46
33
|
|
|
47
|
-
const
|
|
48
|
-
setHidden(true);
|
|
34
|
+
const { message, extraMessage, style } = useOfflineHandlerProps(online);
|
|
49
35
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
timer.current = null;
|
|
53
|
-
}
|
|
54
|
-
}, []);
|
|
36
|
+
const showOnlineToast = useCallback(() => {
|
|
37
|
+
logger.log("Device is back online, emit toast");
|
|
55
38
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
39
|
+
emitShowToast({
|
|
40
|
+
id: OFFLINE_STATUS_TOAST_ID,
|
|
41
|
+
message,
|
|
42
|
+
extraMessage,
|
|
43
|
+
style,
|
|
44
|
+
timeout: timers.goingOnline,
|
|
45
|
+
});
|
|
46
|
+
}, [emitShowToast, message, extraMessage, style]);
|
|
47
|
+
|
|
48
|
+
const showOfflineToast = useCallback(() => {
|
|
49
|
+
logger.log("Device went offline, emit toast");
|
|
60
50
|
|
|
61
|
-
|
|
62
|
-
|
|
51
|
+
emitShowToast({
|
|
52
|
+
id: OFFLINE_STATUS_TOAST_ID,
|
|
53
|
+
message,
|
|
54
|
+
extraMessage,
|
|
55
|
+
style,
|
|
56
|
+
timeout: timers.goingOffline,
|
|
57
|
+
});
|
|
58
|
+
}, [emitShowToast, message, extraMessage, style]);
|
|
63
59
|
|
|
64
60
|
useEffect(() => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
logger.log("Device went offline");
|
|
72
|
-
setTimer(() => setHidden(true), timers.goingOffline);
|
|
73
|
-
setHidden(false);
|
|
61
|
+
// On mount there is no previous state yet: only surface the offline toast
|
|
62
|
+
// for a device that starts offline. Don't announce "back online" for a
|
|
63
|
+
// device that was online to begin with.
|
|
64
|
+
if (prevOnline === undefined) {
|
|
65
|
+
if (!online) {
|
|
66
|
+
showOfflineToast();
|
|
74
67
|
}
|
|
75
68
|
|
|
76
|
-
|
|
77
|
-
logger.log("Device is back online");
|
|
78
|
-
setHidden(false);
|
|
79
|
-
setTimer(() => setHidden(true), timers.goingOnline);
|
|
80
|
-
}
|
|
81
|
-
} else {
|
|
82
|
-
initialRender.current = true;
|
|
69
|
+
return;
|
|
83
70
|
}
|
|
84
71
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
72
|
+
// On subsequent renders, only emit a toast when the online/offline state changes.
|
|
73
|
+
if (prevOnline !== online) {
|
|
74
|
+
if (!online) {
|
|
75
|
+
showOfflineToast();
|
|
76
|
+
} else {
|
|
77
|
+
showOnlineToast();
|
|
89
78
|
}
|
|
90
|
-
}
|
|
91
|
-
}, [
|
|
92
|
-
|
|
93
|
-
return
|
|
94
|
-
<View style={styles.container}>
|
|
95
|
-
<NotificationView
|
|
96
|
-
hidden={hidden}
|
|
97
|
-
online={online}
|
|
98
|
-
previousOnline={previousOnline}
|
|
99
|
-
dismiss={dismiss}
|
|
100
|
-
>
|
|
101
|
-
{children}
|
|
102
|
-
</NotificationView>
|
|
103
|
-
</View>
|
|
104
|
-
);
|
|
79
|
+
}
|
|
80
|
+
}, [online, prevOnline, showOfflineToast, showOnlineToast]);
|
|
81
|
+
|
|
82
|
+
return children;
|
|
105
83
|
};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
|
-
|
|
3
2
|
import { NetInfoState } from "@react-native-community/netinfo";
|
|
4
3
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
5
4
|
import { isOnline as isOnlineUtils } from "@applicaster/quick-brick-core/App/NetworkStatusProvider/utils";
|
|
6
|
-
|
|
5
|
+
|
|
7
6
|
import { Platform } from "react-native";
|
|
8
7
|
|
|
9
8
|
type ConnectionInfo = NetInfoState & { deviceStatus: NetStatus };
|
|
@@ -51,14 +50,3 @@ export const parseConnectionInfo: typeof parseConnectionInfoForDefault =
|
|
|
51
50
|
samsung_tv: parseConnectionInfoForSamsung,
|
|
52
51
|
default: parseConnectionInfoForDefault,
|
|
53
52
|
});
|
|
54
|
-
|
|
55
|
-
export const useNotificationHeight = () => {
|
|
56
|
-
const insets = useSafeAreaInsets();
|
|
57
|
-
|
|
58
|
-
const navBarHeight = platformSelect({ ios: 44, android: 56 });
|
|
59
|
-
|
|
60
|
-
const statusHeight = insets.top;
|
|
61
|
-
const notificationHeight = statusHeight + navBarHeight;
|
|
62
|
-
|
|
63
|
-
return { statusHeight, notificationHeight };
|
|
64
|
-
};
|
|
@@ -8,9 +8,11 @@ import { componentsLogger } from "../../Helpers/logger";
|
|
|
8
8
|
const logger = componentsLogger.addSubsystem("ScreenFeedLoader");
|
|
9
9
|
|
|
10
10
|
/** Loads and provides `feedData` and store to */
|
|
11
|
-
export const ScreenFeedLoader: React.FC<
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
export const ScreenFeedLoader: React.FC<{
|
|
12
|
+
id: string;
|
|
13
|
+
feedData: any;
|
|
14
|
+
children: React.ReactElement | null;
|
|
15
|
+
}> = ({ id, feedData, children }) => {
|
|
14
16
|
const { source: feedUrl, mapping } = feedData;
|
|
15
17
|
|
|
16
18
|
const { data, loading, error } = useFeedLoader({
|
|
@@ -7,7 +7,7 @@ import { useMarginTop } from "./hooks";
|
|
|
7
7
|
|
|
8
8
|
interface IProps {
|
|
9
9
|
targetScreenId?: string;
|
|
10
|
-
children
|
|
10
|
+
children: React.ReactElement | null;
|
|
11
11
|
applyTopCutoff?: boolean;
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -21,7 +21,7 @@ export const TopCutoffOverlay: React.FC<IProps> = ({
|
|
|
21
21
|
targetScreenId,
|
|
22
22
|
children,
|
|
23
23
|
applyTopCutoff = true,
|
|
24
|
-
}
|
|
24
|
+
}) => {
|
|
25
25
|
const cutoffHeight = useMarginTop(targetScreenId);
|
|
26
26
|
|
|
27
27
|
const { backgroundColor: screenBackgroundColor } =
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import { append, compose, identity,
|
|
3
|
+
import { append, compose, identity, tail, take, update } from "ramda";
|
|
4
4
|
|
|
5
5
|
import { AnimationManager } from "./AnimationManager";
|
|
6
6
|
import { Scene } from "./Scene";
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
shouldSkipAnimationForPreviousWebViewScene,
|
|
11
11
|
} from "./utils";
|
|
12
12
|
import { v4 as uuid_v4 } from "uuid";
|
|
13
|
+
import { isScreenActiveForRoute } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useIsScreenActive";
|
|
13
14
|
|
|
14
15
|
export const NAV_ACTION_PUSH = "PUSH";
|
|
15
16
|
|
|
@@ -50,16 +51,16 @@ function scenesForBackTransition(props: SceneProps, { scenes }) {
|
|
|
50
51
|
: [prepareScene(props.children), scenes[0]];
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
const isModalClosed = (navigator) => {
|
|
54
|
-
return !!isNil(navigator?.modalData);
|
|
55
|
-
};
|
|
56
|
-
|
|
57
54
|
type Props = {
|
|
58
55
|
transitionConfig: any;
|
|
59
56
|
children: React.ReactNode;
|
|
60
57
|
navigator: {
|
|
61
58
|
previousAction: string;
|
|
62
59
|
currentRoute: string;
|
|
60
|
+
videoModalState?: {
|
|
61
|
+
visible?: boolean;
|
|
62
|
+
mode?: string;
|
|
63
|
+
};
|
|
63
64
|
screenData: {
|
|
64
65
|
[key: string]: any;
|
|
65
66
|
};
|
|
@@ -283,8 +284,10 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
283
284
|
// so only a single scene should be rendered,
|
|
284
285
|
// instead of dangerous nulls or duplicates.
|
|
285
286
|
renderSingleScene({ scenes, to }) {
|
|
286
|
-
const { contentStyle } = this.props;
|
|
287
|
-
|
|
287
|
+
const { contentStyle, navigator, children } = this.props;
|
|
288
|
+
|
|
289
|
+
const { currentRoute, videoModalState } = navigator;
|
|
290
|
+
const screenData = children.props.screenData;
|
|
288
291
|
const pathname = scenes[to.index].key;
|
|
289
292
|
|
|
290
293
|
return (
|
|
@@ -293,7 +296,11 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
293
296
|
<Scene
|
|
294
297
|
{...{ style: to?.style || {} }}
|
|
295
298
|
pathname={pathname}
|
|
296
|
-
isActive={
|
|
299
|
+
isActive={isScreenActiveForRoute(
|
|
300
|
+
pathname,
|
|
301
|
+
currentRoute,
|
|
302
|
+
videoModalState
|
|
303
|
+
)}
|
|
297
304
|
contentStyle={contentStyle}
|
|
298
305
|
key={scenes[to.index].key}
|
|
299
306
|
screenUniqueId={scenes[to.index].screenUniqueId}
|
|
@@ -311,16 +318,19 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
311
318
|
// Looks redundant, but when written like this
|
|
312
319
|
// we do not need to pass or generate keys.
|
|
313
320
|
renderScenes({ scenes, from, to }) {
|
|
314
|
-
const { contentStyle } = this.props;
|
|
321
|
+
const { contentStyle, navigator } = this.props;
|
|
322
|
+
|
|
323
|
+
const { currentRoute, videoModalState } = navigator;
|
|
315
324
|
|
|
316
325
|
const fromScene = scenes[from.index] && (
|
|
317
326
|
<Scene
|
|
318
327
|
key={scenes[from.index].key}
|
|
319
328
|
pathname={scenes[from.index].key}
|
|
320
|
-
isActive={
|
|
321
|
-
scenes[from.index].key
|
|
322
|
-
|
|
323
|
-
|
|
329
|
+
isActive={isScreenActiveForRoute(
|
|
330
|
+
scenes[from.index].key,
|
|
331
|
+
currentRoute,
|
|
332
|
+
videoModalState
|
|
333
|
+
)}
|
|
324
334
|
style={from.style}
|
|
325
335
|
pointerEvents="none"
|
|
326
336
|
overlayStyle={from.overlayStyle}
|
|
@@ -336,10 +346,11 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
336
346
|
const toScene = scenes[to.index] && (
|
|
337
347
|
<Scene
|
|
338
348
|
pathname={scenes[to.index].key}
|
|
339
|
-
isActive={
|
|
340
|
-
scenes[to.index].key
|
|
341
|
-
|
|
342
|
-
|
|
349
|
+
isActive={isScreenActiveForRoute(
|
|
350
|
+
scenes[to.index].key,
|
|
351
|
+
currentRoute,
|
|
352
|
+
videoModalState
|
|
353
|
+
)}
|
|
343
354
|
key={scenes[to.index].key}
|
|
344
355
|
style={to.style}
|
|
345
356
|
overlayStyle={to.overlayStyle}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-ui-components",
|
|
3
|
-
"version": "16.0.0-alpha.
|
|
3
|
+
"version": "16.0.0-alpha.7845362739",
|
|
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": "16.0.0-alpha.
|
|
32
|
-
"@applicaster/zapp-react-native-bridge": "16.0.0-alpha.
|
|
33
|
-
"@applicaster/zapp-react-native-redux": "16.0.0-alpha.
|
|
34
|
-
"@applicaster/zapp-react-native-utils": "16.0.0-alpha.
|
|
31
|
+
"@applicaster/applicaster-types": "16.0.0-alpha.7845362739",
|
|
32
|
+
"@applicaster/zapp-react-native-bridge": "16.0.0-alpha.7845362739",
|
|
33
|
+
"@applicaster/zapp-react-native-redux": "16.0.0-alpha.7845362739",
|
|
34
|
+
"@applicaster/zapp-react-native-utils": "16.0.0-alpha.7845362739",
|
|
35
35
|
"fast-json-stable-stringify": "^2.1.0",
|
|
36
36
|
"promise": "^8.3.0",
|
|
37
37
|
"url": "^0.11.0",
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
3
|
-
import { useNetworkStatusLocalizations } from "./utils";
|
|
4
|
-
|
|
5
|
-
type Props = {
|
|
6
|
-
children?: React.ReactNode;
|
|
7
|
-
hidden?: boolean;
|
|
8
|
-
online?: boolean;
|
|
9
|
-
previousOnline?: boolean;
|
|
10
|
-
dismiss: () => void;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const NOTIF_DURATION = 4500;
|
|
14
|
-
|
|
15
|
-
const styles: Record<any, React.CSSProperties> = {
|
|
16
|
-
body: {
|
|
17
|
-
position: "absolute",
|
|
18
|
-
bottom: 0,
|
|
19
|
-
width: 1920,
|
|
20
|
-
height: 200,
|
|
21
|
-
background:
|
|
22
|
-
"linear-gradient(180deg, rgba(17,17,17,0.9) 0%, rgba(17,17,17,1) 49%, rgba(0,0,0,0.85) 100%)",
|
|
23
|
-
display: "flex",
|
|
24
|
-
alignItems: "center",
|
|
25
|
-
justifyContent: "center",
|
|
26
|
-
flexDirection: "column",
|
|
27
|
-
color: "#fff",
|
|
28
|
-
paddingBottom: 15,
|
|
29
|
-
},
|
|
30
|
-
title: {
|
|
31
|
-
fontSize: 28,
|
|
32
|
-
margin: 0,
|
|
33
|
-
padding: 0,
|
|
34
|
-
},
|
|
35
|
-
subtitle: {
|
|
36
|
-
fontSize: 20,
|
|
37
|
-
margin: 0,
|
|
38
|
-
padding: 0,
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export const NotificationView = (props: Props) => {
|
|
43
|
-
const { children, hidden, dismiss, previousOnline, online } = props;
|
|
44
|
-
|
|
45
|
-
const theme = useTheme<BaseThemePropertiesTV>();
|
|
46
|
-
const storedLocalizations = useNetworkStatusLocalizations();
|
|
47
|
-
|
|
48
|
-
const [open, setOpen] = React.useState<boolean | null>(null);
|
|
49
|
-
|
|
50
|
-
const timeout = React.useRef<NodeJS.Timeout>();
|
|
51
|
-
const wentOnline = !previousOnline && props.online;
|
|
52
|
-
|
|
53
|
-
const onClose = () => {
|
|
54
|
-
setOpen(false);
|
|
55
|
-
dismiss();
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const closeNotification = () => {
|
|
59
|
-
clearTimeout(timeout.current as NodeJS.Timeout);
|
|
60
|
-
|
|
61
|
-
timeout.current = setTimeout(() => {
|
|
62
|
-
setOpen(false);
|
|
63
|
-
}, NOTIF_DURATION);
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const openNotification = () => {
|
|
67
|
-
if (!open && !hidden) {
|
|
68
|
-
setOpen(true);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const handleNotificationChange = () => {
|
|
73
|
-
if (open !== null) {
|
|
74
|
-
openNotification();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
closeNotification();
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
React.useEffect(() => {
|
|
81
|
-
handleNotificationChange();
|
|
82
|
-
}, [hidden, online]);
|
|
83
|
-
|
|
84
|
-
const showOnlineMsg = wentOnline || online;
|
|
85
|
-
|
|
86
|
-
const MSG = showOnlineMsg
|
|
87
|
-
? (theme?.online_notification_title ??
|
|
88
|
-
storedLocalizations?.online_notification_title)
|
|
89
|
-
: (theme?.offline_notification_title ??
|
|
90
|
-
storedLocalizations?.offline_notification_title);
|
|
91
|
-
|
|
92
|
-
const EXTRA_MSG = showOnlineMsg
|
|
93
|
-
? (theme?.online_notification_subtitle ??
|
|
94
|
-
storedLocalizations?.online_notification_subtitle)
|
|
95
|
-
: (theme?.offline_notification_subtitle ??
|
|
96
|
-
storedLocalizations?.offline_notification_subtitle);
|
|
97
|
-
|
|
98
|
-
return (
|
|
99
|
-
<div onClick={onClose}>
|
|
100
|
-
{children}
|
|
101
|
-
{open ? (
|
|
102
|
-
<div style={styles.body}>
|
|
103
|
-
<div style={styles.title}>
|
|
104
|
-
<h2>{MSG}</h2>
|
|
105
|
-
</div>
|
|
106
|
-
|
|
107
|
-
<h4 style={styles.subtitle}>{EXTRA_MSG}</h4>
|
|
108
|
-
</div>
|
|
109
|
-
) : null}
|
|
110
|
-
</div>
|
|
111
|
-
);
|
|
112
|
-
};
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
3
|
-
import { useNetworkStatusLocalizations } from "./utils";
|
|
4
|
-
|
|
5
|
-
type Props = {
|
|
6
|
-
children?: React.ReactNode;
|
|
7
|
-
online?: boolean;
|
|
8
|
-
previousOnline?: boolean;
|
|
9
|
-
dismiss: () => void;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const DURATION_TO_HIDE_AFTER_BACK_TO_ONLINE = 4500; // ms
|
|
13
|
-
|
|
14
|
-
const styles: Record<any, React.CSSProperties> = {
|
|
15
|
-
body: {
|
|
16
|
-
position: "absolute",
|
|
17
|
-
top: 0,
|
|
18
|
-
width: 1920,
|
|
19
|
-
height: 200,
|
|
20
|
-
background:
|
|
21
|
-
"linear-gradient(180deg, rgba(17,17,17,0.9) 0%, rgba(17,17,17,1) 49%, rgba(0,0,0,0.85) 100%)",
|
|
22
|
-
display: "flex",
|
|
23
|
-
alignItems: "center",
|
|
24
|
-
justifyContent: "center",
|
|
25
|
-
flexDirection: "column",
|
|
26
|
-
color: "#fff",
|
|
27
|
-
paddingTop: 15,
|
|
28
|
-
},
|
|
29
|
-
title: {
|
|
30
|
-
fontSize: 28,
|
|
31
|
-
margin: 0,
|
|
32
|
-
padding: 0,
|
|
33
|
-
},
|
|
34
|
-
subtitle: {
|
|
35
|
-
fontSize: 20,
|
|
36
|
-
margin: 0,
|
|
37
|
-
padding: 0,
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
let timer: NodeJS.Timeout;
|
|
42
|
-
|
|
43
|
-
export const NotificationView = (props: Props) => {
|
|
44
|
-
const { children, dismiss, previousOnline = true, online } = props;
|
|
45
|
-
|
|
46
|
-
const theme = useTheme<BaseThemePropertiesTV>();
|
|
47
|
-
const storedLocalizations = useNetworkStatusLocalizations();
|
|
48
|
-
|
|
49
|
-
const [shown, setShown] = React.useState<boolean>(false);
|
|
50
|
-
|
|
51
|
-
const onClose = () => {
|
|
52
|
-
setShown(false);
|
|
53
|
-
dismiss();
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
React.useEffect(() => {
|
|
57
|
-
if (previousOnline && online) {
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (!previousOnline && !online) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (previousOnline && !online) {
|
|
66
|
-
// went to offline
|
|
67
|
-
clearTimeout(timer);
|
|
68
|
-
setShown(true);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (!previousOnline && online) {
|
|
72
|
-
// back to online
|
|
73
|
-
setShown(true);
|
|
74
|
-
|
|
75
|
-
timer = setTimeout(() => {
|
|
76
|
-
setShown(false);
|
|
77
|
-
}, DURATION_TO_HIDE_AFTER_BACK_TO_ONLINE);
|
|
78
|
-
}
|
|
79
|
-
}, [online, previousOnline]);
|
|
80
|
-
|
|
81
|
-
const title = online
|
|
82
|
-
? (theme?.online_notification_title ??
|
|
83
|
-
storedLocalizations?.online_notification_title)
|
|
84
|
-
: (theme?.offline_notification_title ??
|
|
85
|
-
storedLocalizations?.offline_notification_title);
|
|
86
|
-
|
|
87
|
-
const subtitle = online
|
|
88
|
-
? (theme?.online_notification_subtitle ??
|
|
89
|
-
storedLocalizations?.online_notification_subtitle)
|
|
90
|
-
: (theme?.offline_notification_subtitle ??
|
|
91
|
-
storedLocalizations?.offline_notification_subtitle);
|
|
92
|
-
|
|
93
|
-
return (
|
|
94
|
-
<div onClick={onClose}>
|
|
95
|
-
{children}
|
|
96
|
-
{shown ? (
|
|
97
|
-
<div style={styles.body}>
|
|
98
|
-
<div style={styles.title}>
|
|
99
|
-
<h2>{title}</h2>
|
|
100
|
-
</div>
|
|
101
|
-
|
|
102
|
-
<h4 style={styles.subtitle}>{subtitle}</h4>
|
|
103
|
-
</div>
|
|
104
|
-
) : null}
|
|
105
|
-
</div>
|
|
106
|
-
);
|
|
107
|
-
};
|