Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions ts/features/ingress/__test__/IngressScreen.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ describe(IngressScreen, () => {
jest.clearAllMocks();
});
it("Should update LoadingScreenContent contentTitle after 5 sec and display the cdn unreachable blocking screen after 10", async () => {
jest
.spyOn(itwSelectors, "itwOfflineAccessAvailableSelector")
.mockImplementation(() => false);

const {
getDeviceBlockingScreen,
queryByText,
Expand All @@ -116,6 +120,9 @@ describe(IngressScreen, () => {
jest
.spyOn(backendStatusSelectors, "isBackendStatusLoadedSelector")
.mockImplementation(() => true);
jest
.spyOn(itwSelectors, "itwOfflineAccessAvailableSelector")
.mockImplementation(() => false);

const {
getDeviceBlockingScreen,
Expand All @@ -138,6 +145,22 @@ describe(IngressScreen, () => {
expect(getFirstText()).toBeNull();
expect(getSecondText()).toBeNull();
});
it("Should not display the slowdowns blocking screen if offline wallet is available", async () => {
jest
.spyOn(backendStatusSelectors, "isBackendStatusLoadedSelector")
.mockImplementation(() => true);
jest
.spyOn(itwSelectors, "itwOfflineAccessAvailableSelector")
.mockImplementation(() => true);

const { getDeviceBlockingScreen } = await renderComponentWithSlowdowns();

await act(() => {
jest.advanceTimersByTime(5000);
});

expect(getDeviceBlockingScreen()).toBeFalsy();
});
});
});

Expand Down
65 changes: 33 additions & 32 deletions ts/features/ingress/screens/IngressScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/* eslint-disable functional/immutable-data */
/**
* An ingress screen to choose the real first screen the user must navigate to.
*/
import { memo, useEffect, useRef, useState } from "react";
import { memo, useCallback, useEffect, useRef, useState } from "react";
import { Millisecond } from "@pagopa/ts-commons/lib/units";
import { AccessibilityInfo, View } from "react-native";
import I18n from "../../../i18n";
Expand Down Expand Up @@ -44,6 +43,22 @@ export const IngressScreen = () => {
const [showBlockingScreen, setShowBlockingScreen] = useState(false);
const [contentTitle, setContentTitle] = useState(I18n.t("startup.title"));

const showOfflineWallet = useCallback(() => {
// This dispatch could be placed inside `onSuccess`,
// but executing it here ensures the startup saga stops immediately.
dispatch(setOfflineAccessReason(OfflineAccessReasonEnum.DEVICE_OFFLINE));
dispatch(
identificationRequest(false, false, undefined, undefined, {
onSuccess: () => {
// This dispatch mounts the new offline navigator.
// It must be initialized **after** the user completes
// biometric authentication to prevent graphical glitches.
dispatch(startupLoadSuccess(StartupStatusEnum.OFFLINE));
}
})
);
}, [dispatch]);

useEffect(() => {
// Since the screen is shown for a very short time,
// we prefer to announce the content to the screen reader,
Expand All @@ -61,48 +76,34 @@ export const IngressScreen = () => {
}, [isMixpanelInitialized, isMixpanelEnabled]);

useEffect(() => {
const timeouts: Array<number> = [];

timeouts.push(
setTimeout(() => {
setContentTitle(I18n.t("startup.title2"));
timeouts.shift();
}, TIMEOUT_CHANGE_LABEL)
);

timeouts.push(
setTimeout(() => {
const timeoutChangeLabel = setTimeout(() => {
setContentTitle(I18n.t("startup.title2"));
}, TIMEOUT_CHANGE_LABEL);

const timeoutBlockingScreen = setTimeout(() => {
if (isOfflineAccessAvailable) {
// Avoid to show the blocking screen if offline access is available
showOfflineWallet();
} else {
setShowBlockingScreen(true);
dispatch(setIsBlockingScreen());
timeouts.shift();
}, TIMEOUT_BLOCKING_SCREEN)
);
}
}, TIMEOUT_BLOCKING_SCREEN);

return () => {
timeouts?.forEach(clearTimeout);
clearTimeout(timeoutChangeLabel);
clearTimeout(timeoutBlockingScreen);
};
}, [dispatch]);
}, [dispatch, showOfflineWallet, isOfflineAccessAvailable]);

useEffect(() => {
const visualizeOfflineWallet =
isConnected === false && isOfflineAccessAvailable;

if (visualizeOfflineWallet) {
// This dispatch could be placed inside `onSuccess`,
// but executing it here ensures the startup saga stops immediately.
dispatch(setOfflineAccessReason(OfflineAccessReasonEnum.DEVICE_OFFLINE));
dispatch(
identificationRequest(false, false, undefined, undefined, {
onSuccess: () => {
// This dispatch mounts the new offline navigator.
// It must be initialized **after** the user completes
// biometric authentication to prevent graphical glitches.
dispatch(startupLoadSuccess(StartupStatusEnum.OFFLINE));
}
})
);
showOfflineWallet();
}
}, [dispatch, isConnected, isOfflineAccessAvailable]);
}, [dispatch, isConnected, isOfflineAccessAvailable, showOfflineWallet]);

if (isConnected === false && !isOfflineAccessAvailable) {
return <IngressScreenNoInternetConnection />;
Expand Down
Loading