// This file is part of Moonfire NVR, a security camera network video recorder. // Copyright (C) 2021 The Moonfire NVR Authors; see AUTHORS and LICENSE.txt. // SPDX-License-Identifier: GPL-v3.0-or-later WITH GPL-3.0-linking-exception import Container from "@material-ui/core/Container"; import React, { useEffect, useReducer, useState } from "react"; import * as api from "./api"; import MoonfireMenu from "./AppMenu"; import Login from "./Login"; import { useSnackbars } from "./snackbars"; import { Camera, Session } from "./types"; import List from "./List"; import AppBar from "@material-ui/core/AppBar"; type LoginState = | "logged-in" | "not-logged-in" | "server-requires-login" | "user-requested-login"; function App() { const [showMenu, toggleShowMenu] = useReducer((m: boolean) => !m, true); const [session, setSession] = useState(null); const [cameras, setCameras] = useState(null); const [timeZoneName, setTimeZoneName] = useState(null); const [fetchSeq, setFetchSeq] = useState(0); const [loginState, setLoginState] = useState("not-logged-in"); const [error, setError] = useState(null); const needNewFetch = () => setFetchSeq((seq) => seq + 1); const snackbars = useSnackbars(); const onLoginSuccess = () => { setLoginState("logged-in"); needNewFetch(); }; const logout = async () => { const resp = await api.logout( { csrf: session!.csrf, }, {} ); switch (resp.status) { case "aborted": break; case "error": snackbars.enqueue({ message: "Logout failed: " + resp.message, }); break; case "success": setSession(null); needNewFetch(); break; } }; useEffect(() => { const abort = new AbortController(); const doFetch = async (signal: AbortSignal) => { const resp = await api.toplevel({ signal }); switch (resp.status) { case "aborted": break; case "error": if (resp.httpStatus === 401) { setLoginState("server-requires-login"); return; } setError(resp); break; case "success": setError(null); setLoginState( resp.response.session === undefined ? "not-logged-in" : "logged-in" ); setSession(resp.response.session || null); setCameras(resp.response.cameras); setTimeZoneName(resp.response.timeZoneName); } }; doFetch(abort.signal); return () => { abort.abort(); }; }, [fetchSeq]); return ( <> { setLoginState("user-requested-login"); }} logout={logout} menuClick={toggleShowMenu} /> { setLoginState((s) => s === "user-requested-login" ? "not-logged-in" : s ); }} /> {error != null && (

Error querying server

{error.message}

You may find more information in the Javascript console. Try reloading the page once you believe the problem is resolved.

)} {cameras != null && cameras.length > 0 && ( )} ); } export default App;