160 lines
5.2 KiB
TypeScript
160 lines
5.2 KiB
TypeScript
import React, { createContext, useContext, useEffect, useState, ReactNode } from "react";
|
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
import { AppState } from "react-native";
|
|
import { v4 as uuidv4 } from "uuid";
|
|
import axios from "axios";
|
|
import log from "@/util/log"
|
|
|
|
export const API_URL = process.env.EXPO_PUBLIC_API_URL;
|
|
|
|
// Define context type
|
|
interface UserContextType {
|
|
isProfileActive: boolean;
|
|
setProfileActive: (active: boolean) => void;
|
|
userId: string;
|
|
userName: string;
|
|
setUserName: (name: string) => void;
|
|
userImage: string;
|
|
setUserImage: (image: string) => void;
|
|
userStatus: string;
|
|
setUserStatus: (status: string) => void;
|
|
setUserDataChanged: (changed: boolean) => void;
|
|
isLoading: boolean;
|
|
currentTheme: string;
|
|
setTheme: (theme: string) => void;
|
|
}
|
|
|
|
// Create context with default values
|
|
const UserContext = createContext<UserContextType | undefined>(undefined);
|
|
|
|
// Define provider props type
|
|
interface UserProviderProps {
|
|
children: ReactNode;
|
|
}
|
|
|
|
export const UserProvider: React.FC<UserProviderProps> = ({ children }) => {
|
|
const [isProfileActive, setProfileActive] = useState(false);
|
|
const [userId, setUserId] = useState("");
|
|
const [userName, setUserName] = useState("");
|
|
const [userImage, setUserImage] = useState("");
|
|
const [userStatus, setUserStatus] = useState("none");
|
|
const [userDataChanged, setUserDataChanged] = useState(false);
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
const [appState, setAppState] = useState(AppState.currentState);
|
|
const [currentTheme, setTheme] = useState("");
|
|
const [isDarkMode, setDarkMode] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const loadUserData = async () => {
|
|
try {
|
|
const storedUserId = await AsyncStorage.getItem("userId");
|
|
const storedUserName = await AsyncStorage.getItem("userName");
|
|
const storedUserImage = await AsyncStorage.getItem("userImage");
|
|
const storedUserTheme = await AsyncStorage.getItem("theme");
|
|
log.debug("Stored theme: ", storedUserTheme);
|
|
if (storedUserId) {
|
|
setUserId(storedUserId);
|
|
setUserName(storedUserName || "");
|
|
setUserImage(storedUserImage || "");
|
|
setTheme(storedUserTheme || "blue");
|
|
setProfileActive(false);
|
|
} else {
|
|
setUserId(uuidv4());
|
|
setUserName("");
|
|
setUserImage("");
|
|
setTheme("blue")
|
|
setProfileActive(true);
|
|
}
|
|
} catch (error) {
|
|
log.error("Error loading user data:", error);
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
loadUserData();
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (!userDataChanged) return;
|
|
|
|
const saveUserData = async () => {
|
|
try {
|
|
await AsyncStorage.setItem("userId", userId);
|
|
await AsyncStorage.setItem("userName", userName);
|
|
await AsyncStorage.setItem("userImage", userImage);
|
|
await AsyncStorage.setItem("theme", currentTheme);
|
|
log.debug("Current theme: ", currentTheme);
|
|
setUserDataChanged(false);
|
|
} catch (error) {
|
|
log.error("Error saving user data:", error);
|
|
}
|
|
};
|
|
|
|
saveUserData();
|
|
}, [userDataChanged]);
|
|
|
|
useEffect(() => {
|
|
const handleAppStateChange = (nextAppState: string) => {
|
|
if (appState.match(/inactive|background/) && nextAppState === "active") {
|
|
if (!isLoading) {
|
|
fetchCurrentStatus();
|
|
} else {
|
|
log.debug("Waiting for loading to complete before fetching status...");
|
|
}
|
|
}
|
|
setAppState(AppState.currentState);
|
|
};
|
|
|
|
const listener = AppState.addEventListener("change", handleAppStateChange);
|
|
|
|
return () => {
|
|
listener.remove();
|
|
};
|
|
}, [appState]);
|
|
|
|
const fetchCurrentStatus = async () => {
|
|
try {
|
|
const response = await axios.post(API_URL + "/get", { id: userId });
|
|
if (response.data?.status) {
|
|
setTimeout(() => {
|
|
setUserStatus("none");
|
|
}, 0);
|
|
}
|
|
} catch (error) {
|
|
log.error("Error fetching status:", error);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<UserContext.Provider
|
|
value={{
|
|
isProfileActive,
|
|
setProfileActive,
|
|
userId,
|
|
userName,
|
|
setUserName,
|
|
userImage,
|
|
setUserImage,
|
|
userStatus,
|
|
setUserStatus,
|
|
setUserDataChanged,
|
|
isLoading,
|
|
currentTheme,
|
|
setTheme,
|
|
}}
|
|
>
|
|
{children}
|
|
</UserContext.Provider>
|
|
);
|
|
};
|
|
|
|
// Custom hook to use context
|
|
export const useUser = (): UserContextType => {
|
|
const context = useContext(UserContext);
|
|
if (!context) {
|
|
throw new Error("useUser must be used within a UserProvider");
|
|
}
|
|
return context;
|
|
};
|