feat(mobile): auth added in
Some checks failed
Build and Push LST Docker Image / docker (push) Has been cancelled
Some checks failed
Build and Push LST Docker Image / docker (push) Has been cancelled
This commit is contained in:
133
lstMobile/src/hooks/useAppStartup.tsx
Normal file
133
lstMobile/src/hooks/useAppStartup.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
import axios from "axios";
|
||||
import Constants from "expo-constants";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { devDelay } from "../lib/devMode";
|
||||
import { useAppStore } from "./useAppStore";
|
||||
import { useServerStore } from "./useServerCheck";
|
||||
|
||||
type StartupStatus =
|
||||
| "loading"
|
||||
| "validating"
|
||||
| "scannerMode"
|
||||
| "normalScanner"
|
||||
| "checkingUpdates"
|
||||
| "opening"
|
||||
| "error";
|
||||
|
||||
export function useAppStartup() {
|
||||
const [ready, setReady] = useState(false);
|
||||
const [status, setStatus] = useState<StartupStatus>("loading");
|
||||
const [startupRoute, setStartupRoute] = useState<string | null>(null);
|
||||
|
||||
const hasRunKey = useRef<string | null>(null);
|
||||
|
||||
const hasHydrated = useAppStore((s) => s.hasHydrated);
|
||||
const serverPort = useAppStore((s) => s.serverPort);
|
||||
const serverIp = useAppStore((s) => s.serverIp);
|
||||
const setServerVersion = useServerStore((s) => s.setServerVersion);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasHydrated) {
|
||||
setStatus("loading");
|
||||
return;
|
||||
}
|
||||
|
||||
const runKey = `${serverIp}:${serverPort}`;
|
||||
|
||||
if (hasRunKey.current === runKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
hasRunKey.current = runKey;
|
||||
|
||||
let cancelled = false;
|
||||
|
||||
const startup = async () => {
|
||||
try {
|
||||
setReady(false);
|
||||
setStartupRoute(null);
|
||||
|
||||
await devDelay(1500);
|
||||
if (cancelled) return;
|
||||
|
||||
setStatus("validating");
|
||||
await devDelay(1500);
|
||||
if (cancelled) return;
|
||||
|
||||
const hasValidSetup = useAppStore.getState().hasValidSetup;
|
||||
|
||||
if (!hasValidSetup()) {
|
||||
setStartupRoute("/setup");
|
||||
setReady(true);
|
||||
return;
|
||||
}
|
||||
|
||||
const port =
|
||||
parseInt(serverPort || "0", 10) >= 50000 ? "3000" : serverPort;
|
||||
|
||||
try {
|
||||
const res = await axios.get(
|
||||
`http://${serverIp}:${port}/lst/api/mobile/version`,
|
||||
{ timeout: 5000 },
|
||||
);
|
||||
|
||||
if (res.status === 200) {
|
||||
setServerVersion(res.data);
|
||||
}
|
||||
|
||||
const build = Constants.expoConfig?.android?.versionCode ?? 1;
|
||||
|
||||
if (build < res.data.minSupportedVersionCode) {
|
||||
setStartupRoute("/updateScreen");
|
||||
setReady(true);
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Version check error:", error);
|
||||
}
|
||||
|
||||
setStatus("scannerMode");
|
||||
await devDelay(1500);
|
||||
if (cancelled) return;
|
||||
|
||||
if (parseInt(serverPort || "0", 10) >= 50000) {
|
||||
setStatus("normalScanner");
|
||||
await devDelay(1500);
|
||||
|
||||
setStartupRoute("/scanner");
|
||||
setReady(true);
|
||||
return;
|
||||
}
|
||||
|
||||
setStatus("checkingUpdates");
|
||||
console.log("checking updates");
|
||||
await devDelay(1500);
|
||||
if (cancelled) return;
|
||||
|
||||
setStatus("opening");
|
||||
console.log("opening");
|
||||
await devDelay(1500);
|
||||
if (cancelled) return;
|
||||
|
||||
setStartupRoute("/(tabs)/scanner");
|
||||
console.log("scanner");
|
||||
setReady(true);
|
||||
} catch (error) {
|
||||
console.log("Startup error:", error);
|
||||
setStatus("error");
|
||||
}
|
||||
};
|
||||
|
||||
startup();
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [hasHydrated, serverIp, serverPort, setServerVersion]);
|
||||
|
||||
return {
|
||||
ready,
|
||||
startupRoute,
|
||||
status,
|
||||
};
|
||||
}
|
||||
33
lstMobile/src/hooks/useDeviceCheck.tsx
Normal file
33
lstMobile/src/hooks/useDeviceCheck.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { AppState, type AppStateStatus } from "react-native";
|
||||
import { useMobileAuthStore } from "./useMobileAuth";
|
||||
|
||||
export default function useDeviceLock() {
|
||||
const [appState, setAppState] = useState<AppStateStatus>(
|
||||
AppState.currentState,
|
||||
);
|
||||
const appStateRef = useRef<AppStateStatus>(AppState.currentState);
|
||||
|
||||
useEffect(() => {
|
||||
const subscription = AppState.addEventListener("change", (nextAppState) => {
|
||||
const previousAppState = appStateRef.current;
|
||||
|
||||
const wasActive = previousAppState === "active";
|
||||
|
||||
// if the we see aggressive locking then we should remove inactive.
|
||||
const isNowInactive =
|
||||
nextAppState === "background" || nextAppState === "inactive";
|
||||
|
||||
if (wasActive && isNowInactive) {
|
||||
useMobileAuthStore.getState().lock();
|
||||
}
|
||||
|
||||
appStateRef.current = nextAppState;
|
||||
setAppState(nextAppState);
|
||||
});
|
||||
|
||||
return () => subscription.remove();
|
||||
}, []);
|
||||
|
||||
return appState;
|
||||
}
|
||||
@@ -5,6 +5,7 @@ type MobileUser = {
|
||||
name: string;
|
||||
role: "user" | "lead" | "manager" | "admin";
|
||||
excludedCommand: string[];
|
||||
scannerId: string;
|
||||
};
|
||||
|
||||
type AuthState = {
|
||||
|
||||
Reference in New Issue
Block a user