mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2025-12-06 07:42:29 -05:00
Stop using deprecated @mui/styles
I was struggling to upgrade the version of mui stuff (material and date picker). I'm hoping getting rid of the deprecated stuff eases this a bit. I don't love that I can't just use sx on plain HTML stuff and have to wrap it in Box, but oh well. Looks like I'm not alone, fwiw. https://github.com/mui/material-ui/issues/23220
This commit is contained in:
@@ -2,11 +2,11 @@
|
||||
// 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 Box from "@mui/material/Box";
|
||||
import Card from "@mui/material/Card";
|
||||
import { Camera, Stream, StreamType } from "../types";
|
||||
import Checkbox from "@mui/material/Checkbox";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import { makeStyles } from "@mui/styles";
|
||||
import { ToplevelResponse } from "../api";
|
||||
|
||||
interface Props {
|
||||
@@ -15,30 +15,9 @@ interface Props {
|
||||
setSelected: (selected: Set<number>) => void;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles({
|
||||
streamSelectorTable: {
|
||||
fontSize: "0.9rem",
|
||||
"& td:first-child": {
|
||||
paddingRight: "3px",
|
||||
},
|
||||
"& td:not(:first-child)": {
|
||||
textAlign: "center",
|
||||
},
|
||||
},
|
||||
check: {
|
||||
padding: "3px",
|
||||
},
|
||||
"@media (pointer: fine)": {
|
||||
check: {
|
||||
padding: "0px",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/** Returns a table which allows selecting zero or more streams. */
|
||||
const StreamMultiSelector = ({ toplevel, selected, setSelected }: Props) => {
|
||||
const theme = useTheme();
|
||||
const classes = useStyles();
|
||||
const setStream = (s: Stream, checked: boolean) => {
|
||||
const updated = new Set(selected);
|
||||
if (checked) {
|
||||
@@ -92,13 +71,10 @@ const StreamMultiSelector = ({ toplevel, selected, setSelected }: Props) => {
|
||||
function checkbox(st: StreamType) {
|
||||
const s = c.streams[st];
|
||||
if (s === undefined) {
|
||||
return (
|
||||
<Checkbox className={classes.check} color="secondary" disabled />
|
||||
);
|
||||
return <Checkbox color="secondary" disabled />;
|
||||
}
|
||||
return (
|
||||
<Checkbox
|
||||
className={classes.check}
|
||||
size="small"
|
||||
checked={selected.has(s.id)}
|
||||
color="secondary"
|
||||
@@ -120,7 +96,26 @@ const StreamMultiSelector = ({ toplevel, selected, setSelected }: Props) => {
|
||||
padding: theme.spacing(1),
|
||||
}}
|
||||
>
|
||||
<table className={classes.streamSelectorTable}>
|
||||
<Box
|
||||
component="table"
|
||||
sx={{
|
||||
fontSize: "0.9rem",
|
||||
"& td:first-child": {
|
||||
paddingRight: "3px",
|
||||
},
|
||||
"& td:not(:first-child)": {
|
||||
textAlign: "center",
|
||||
},
|
||||
"& .MuiCheckbox-root": {
|
||||
padding: "3px",
|
||||
},
|
||||
"@media (pointer: fine)": {
|
||||
"& .MuiCheckbox-root": {
|
||||
padding: "0px",
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<td />
|
||||
@@ -129,7 +124,7 @@ const StreamMultiSelector = ({ toplevel, selected, setSelected }: Props) => {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{cameraRows}</tbody>
|
||||
</table>
|
||||
</Box>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
import Box from "@mui/material/Box";
|
||||
import Modal from "@mui/material/Modal";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import { makeStyles } from "@mui/styles";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import Table from "@mui/material/Table";
|
||||
import TableContainer from "@mui/material/TableContainer";
|
||||
import utcToZonedTime from "date-fns-tz/utcToZonedTime";
|
||||
@@ -26,56 +25,6 @@ import { FrameProps } from "../App";
|
||||
import IconButton from "@mui/material/IconButton";
|
||||
import FilterList from "@mui/icons-material/FilterList";
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) => ({
|
||||
root: {
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
margin: theme.spacing(2),
|
||||
},
|
||||
selectors: {
|
||||
width: "max-content",
|
||||
"& .MuiCard-root": {
|
||||
marginRight: theme.spacing(2),
|
||||
marginBottom: theme.spacing(2),
|
||||
},
|
||||
},
|
||||
videoTable: {
|
||||
flexGrow: 1,
|
||||
width: "max-content",
|
||||
height: "max-content",
|
||||
"& .streamHeader": {
|
||||
background: theme.palette.primary.light,
|
||||
color: theme.palette.primary.contrastText,
|
||||
},
|
||||
"& .MuiTableBody-root:not(:last-child):after": {
|
||||
content: "''",
|
||||
display: "block",
|
||||
height: theme.spacing(2),
|
||||
},
|
||||
"& tbody .recording": {
|
||||
cursor: "pointer",
|
||||
},
|
||||
"& .opt": {
|
||||
[theme.breakpoints.down("lg")]: {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// When there's a video modal up, make the content as large as possible
|
||||
// without distorting it. Center it in the screen and ensure that the video
|
||||
// element only takes up the space actually used by the content, so that
|
||||
// clicking outside it will dismiss the modal.
|
||||
videoModal: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
"& video": {
|
||||
objectFit: "fill",
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
interface FullScreenVideoProps {
|
||||
src: string;
|
||||
aspect: [number, number];
|
||||
@@ -225,7 +174,7 @@ const calcSelectedStreams = (
|
||||
};
|
||||
|
||||
const Main = ({ toplevel, timeZoneName, Frame }: Props) => {
|
||||
const classes = useStyles();
|
||||
const theme = useTheme();
|
||||
|
||||
const {
|
||||
selectedStreamIds,
|
||||
@@ -288,7 +237,31 @@ const Main = ({ toplevel, timeZoneName, Frame }: Props) => {
|
||||
setActiveRecording(null);
|
||||
};
|
||||
const recordingsTable = (
|
||||
<TableContainer component={Paper} className={classes.videoTable}>
|
||||
<TableContainer
|
||||
component={Paper}
|
||||
sx={{
|
||||
flexGrow: 1,
|
||||
width: "max-content",
|
||||
height: "max-content",
|
||||
"& .streamHeader": {
|
||||
background: theme.palette.primary.light,
|
||||
color: theme.palette.primary.contrastText,
|
||||
},
|
||||
"& .MuiTableBody-root:not(:last-child):after": {
|
||||
content: "''",
|
||||
display: "block",
|
||||
height: theme.spacing(2),
|
||||
},
|
||||
"& tbody .recording": {
|
||||
cursor: "pointer",
|
||||
},
|
||||
"& .opt": {
|
||||
[theme.breakpoints.down("lg")]: {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Table size="small">{videoLists}</Table>
|
||||
</TableContainer>
|
||||
);
|
||||
@@ -305,10 +278,22 @@ const Main = ({ toplevel, timeZoneName, Frame }: Props) => {
|
||||
</IconButton>
|
||||
}
|
||||
>
|
||||
<div className={classes.root}>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
margin: theme.spacing(2),
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
className={classes.selectors}
|
||||
sx={{ display: showSelectors ? "block" : "none" }}
|
||||
sx={{
|
||||
display: showSelectors ? "block" : "none",
|
||||
width: "max-content",
|
||||
"& .MuiCard-root": {
|
||||
marginRight: theme.spacing(2),
|
||||
marginBottom: theme.spacing(2),
|
||||
},
|
||||
}}
|
||||
>
|
||||
<StreamMultiSelector
|
||||
toplevel={toplevel}
|
||||
@@ -331,7 +316,22 @@ const Main = ({ toplevel, timeZoneName, Frame }: Props) => {
|
||||
</Box>
|
||||
{videoLists.length > 0 && recordingsTable}
|
||||
{activeRecording != null && (
|
||||
<Modal open onClose={closeModal} className={classes.videoModal}>
|
||||
<Modal
|
||||
open
|
||||
onClose={closeModal}
|
||||
sx={{
|
||||
// Make the content as large as possible without distorting it.
|
||||
// Center it in the screen and ensure that the video element only
|
||||
// takes up the space actually used by the content, so that clicking
|
||||
// outside it will dismiss the modal.
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
"& video": {
|
||||
objectFit: "fill",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<FullScreenVideo
|
||||
src={api.recordingUrl(
|
||||
activeRecording[0].camera.uuid,
|
||||
@@ -347,7 +347,7 @@ const Main = ({ toplevel, timeZoneName, Frame }: Props) => {
|
||||
/>
|
||||
</Modal>
|
||||
)}
|
||||
</div>
|
||||
</Box>
|
||||
</Frame>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user