TP-67100 | Fetch Bundle Immediately (#10937)
This commit is contained in:
73
App.tsx
73
App.tsx
@@ -1,7 +1,7 @@
|
||||
import { init } from "@sentry/react-native";
|
||||
import { Component } from "react";
|
||||
import codePush from "react-native-code-push";
|
||||
import { SentryConstants } from "./App/common/constants/SentryConstants";
|
||||
import { BundleState, SentryConstants } from "./App/common/constants";
|
||||
import { logToSentry } from "./App/common/hooks/useSentryLogging";
|
||||
import { CtaData } from "./App/common/interface";
|
||||
import RnApp from "./App/common/navigator/RnAppCreator";
|
||||
@@ -9,13 +9,30 @@ import {
|
||||
getBuildConfigDetails,
|
||||
setBuildConfigDetails,
|
||||
} from "./App/common/utilities/CacheUtils";
|
||||
import { GenericShimmerScreen } from "./App/Container/Navi-Insurance";
|
||||
import {
|
||||
getStringPreference,
|
||||
setStringPreference,
|
||||
} from "./App/common/utilities/SharedPreferenceUtils";
|
||||
|
||||
init({
|
||||
dsn: SentryConstants.SENTRY_DSN,
|
||||
environment: SentryConstants.SENTRY_ENVIRONMENT_PRODUCTION,
|
||||
});
|
||||
|
||||
export default class App extends Component<{}> {
|
||||
interface AppState {
|
||||
bundleState: BundleState;
|
||||
}
|
||||
|
||||
export default class App extends Component<{}, AppState> {
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
let bundleState = BundleState.LOADING;
|
||||
getBundleStatus().then(value => (bundleState = value));
|
||||
this.state = {
|
||||
bundleState: bundleState,
|
||||
};
|
||||
}
|
||||
checkForUpdates = async () => {
|
||||
let flavor: string | undefined;
|
||||
getBuildConfigDetails().then(res => {
|
||||
@@ -34,18 +51,44 @@ export default class App extends Component<{}> {
|
||||
|
||||
onCodepushStatusChange = (status: codePush.SyncStatus) => {
|
||||
switch (status) {
|
||||
case codePush.SyncStatus.CHECKING_FOR_UPDATE:
|
||||
case codePush.SyncStatus.DOWNLOADING_PACKAGE:
|
||||
case codePush.SyncStatus.INSTALLING_UPDATE:
|
||||
this.setState({ bundleState: BundleState.LOADING });
|
||||
storeBundleStatus(BundleState.LOADING);
|
||||
break;
|
||||
case codePush.SyncStatus.UP_TO_DATE:
|
||||
this.setState({ bundleState: BundleState.LOADED });
|
||||
storeBundleStatus(BundleState.LOADED);
|
||||
break;
|
||||
case codePush.SyncStatus.UPDATE_IGNORED:
|
||||
this.setState({ bundleState: BundleState.LOADED });
|
||||
storeBundleStatus(BundleState.LOADED);
|
||||
logToSentry(
|
||||
`Codepush Ignored | Status: ${status} | MethodName: onCodepushStatusChange`,
|
||||
);
|
||||
break;
|
||||
case codePush.SyncStatus.UNKNOWN_ERROR:
|
||||
this.setState({ bundleState: BundleState.ERROR });
|
||||
storeBundleStatus(BundleState.ERROR);
|
||||
logToSentry(
|
||||
`Codepush Failed | Status: ${status} | MethodName: onCodepushStatusChange`,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
this.setState({ bundleState: BundleState.LOADED });
|
||||
storeBundleStatus(BundleState.LOADED);
|
||||
}
|
||||
};
|
||||
|
||||
override shouldComponentUpdate(
|
||||
nextProps: Readonly<{}>,
|
||||
nextState: Readonly<AppState>,
|
||||
_: any,
|
||||
): boolean {
|
||||
return this.state.bundleState !== nextState.bundleState;
|
||||
}
|
||||
|
||||
getInitialCta = (): CtaData | undefined => {
|
||||
const { CtaData } = this.props as any;
|
||||
|
||||
@@ -68,12 +111,34 @@ export default class App extends Component<{}> {
|
||||
};
|
||||
|
||||
override componentDidMount(): void {
|
||||
setBuildConfigDetails();
|
||||
this.checkForUpdates();
|
||||
setBuildConfigDetails();
|
||||
}
|
||||
|
||||
override componentWillUnmount(): void {
|
||||
invalidateStatus(BundleState.LOADING);
|
||||
}
|
||||
|
||||
override render() {
|
||||
const cta = this.getInitialCta();
|
||||
return cta ? RnApp.create(cta) : <></>;
|
||||
return !!cta && this.state.bundleState === BundleState.LOADED ? (
|
||||
RnApp.create(cta)
|
||||
) : this.state.bundleState === BundleState.LOADING ? (
|
||||
<GenericShimmerScreen />
|
||||
) : (
|
||||
<></>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const storeBundleStatus = (bundleState: string) => {
|
||||
return setStringPreference("reactBundleState", bundleState);
|
||||
};
|
||||
|
||||
const invalidateStatus = (bundleState: string) => {
|
||||
return setStringPreference("reactBundleState", bundleState);
|
||||
};
|
||||
|
||||
const getBundleStatus = async () => {
|
||||
return await getStringPreference("reactBundleState", "string");
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export { default as QuoteOfferScreen } from "./screen/quote-offer-screen/QuoteOfferScreen";
|
||||
export { default as QuoteApologyScreen } from "./screen/quote-apology-screen/QuoteApologyScreen";
|
||||
export { default as ComparePlanScreen } from "./screen/compare-plan-screen/ComparePlanScreen";
|
||||
export { default as ComparePlanScreen } from "./screen/compare-plan-screen/ComparePlanScreen";
|
||||
export { default as GenericShimmerScreen } from "./screen/generic-shimmer-screen/GenericShimmerScreen";
|
||||
@@ -0,0 +1,104 @@
|
||||
import { View } from "react-native";
|
||||
import SkeletonPlaceholder from "react-native-skeleton-placeholder";
|
||||
import Colors from "../../../../../assets/colors/colors";
|
||||
import styles from "./GenericShimmerScreenStyle";
|
||||
import { StaticHeader } from "../../../../../components/reusable/static-header/StaticHeader";
|
||||
import { CtaData, CtaType } from "../../../../common/interface";
|
||||
import { ConstantCta } from "../../../../common/constants/CtaConstants";
|
||||
import { logToSentry } from "../../../../common/hooks/useSentryLogging";
|
||||
import {
|
||||
invalidateCacheWithUrl,
|
||||
shouldInvalidateSavedData,
|
||||
} from "../../../../common/utilities/CacheUtils";
|
||||
import { NativeDeeplinkNavigatorModule } from "../../../../common/native-module/NativeModules";
|
||||
|
||||
const GenericShimmerScreen = () => {
|
||||
const handleClick = (cta?: CtaData) => {
|
||||
if (!cta) {
|
||||
logToSentry(
|
||||
`Navigation cta is missing or invalid: ${cta} | MethodName: handleClick}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (invalidateCacheWithUrl(cta.url) || shouldInvalidateSavedData(cta)) {
|
||||
invalidatePostApiData();
|
||||
}
|
||||
|
||||
try {
|
||||
switch (cta.type) {
|
||||
case CtaType.DEEP_LINK:
|
||||
case CtaType.USE_ROOT_DEEPLINK_NAVIGATOR:
|
||||
NativeDeeplinkNavigatorModule.navigateToNaviInsuranceDeeplinkNavigator(
|
||||
JSON.stringify(cta),
|
||||
);
|
||||
break;
|
||||
default:
|
||||
NativeDeeplinkNavigatorModule.navigateToNaviDeeplinkNavigator(
|
||||
JSON.stringify(cta),
|
||||
);
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
logToSentry(
|
||||
`Error while navigating to deep link with CTA: ${cta} | MethodName: handleClick}`,
|
||||
);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.header}>
|
||||
<StaticHeader
|
||||
handleClick={handleClick}
|
||||
leftIconCta={ConstantCta.STATIC_HEADER_LEFT_ICON_CTA}
|
||||
/>
|
||||
</View>
|
||||
<ContentShimmer />
|
||||
<FooterShimmer />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default GenericShimmerScreen;
|
||||
|
||||
const ContentShimmer = () => {
|
||||
return (
|
||||
<View style={styles.content}>
|
||||
<SkeletonPlaceholder
|
||||
backgroundColor={Colors.shimmerBgColor}
|
||||
highlightColor={Colors.shimmerHighlightColor}
|
||||
direction="right"
|
||||
angle={100}
|
||||
borderRadius={4}
|
||||
>
|
||||
<View>
|
||||
<View style={styles.shimmerLayout1} />
|
||||
<View style={styles.shimmerLayout2} />
|
||||
<View style={styles.shimmerLayout3} />
|
||||
<View style={styles.shimmerLayout4} />
|
||||
</View>
|
||||
</SkeletonPlaceholder>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const FooterShimmer = () => {
|
||||
return (
|
||||
<View style={styles.footer}>
|
||||
<SkeletonPlaceholder
|
||||
backgroundColor={Colors.shimmerBgColor}
|
||||
highlightColor={Colors.shimmerHighlightColor}
|
||||
direction="right"
|
||||
angle={100}
|
||||
borderRadius={4}
|
||||
>
|
||||
<View>
|
||||
<View style={styles.shimmerFooterLayout} />
|
||||
</View>
|
||||
</SkeletonPlaceholder>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
function invalidatePostApiData() {
|
||||
throw new Error("Function not implemented.");
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
import { StyleSheet } from "react-native";
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
shimmerHeader: {
|
||||
alignItems: "stretch",
|
||||
position: "absolute",
|
||||
zIndex: 1,
|
||||
},
|
||||
shimmerContent: {},
|
||||
shimmerFooterContainer: {
|
||||
height: 100,
|
||||
zIndex: 2,
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
},
|
||||
header: {
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
width: "100%",
|
||||
backgroundColor: "white",
|
||||
},
|
||||
content: {
|
||||
marginTop: 88,
|
||||
flexGrow: 1,
|
||||
marginHorizontal: 16,
|
||||
},
|
||||
footer: {
|
||||
borderTopStartRadius: 16,
|
||||
borderTopEndRadius: 16,
|
||||
shadowColor: "black",
|
||||
shadowOpacity: 0.26,
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowRadius: 10,
|
||||
elevation: 3,
|
||||
backgroundColor: "white",
|
||||
},
|
||||
shimmerLayout1: {
|
||||
position: "relative",
|
||||
marginTop: 12,
|
||||
|
||||
height: 152,
|
||||
alignItems: "center",
|
||||
borderRadius: 4,
|
||||
flexShrink: 0,
|
||||
gap: 10.5,
|
||||
},
|
||||
shimmerLayout2: {
|
||||
position: "relative",
|
||||
marginTop: 24,
|
||||
|
||||
height: 78,
|
||||
alignItems: "center",
|
||||
borderRadius: 4,
|
||||
flexShrink: 0,
|
||||
gap: 10.5,
|
||||
},
|
||||
shimmerLayout3: {
|
||||
position: "relative",
|
||||
marginTop: 24,
|
||||
|
||||
height: 148,
|
||||
alignItems: "center",
|
||||
borderRadius: 4,
|
||||
flexShrink: 0,
|
||||
gap: 10.5,
|
||||
},
|
||||
shimmerLayout4: {
|
||||
position: "relative",
|
||||
|
||||
marginTop: 24,
|
||||
height: 35,
|
||||
alignItems: "center",
|
||||
borderRadius: 4,
|
||||
flexShrink: 0,
|
||||
gap: 10.5,
|
||||
},
|
||||
|
||||
shimmerFooterLayout: {
|
||||
position: "relative",
|
||||
marginHorizontal: 16,
|
||||
marginTop: 16,
|
||||
marginBottom: 24,
|
||||
height: 49,
|
||||
alignItems: "center",
|
||||
borderRadius: 4,
|
||||
flexShrink: 0,
|
||||
gap: 10.5,
|
||||
},
|
||||
|
||||
shimmerHeaderLayout: {
|
||||
position: "relative",
|
||||
marginHorizontal: 16,
|
||||
marginTop: 16,
|
||||
marginBottom: 24,
|
||||
height: 49,
|
||||
alignItems: "center",
|
||||
borderRadius: 4,
|
||||
flexShrink: 0,
|
||||
gap: 10.5,
|
||||
},
|
||||
});
|
||||
|
||||
export default styles;
|
||||
@@ -25,6 +25,12 @@ export enum ScreenProperties {
|
||||
ANIMATE_HEADER = "ANIMATE_HEADER",
|
||||
}
|
||||
|
||||
export enum BundleState {
|
||||
LOADING = "LOADING",
|
||||
LOADED = "LOADED",
|
||||
ERROR = "ERROR",
|
||||
}
|
||||
|
||||
export const ERROR_TITLE = "Something went wrong";
|
||||
export const ERROR_SUBTITLE = "Please try again after some time";
|
||||
export const RETRY = "Retry";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { TouchableOpacity } from "react-native-gesture-handler";
|
||||
import { BackHandler, View } from "react-native";
|
||||
import { BackHandler, View, TouchableOpacity } from "react-native";
|
||||
import { CtaData } from "../../../App/common/interface";
|
||||
import { styles } from "./StaticHeaderStyle";
|
||||
import { ImageName } from "../../../App/common/constants/StringConstant";
|
||||
|
||||
Reference in New Issue
Block a user