231 lines
6.7 KiB
TypeScript
231 lines
6.7 KiB
TypeScript
import UploadProgress from "@/components/upload-progress/upload-progress";
|
|
import { checkUserSession } from "@/redux/user/user.actions";
|
|
import { selectBodyshop, selectCurrentUser } from "@/redux/user/user.selectors";
|
|
import { ApolloProvider } from "@apollo/client";
|
|
import { loadDevMessages, loadErrorMessages } from "@apollo/client/dev";
|
|
import MaterialIcons from "@expo/vector-icons/MaterialIcons";
|
|
|
|
import {
|
|
DarkTheme,
|
|
DefaultTheme,
|
|
ThemeProvider,
|
|
} from "@react-navigation/native";
|
|
import * as Sentry from "@sentry/react-native";
|
|
import * as Notifications from "expo-notifications";
|
|
import { Stack } from "expo-router";
|
|
import {
|
|
Icon,
|
|
Label,
|
|
NativeTabs,
|
|
VectorIcon,
|
|
} from "expo-router/unstable-native-tabs";
|
|
import React, { useEffect } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { Platform, View } from "react-native";
|
|
import {
|
|
ActivityIndicator,
|
|
Provider as PaperProvider,
|
|
} from "react-native-paper";
|
|
import { connect, Provider } from "react-redux";
|
|
import { PersistGate } from "redux-persist/integration/react";
|
|
import { createStructuredSelector } from "reselect";
|
|
import { client } from "../graphql/client";
|
|
import { useTheme as usePaperTheme } from "../hooks/useTheme";
|
|
import { persistor, store } from "../redux/store";
|
|
import "../translations/i18n";
|
|
import { registerForPushNotificationsAsync } from "../util/notificationHandler";
|
|
|
|
loadDevMessages();
|
|
loadErrorMessages();
|
|
|
|
Sentry.init({
|
|
dsn: "https://8d6c3de1940a4e4f8b81cf4d2150bdea@o492140.ingest.us.sentry.io/5558869",
|
|
// Adds more context data to events (IP address, cookies, user, etc.)
|
|
// For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
|
|
sendDefaultPii: true,
|
|
// Enable Logs
|
|
enableLogs: true,
|
|
// Configure Session Replay
|
|
replaysSessionSampleRate: 0.1,
|
|
replaysOnErrorSampleRate: 1,
|
|
integrations: [
|
|
Sentry.mobileReplayIntegration(),
|
|
Sentry.feedbackIntegration(),
|
|
],
|
|
ignoreErrors: [/.*Network Error.*/i],
|
|
});
|
|
|
|
function AuthenticatedLayout() {
|
|
const { t } = useTranslation();
|
|
const paperTheme = usePaperTheme();
|
|
|
|
return (
|
|
<ThemeProvider
|
|
value={paperTheme.theme === "dark" ? DarkTheme : DefaultTheme}
|
|
>
|
|
<NativeTabs
|
|
minimizeBehavior="onScrollDown"
|
|
disableTransparentOnScrollEdge
|
|
{...(paperTheme.theme === "dark"
|
|
? {
|
|
backgroundColor: DarkTheme.colors.background,
|
|
tintColor: DarkTheme.colors.text,
|
|
indicatorColor: DarkTheme.colors.border,
|
|
}
|
|
: {})}
|
|
>
|
|
<NativeTabs.Trigger name="jobs">
|
|
<Label>{t("joblist.labels.activejobs")}</Label>
|
|
|
|
{Platform.select({
|
|
ios: <Icon sf="checklist" drawable="custom_android_drawable" />,
|
|
android: (
|
|
<Icon
|
|
src={<VectorIcon family={MaterialIcons} name="checklist" />}
|
|
/>
|
|
),
|
|
})}
|
|
</NativeTabs.Trigger>
|
|
{/* <NativeTabs.Trigger name="production">
|
|
{Platform.select({
|
|
ios: <Icon sf="gear" drawable="custom_android_drawable" />,
|
|
android: (
|
|
<Icon src={<VectorIcon family={MaterialIcons} name="start" />} />
|
|
),
|
|
})}
|
|
<Label>{t("production.titles.production")}</Label>
|
|
</NativeTabs.Trigger> */}
|
|
<NativeTabs.Trigger name="settings">
|
|
{Platform.select({
|
|
ios: <Icon sf="gear" drawable="custom_android_drawable" />,
|
|
android: (
|
|
<Icon
|
|
src={<VectorIcon family={MaterialIcons} name="settings" />}
|
|
/>
|
|
),
|
|
})}
|
|
<Label>{t("settings.titles.settings")}</Label>
|
|
</NativeTabs.Trigger>
|
|
<NativeTabs.Trigger name="search" role="search">
|
|
{Platform.select({
|
|
//ios: <Icon sf="checklist" drawable="custom_android_drawable" />,
|
|
android: (
|
|
<Icon src={<VectorIcon family={MaterialIcons} name="search" />} />
|
|
),
|
|
})}
|
|
<Label>Search</Label>
|
|
</NativeTabs.Trigger>
|
|
</NativeTabs>
|
|
</ThemeProvider>
|
|
);
|
|
}
|
|
|
|
function UnauthenticatedLayout() {
|
|
const paperTheme = usePaperTheme();
|
|
|
|
return (
|
|
<ThemeProvider
|
|
value={paperTheme.theme === "dark" ? DarkTheme : DefaultTheme}
|
|
>
|
|
<Stack>
|
|
<Stack.Screen name="sign-in" options={{ headerShown: false }} />
|
|
</Stack>
|
|
</ThemeProvider>
|
|
);
|
|
}
|
|
|
|
function LoadingLayout() {
|
|
return (
|
|
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
|
|
<ActivityIndicator size="large" />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const mapStateToProps = createStructuredSelector({
|
|
bodyshop: selectBodyshop,
|
|
currentUser: selectCurrentUser,
|
|
});
|
|
const mapDispatchToProps = (dispatch: any) => ({
|
|
checkUserSession: () => dispatch(checkUserSession()),
|
|
});
|
|
function AppContent({ currentUser, checkUserSession, bodyshop }: any) {
|
|
useEffect(() => {
|
|
checkUserSession();
|
|
}, [checkUserSession]);
|
|
|
|
useEffect(() => {
|
|
registerForPushNotificationsAsync()
|
|
.then((token) => console.log("Expo Push Token:", token))
|
|
.catch((error: any) =>
|
|
console.log("Error getting Expo Push Token:", error)
|
|
);
|
|
|
|
const notificationListener = Notifications.addNotificationReceivedListener(
|
|
async (notification) => {
|
|
console.log("Notification received:", notification);
|
|
Notifications.setBadgeCountAsync(
|
|
(await Notifications.getBadgeCountAsync()) + 1
|
|
);
|
|
}
|
|
);
|
|
|
|
const responseListener =
|
|
Notifications.addNotificationResponseReceivedListener((response) => {
|
|
console.log("Notification response received:", response);
|
|
});
|
|
|
|
//Clear the badges.
|
|
Notifications.setBadgeCountAsync(0);
|
|
|
|
return () => {
|
|
notificationListener.remove();
|
|
responseListener.remove();
|
|
};
|
|
}, []);
|
|
|
|
if (currentUser.authorized === null) {
|
|
return (
|
|
<ThemedLayout>
|
|
<LoadingLayout />
|
|
</ThemedLayout>
|
|
);
|
|
}
|
|
if (currentUser.authorized) {
|
|
return (
|
|
<ThemedLayout>
|
|
<UploadProgress />
|
|
<AuthenticatedLayout />
|
|
</ThemedLayout>
|
|
);
|
|
}
|
|
return (
|
|
<ThemedLayout>
|
|
<UnauthenticatedLayout />
|
|
</ThemedLayout>
|
|
);
|
|
}
|
|
|
|
function ThemedLayout({ children }: { children: React.ReactNode }) {
|
|
const themeToApply = usePaperTheme();
|
|
return <PaperProvider theme={themeToApply}>{children}</PaperProvider>;
|
|
}
|
|
const ConnectedAppContent = connect(
|
|
mapStateToProps,
|
|
mapDispatchToProps
|
|
)(AppContent);
|
|
|
|
function AppLayout() {
|
|
return (
|
|
<Provider store={store}>
|
|
<PersistGate persistor={persistor}>
|
|
<ApolloProvider client={client}>
|
|
<ConnectedAppContent />
|
|
</ApolloProvider>
|
|
</PersistGate>
|
|
</Provider>
|
|
);
|
|
}
|
|
|
|
export default Sentry.wrap(AppLayout);
|