use menu button to show/hide selectors

Once I have more than one area of the UI (e.g., adding config, live
video, or a scrub bar prototype), I'll use this for a pull-down menu to
go between them, and maybe add a filter icon to do what this does. But
this works for now and most closely matches the old UI.

I tried to use a Collapse or Slide transition, but I had trouble getting
it to work on both desktop and mobile. In particular, the way I used the
flex wrap to display the selectors on the left/above doesn't seem
compatible with picking an orientation. If I pick the wrong orientation,
the list views won't fill the empty space.
This commit is contained in:
Scott Lamb 2021-03-16 16:15:03 -07:00
parent 4d6a8c98d9
commit 731eb8170d
2 changed files with 25 additions and 15 deletions

View File

@ -3,7 +3,7 @@
// SPDX-License-Identifier: GPL-v3.0-or-later WITH GPL-3.0-linking-exception // SPDX-License-Identifier: GPL-v3.0-or-later WITH GPL-3.0-linking-exception
import Container from "@material-ui/core/Container"; import Container from "@material-ui/core/Container";
import React, { useEffect, useState } from "react"; import React, { useEffect, useReducer, useState } from "react";
import * as api from "./api"; import * as api from "./api";
import MoonfireMenu from "./AppMenu"; import MoonfireMenu from "./AppMenu";
import Login from "./Login"; import Login from "./Login";
@ -19,6 +19,7 @@ type LoginState =
| "user-requested-login"; | "user-requested-login";
function App() { function App() {
const [showMenu, toggleShowMenu] = useReducer((m: boolean) => !m, true);
const [session, setSession] = useState<Session | null>(null); const [session, setSession] = useState<Session | null>(null);
const [cameras, setCameras] = useState<Camera[] | null>(null); const [cameras, setCameras] = useState<Camera[] | null>(null);
const [timeZoneName, setTimeZoneName] = useState<string | null>(null); const [timeZoneName, setTimeZoneName] = useState<string | null>(null);
@ -96,6 +97,7 @@ function App() {
setLoginState("user-requested-login"); setLoginState("user-requested-login");
}} }}
logout={logout} logout={logout}
menuClick={toggleShowMenu}
/> />
</AppBar> </AppBar>
<Login <Login
@ -121,7 +123,11 @@ function App() {
</Container> </Container>
)} )}
{cameras != null && cameras.length > 0 && ( {cameras != null && cameras.length > 0 && (
<List cameras={cameras} timeZoneName={timeZoneName!} /> <List
cameras={cameras}
showMenu={showMenu}
timeZoneName={timeZoneName!}
/>
)} )}
</> </>
); );

View File

@ -2,20 +2,21 @@
// Copyright (C) 2021 The Moonfire NVR Authors; see AUTHORS and LICENSE.txt. // 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 // SPDX-License-Identifier: GPL-v3.0-or-later WITH GPL-3.0-linking-exception
import React, { useMemo, useState } from "react"; import Box from "@material-ui/core/Box";
import { Camera, Stream } from "../types";
import * as api from "../api";
import VideoList from "./VideoList";
import { makeStyles, Theme } from "@material-ui/core/styles";
import Modal from "@material-ui/core/Modal"; import Modal from "@material-ui/core/Modal";
import format from "date-fns/format"; import Paper from "@material-ui/core/Paper";
import utcToZonedTime from "date-fns-tz/utcToZonedTime"; import { makeStyles, Theme } from "@material-ui/core/styles";
import Table from "@material-ui/core/Table"; import Table from "@material-ui/core/Table";
import TableContainer from "@material-ui/core/TableContainer"; import TableContainer from "@material-ui/core/TableContainer";
import Paper from "@material-ui/core/Paper"; import utcToZonedTime from "date-fns-tz/utcToZonedTime";
import format from "date-fns/format";
import React, { useMemo, useState } from "react";
import * as api from "../api";
import { Camera, Stream } from "../types";
import DisplaySelector from "./DisplaySelector";
import StreamMultiSelector from "./StreamMultiSelector"; import StreamMultiSelector from "./StreamMultiSelector";
import TimerangeSelector from "./TimerangeSelector"; import TimerangeSelector from "./TimerangeSelector";
import DisplaySelector from "./DisplaySelector"; import VideoList from "./VideoList";
const useStyles = makeStyles((theme: Theme) => ({ const useStyles = makeStyles((theme: Theme) => ({
root: { root: {
@ -62,11 +63,11 @@ const useStyles = makeStyles((theme: Theme) => ({
interface Props { interface Props {
timeZoneName: string; timeZoneName: string;
cameras: Camera[]; cameras: Camera[];
showMenu: boolean;
} }
const Main = ({ cameras, timeZoneName }: Props) => { const Main = ({ cameras, timeZoneName, showMenu }: Props) => {
const classes = useStyles(); const classes = useStyles();
/** /**
@ -123,7 +124,10 @@ const Main = ({ cameras, timeZoneName }: Props) => {
); );
return ( return (
<div className={classes.root}> <div className={classes.root}>
<div className={classes.selectors}> <Box
className={classes.selectors}
sx={{ display: showMenu ? "block" : "none" }}
>
<StreamMultiSelector <StreamMultiSelector
cameras={cameras} cameras={cameras}
selected={selectedStreams} selected={selectedStreams}
@ -143,7 +147,7 @@ const Main = ({ cameras, timeZoneName }: Props) => {
timestampTrack={timestampTrack} timestampTrack={timestampTrack}
setTimestampTrack={setTimestampTrack} setTimestampTrack={setTimestampTrack}
/> />
</div> </Box>
{videoLists.length > 0 && recordingsTable} {videoLists.length > 0 && recordingsTable}
{activeRecording != null && ( {activeRecording != null && (
<Modal open onClose={closeModal}> <Modal open onClose={closeModal}>