import React, { useEffect, useRef } from "react";
import { ScrollView, View } from "react-native";
import Loader from "~/components/Loader";
import { useSubscription } from "@apollo/client";
import Error from "~/components/Error";
import * as Sentry from "@sentry/react-native";
import { LOAD_PROFILE_SUBSCRIPTION } from "./gql";
import { useNetworkState, useSessionState } from "~/stores";
import { createLogger } from "~/lib/logger";
import { FEATURE_SCOPES } from "~/lib/logger/scopes";
import withConnectivity from "~/hoc/withConnectivity";
import { useIsFocused } from "@react-navigation/native";
import Form from "./Form";
const profileLogger = createLogger({
module: FEATURE_SCOPES.PROFILE,
feature: "screen",
});
export default withConnectivity(function Profile({ navigation, route }) {
const { userId } = useSessionState(["userId"]);
const { wsClosedDate, wsConnected, hasInternetConnection } = useNetworkState([
"wsClosedDate",
"wsConnected",
"hasInternetConnection",
]);
const isFocused = useIsFocused();
const lastDataAtRef = useRef(Date.now());
// profileLogger.debug("Profile user ID", { userId });
const { data, loading, error, restart } = useSubscription(
LOAD_PROFILE_SUBSCRIPTION,
{
variables: {
userId,
},
skip: !userId,
},
);
useEffect(() => {
restart();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [userId]);
useEffect(() => {
if (!wsClosedDate) return;
// WS was closed/reconnected; restart the subscription to avoid being stuck.
try {
profileLogger.info(
"WS reconnect detected, restarting profile subscription",
{
wsClosedDate,
},
);
restart();
} catch (_e) {
// ignore
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wsClosedDate]);
useEffect(() => {
if (!isFocused) return;
if (!hasInternetConnection) return;
if (!wsConnected) return;
const interval = setInterval(() => {
const age = Date.now() - lastDataAtRef.current;
if (age < 45_000) return;
try {
Sentry.addBreadcrumb({
category: "profile",
level: "warning",
message: "profile subscription stale, restarting",
data: { ageMs: age },
});
} catch (_e) {
// ignore
}
profileLogger.warn("Profile subscription stale, restarting", {
ageMs: age,
});
try {
lastDataAtRef.current = Date.now();
restart();
} catch (_e) {
// ignore
}
}, 15_000);
return () => clearInterval(interval);
}, [hasInternetConnection, isFocused, restart, wsConnected]);
useEffect(() => {
if (data?.selectOneUser) {
lastDataAtRef.current = Date.now();
}
}, [data]);
const clearAuthWaitParams = React.useCallback(() => {
navigation.setParams({
waitingSmsType: undefined,
openAccountModal: undefined,
});
}, [navigation]);
if (!userId) {
return ;
}
if (loading) {
return ;
}
if (error) {
profileLogger.error("Profile subscription error", { error });
return ;
}
if (!data?.selectOneUser) {
// No error surfaced, but no payload either. Avoid infinite loader.
profileLogger.error("Profile subscription returned no user", { userId });
return ;
}
return (
);
});