mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-05 18:55:23 +03:00
ViewMode renamed to UserView in code
This commit is contained in:
parent
889a629a9e
commit
97a5363c84
@ -8,16 +8,16 @@ import DarkModeIcon from './icons/DarkMode';
|
|||||||
import SettingsIcon from './icons/Settings';
|
import SettingsIcon from './icons/Settings';
|
||||||
import FrigateRestartIcon from './icons/FrigateRestart';
|
import FrigateRestartIcon from './icons/FrigateRestart';
|
||||||
import Prompt from './components/Prompt';
|
import Prompt from './components/Prompt';
|
||||||
import { useDarkMode, useViewMode } from './context';
|
import { useDarkMode, useUserView } from './context';
|
||||||
import { useCallback, useRef, useState } from 'preact/hooks';
|
import { useCallback, useRef, useState } from 'preact/hooks';
|
||||||
import { useRestart } from './api/ws';
|
import { useRestart } from './api/ws';
|
||||||
import { ViewModeTypes } from './components/ViewOptionEnum'
|
import { UserViewTypes } from './context/UserViewTypes'
|
||||||
|
|
||||||
export default function AppBar() {
|
export default function AppBar() {
|
||||||
const [showMoreMenu, setShowMoreMenu] = useState(false);
|
const [showMoreMenu, setShowMoreMenu] = useState(false);
|
||||||
const [showDialog, setShowDialog] = useState(false);
|
const [showDialog, setShowDialog] = useState(false);
|
||||||
const [showDialogWait, setShowDialogWait] = useState(false);
|
const [showDialogWait, setShowDialogWait] = useState(false);
|
||||||
const { currentViewMode, setViewMode } = useViewMode();
|
const { currentUserView, setUserView } = useUserView();
|
||||||
const { setDarkMode } = useDarkMode();
|
const { setDarkMode } = useDarkMode();
|
||||||
const { send: sendRestart } = useRestart();
|
const { send: sendRestart } = useRestart();
|
||||||
|
|
||||||
@ -29,12 +29,12 @@ export default function AppBar() {
|
|||||||
[setDarkMode, setShowMoreMenu]
|
[setDarkMode, setShowMoreMenu]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSetViewMode = useCallback(
|
const handleSetUserView = useCallback(
|
||||||
(value) => {
|
(value) => {
|
||||||
setViewMode(value);
|
setUserView(value);
|
||||||
setShowMoreMenu(false);
|
setShowMoreMenu(false);
|
||||||
},
|
},
|
||||||
[setViewMode, setShowMoreMenu]
|
[setUserView, setShowMoreMenu]
|
||||||
);
|
);
|
||||||
|
|
||||||
const moreRef = useRef(null);
|
const moreRef = useRef(null);
|
||||||
@ -75,10 +75,10 @@ export default function AppBar() {
|
|||||||
<MenuItem icon={SettingsIcon} label="Viewmode:">
|
<MenuItem icon={SettingsIcon} label="Viewmode:">
|
||||||
<select
|
<select
|
||||||
className="py-0.5 pr-8"
|
className="py-0.5 pr-8"
|
||||||
value={currentViewMode}
|
value={currentUserView}
|
||||||
onChange={(e) => handleSetViewMode(e.target.value)}
|
onChange={(e) => handleSetUserView(e.target.value)}
|
||||||
>
|
>
|
||||||
{ Object.keys(ViewModeTypes).filter((v) => !isNaN(Number(v))).map(key => <option key={key} value={key}>{ViewModeTypes[key]}</option>) }
|
{ Object.keys(UserViewTypes).filter((v) => !isNaN(Number(v))).map(key => <option key={key} value={key}>{UserViewTypes[key]}</option>) }
|
||||||
</select>
|
</select>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuSeparator />
|
<MenuSeparator />
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { Match } from 'preact-router/match';
|
|||||||
import { memo } from 'preact/compat';
|
import { memo } from 'preact/compat';
|
||||||
import { ENV } from './env';
|
import { ENV } from './env';
|
||||||
import { useMemo } from 'preact/hooks'
|
import { useMemo } from 'preact/hooks'
|
||||||
import ViewOption from './components/ViewOption'
|
import UserViewer from './components/UserViewer'
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import NavigationDrawer, { Destination, Separator } from './components/NavigationDrawer';
|
import NavigationDrawer, { Destination, Separator } from './components/NavigationDrawer';
|
||||||
|
|
||||||
@ -47,17 +47,17 @@ export default function Sidebar() {
|
|||||||
<Destination href="/events" text="Events" />
|
<Destination href="/events" text="Events" />
|
||||||
<Destination href="/exports" text="Exports" />
|
<Destination href="/exports" text="Exports" />
|
||||||
<Separator />
|
<Separator />
|
||||||
<ViewOption requiredmode="advanced">
|
<UserViewer requiredmode="advanced">
|
||||||
<Destination href="/storage" text="Storage" />
|
<Destination href="/storage" text="Storage" />
|
||||||
<Destination href="/system" text="System" />
|
<Destination href="/system" text="System" />
|
||||||
</ViewOption>
|
</UserViewer>
|
||||||
<ViewOption requiredmode="admin">
|
<UserViewer requiredmode="admin">
|
||||||
<Destination href="/config" text="Config" />
|
<Destination href="/config" text="Config" />
|
||||||
</ViewOption>
|
</UserViewer>
|
||||||
<ViewOption requiredmode="advanced">
|
<UserViewer requiredmode="advanced">
|
||||||
<Destination href="/logs" text="Logs" />
|
<Destination href="/logs" text="Logs" />
|
||||||
<Separator />
|
<Separator />
|
||||||
</ViewOption>
|
</UserViewer>
|
||||||
<div className="flex flex-grow" />
|
<div className="flex flex-grow" />
|
||||||
{ENV !== 'production' ? (
|
{ENV !== 'production' ? (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import AppBar from './AppBar';
|
|||||||
import Cameras from './routes/Cameras';
|
import Cameras from './routes/Cameras';
|
||||||
import { Router } from 'preact-router';
|
import { Router } from 'preact-router';
|
||||||
import Sidebar from './Sidebar';
|
import Sidebar from './Sidebar';
|
||||||
import { DarkModeProvider, DrawerProvider, ViewModeProvider } from './context';
|
import { DarkModeProvider, DrawerProvider, UserViewProvider } from './context';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
@ -16,7 +16,7 @@ export default function App() {
|
|||||||
return (
|
return (
|
||||||
<DarkModeProvider>
|
<DarkModeProvider>
|
||||||
<DrawerProvider>
|
<DrawerProvider>
|
||||||
<ViewModeProvider config={config}>
|
<UserViewProvider config={config}>
|
||||||
<div data-testid="app" className="w-full">
|
<div data-testid="app" className="w-full">
|
||||||
<AppBar />
|
<AppBar />
|
||||||
{!config ? (
|
{!config ? (
|
||||||
@ -48,7 +48,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</ViewModeProvider>
|
</UserViewProvider>
|
||||||
</DrawerProvider>
|
</DrawerProvider>
|
||||||
</DarkModeProvider>
|
</DarkModeProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
12
web/src/components/UserViewer.jsx
Normal file
12
web/src/components/UserViewer.jsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { h } from 'preact';
|
||||||
|
import { useUserView } from '../context';
|
||||||
|
import { UserViewTypes } from '../context/UserViewTypes';
|
||||||
|
|
||||||
|
export default function UserViewer({children, requiredmode }) {
|
||||||
|
const { currentUserView } = useUserView();
|
||||||
|
|
||||||
|
return currentUserView >= UserViewTypes[requiredmode] ? (
|
||||||
|
<>{children}</>
|
||||||
|
|
||||||
|
) : null;
|
||||||
|
}
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import { h } from 'preact';
|
|
||||||
import { useViewMode } from '../context';
|
|
||||||
import { ViewModeTypes } from './ViewOptionEnum';
|
|
||||||
|
|
||||||
export default function ViewOption({children, requiredmode }) {
|
|
||||||
const { currentViewMode } = useViewMode();
|
|
||||||
|
|
||||||
return currentViewMode >= ViewModeTypes[requiredmode] ? (
|
|
||||||
<>{children}</>
|
|
||||||
|
|
||||||
) : null;
|
|
||||||
}
|
|
||||||
@ -1,27 +1,27 @@
|
|||||||
import { h } from 'preact';
|
import { h } from 'preact';
|
||||||
import { render, screen, waitFor } from '@testing-library/preact';
|
import { render, screen, waitFor } from '@testing-library/preact';
|
||||||
import { set as setData } from 'idb-keyval';
|
import { set as setData } from 'idb-keyval';
|
||||||
import ViewOption from '../ViewOption';
|
import UserViewer from '../UserViewer';
|
||||||
import { ViewModeProvider } from '../../context';
|
import { UserViewProvider } from '../../context';
|
||||||
import { ViewModeTypes } from '../ViewOptionEnum';
|
import { UserViewTypes } from '../../context/UserViewTypes';
|
||||||
import * as WS from '../../api/ws';
|
import * as WS from '../../api/ws';
|
||||||
|
|
||||||
describe('ViewOption', () => {
|
describe('UserViewer', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.spyOn(WS, 'WsProvider').mockImplementation(({ children }) => children);
|
vi.spyOn(WS, 'WsProvider').mockImplementation(({ children }) => children);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('make sure children are visible with same modes', async () => {
|
test('make sure children are visible with same modes', async () => {
|
||||||
const maxViewMode = (Object.keys(ViewModeTypes).filter(isNaN).length-1);
|
const maxViewMode = (Object.keys(UserViewTypes).filter(isNaN).length-1);
|
||||||
const maxViewModeHR = ViewModeTypes[maxViewMode];
|
const maxViewModeHR = UserViewTypes[maxViewMode];
|
||||||
setData('view-mode', maxViewMode);
|
setData('view-mode', maxViewMode);
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<ViewModeProvider>
|
<UserViewProvider>
|
||||||
<ViewOption requiredmode={maxViewModeHR}>
|
<UserViewer requiredmode={maxViewModeHR}>
|
||||||
<div data-testid='children'>stuff</div>
|
<div data-testid='children'>stuff</div>
|
||||||
</ViewOption>
|
</UserViewer>
|
||||||
</ViewModeProvider>
|
</UserViewProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
const el = await screen.findByTestId('children');
|
const el = await screen.findByTestId('children');
|
||||||
@ -29,16 +29,16 @@ describe('ViewOption', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('make sure children are visible with max viewmode, and a small requiredmode', async () => {
|
test('make sure children are visible with max viewmode, and a small requiredmode', async () => {
|
||||||
const maxViewMode = (Object.keys(ViewModeTypes).filter(isNaN).length-1);
|
const maxViewMode = (Object.keys(UserViewTypes).filter(isNaN).length-1);
|
||||||
const lowViewModeHR = ViewModeTypes[1];
|
const lowViewModeHR = UserViewTypes[1];
|
||||||
setData('view-mode', maxViewMode);
|
setData('view-mode', maxViewMode);
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<ViewModeProvider>
|
<UserViewProvider>
|
||||||
<ViewOption requiredmode={lowViewModeHR}>
|
<UserViewer requiredmode={lowViewModeHR}>
|
||||||
<div data-testid='children'>stuff</div>
|
<div data-testid='children'>stuff</div>
|
||||||
</ViewOption>
|
</UserViewer>
|
||||||
</ViewModeProvider>
|
</UserViewProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
const el = await screen.findByTestId('children');
|
const el = await screen.findByTestId('children');
|
||||||
@ -46,17 +46,17 @@ describe('ViewOption', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('make sure children are hidden, due to failed requiredmode', async () => {
|
test('make sure children are hidden, due to failed requiredmode', async () => {
|
||||||
const maxViewMode = (Object.keys(ViewModeTypes).filter(isNaN).length-1);
|
const maxViewMode = (Object.keys(UserViewTypes).filter(isNaN).length-1);
|
||||||
const maxViewModeHR = ViewModeTypes[maxViewMode];
|
const maxViewModeHR = UserViewTypes[maxViewMode];
|
||||||
setData('view-mode', '0');
|
setData('view-mode', '0');
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<ViewModeProvider>
|
<UserViewProvider>
|
||||||
<ViewOption requiredmode={maxViewModeHR}>
|
<UserViewer requiredmode={maxViewModeHR}>
|
||||||
<div data-testid='children'>stuff</div>
|
<div data-testid='children'>stuff</div>
|
||||||
</ViewOption>
|
</UserViewer>
|
||||||
<div>bugfix</div>
|
<div>bugfix</div>
|
||||||
</ViewModeProvider>
|
</UserViewProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
//without this, the test will always pass, even if setData('view-mode', '2') ... really strange behavior
|
//without this, the test will always pass, even if setData('view-mode', '2') ... really strange behavior
|
||||||
@ -1,5 +1,5 @@
|
|||||||
export enum ViewModeTypes {
|
export enum UserViewTypes {
|
||||||
"user",
|
"user",
|
||||||
"advanced",
|
"advanced",
|
||||||
"admin",
|
"admin",
|
||||||
}
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { h } from 'preact';
|
import { h } from 'preact';
|
||||||
import { set as setData, get as getData } from 'idb-keyval';
|
import { set as setData, get as getData } from 'idb-keyval';
|
||||||
import { DarkModeProvider, useDarkMode, usePersistence, ViewModeProvider, useViewMode } from '..';
|
import { DarkModeProvider, useDarkMode, usePersistence, UserViewProvider, useUserView } from '..';
|
||||||
import { ViewModeTypes } from '../../components/ViewOptionEnum'
|
import { UserViewTypes } from '../../context/UserViewTypes'
|
||||||
import { fireEvent, render, screen } from 'testing-library';
|
import { fireEvent, render, screen } from 'testing-library';
|
||||||
import { useCallback } from 'preact/hooks';
|
import { useCallback } from 'preact/hooks';
|
||||||
import * as WS from '../../api/ws';
|
import * as WS from '../../api/ws';
|
||||||
@ -197,9 +197,9 @@ describe('usePersistence', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function ViewModeChecker() {
|
function UserViewChecker() {
|
||||||
const { currentViewMode } = useViewMode();
|
const { currentUserView } = useUserView();
|
||||||
return <div data-testid={currentViewMode}>{currentViewMode}</div>;
|
return <div data-testid={currentUserView}>{currentUserView}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('ViewMode', () => {
|
describe('ViewMode', () => {
|
||||||
@ -211,24 +211,24 @@ describe('ViewMode', () => {
|
|||||||
setData('view-mode', null);
|
setData('view-mode', null);
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<ViewModeProvider>
|
<UserViewProvider>
|
||||||
<ViewModeChecker />
|
<UserViewChecker />
|
||||||
</ViewModeProvider>
|
</UserViewProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
const maxViewMode = (Object.keys(ViewModeTypes).filter(isNaN).length-1);
|
const maxViewMode = (Object.keys(UserViewTypes).filter(isNaN).length-1);
|
||||||
const el = await screen.findByTestId(maxViewMode);
|
const el = await screen.findByTestId(maxViewMode);
|
||||||
expect(el).toBeInTheDocument();
|
expect(el).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.keys(ViewModeTypes).filter((v) => !isNaN(Number(v))).map(key =>
|
Object.keys(UserViewTypes).filter((v) => !isNaN(Number(v))).map(key =>
|
||||||
test(`uses a viewmode option that is stored in idb - ${ViewModeTypes[key]}`, async () => {
|
test(`uses a viewmode option that is stored in idb - ${UserViewTypes[key]}`, async () => {
|
||||||
setData('view-mode', key);
|
setData('view-mode', key);
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<ViewModeProvider>
|
<UserViewProvider>
|
||||||
<ViewModeChecker />
|
<UserViewChecker />
|
||||||
</ViewModeProvider>
|
</UserViewProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
const el = await screen.findByTestId(key);
|
const el = await screen.findByTestId(key);
|
||||||
@ -236,26 +236,26 @@ describe('ViewMode', () => {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
test('update viewmode live, using setViewMode from context and verify idb save', async () => {
|
test('update viewmode live, using setUserView from context and verify idb save', async () => {
|
||||||
setData('view-mode', null);
|
setData('view-mode', null);
|
||||||
|
|
||||||
function Updater() {
|
function Updater() {
|
||||||
const { setViewMode } = useViewMode();
|
const { setUserView } = useUserView();
|
||||||
const handleClick = useCallback((value) => {
|
const handleClick = useCallback((value) => {
|
||||||
setViewMode(value.button.toString());
|
setUserView(value.button.toString());
|
||||||
}, [setViewMode]);
|
}, [setUserView]);
|
||||||
return <div onClick={handleClick}>click me</div>;
|
return <div onClick={handleClick}>click me</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<ViewModeProvider>
|
<UserViewProvider>
|
||||||
<ViewModeChecker />
|
<UserViewChecker />
|
||||||
<Updater />
|
<Updater />
|
||||||
</ViewModeProvider>
|
</UserViewProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
const button = await screen.findByText('click me');
|
const button = await screen.findByText('click me');
|
||||||
const maxViewMode = (Object.keys(ViewModeTypes).filter(isNaN).length-1);
|
const maxViewMode = (Object.keys(UserViewTypes).filter(isNaN).length-1);
|
||||||
|
|
||||||
fireEvent.click(button, {button: '0'});
|
fireEvent.click(button, {button: '0'});
|
||||||
const minmode = await screen.findByTestId('0');
|
const minmode = await screen.findByTestId('0');
|
||||||
|
|||||||
@ -1,19 +1,19 @@
|
|||||||
import { h, createContext } from 'preact';
|
import { h, createContext } from 'preact';
|
||||||
import { get as getData, set as setData } from 'idb-keyval';
|
import { get as getData, set as setData } from 'idb-keyval';
|
||||||
import { useCallback, useContext, useEffect, useLayoutEffect, useState } from 'preact/hooks';
|
import { useCallback, useContext, useEffect, useLayoutEffect, useState } from 'preact/hooks';
|
||||||
import { ViewModeTypes } from '../components/ViewOptionEnum';
|
import { UserViewTypes } from './UserViewTypes';
|
||||||
|
|
||||||
const ViewMode = createContext("");
|
const UserView = createContext("");
|
||||||
|
|
||||||
export function ViewModeProvider({ children, config }) {
|
export function UserViewProvider({ children, config }) {
|
||||||
const [currentViewMode, setCurrentViewMode] = useState(null);
|
const [currentUserView, setCurrentUserView] = useState(null);
|
||||||
|
|
||||||
const setViewMode = useCallback(
|
const setUserView = useCallback(
|
||||||
(value) => {
|
(value) => {
|
||||||
setData('view-mode', value);
|
setData('view-mode', value);
|
||||||
setCurrentViewMode(value);
|
setCurrentUserView(value);
|
||||||
},
|
},
|
||||||
[setCurrentViewMode]
|
[setCurrentUserView]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -21,25 +21,25 @@ export function ViewModeProvider({ children, config }) {
|
|||||||
let viewmode = await getData('view-mode');
|
let viewmode = await getData('view-mode');
|
||||||
|
|
||||||
if(viewmode == null) {
|
if(viewmode == null) {
|
||||||
const maxViewMode = (Object.keys(ViewModeTypes).filter(isNaN).length-1).toString();
|
const maxViewMode = (Object.keys(UserViewTypes).filter(isNaN).length-1).toString();
|
||||||
const configValue = config ? ViewModeTypes[config.ui.viewmode].toString() : maxViewMode;
|
const configValue = config ? UserViewTypes[config.ui.viewmode].toString() : maxViewMode;
|
||||||
viewmode = configValue;
|
viewmode = configValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
setViewMode(viewmode);
|
setUserView(viewmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
load();
|
load();
|
||||||
}, [config, setViewMode]);
|
}, [config, setUserView]);
|
||||||
|
|
||||||
|
|
||||||
return !currentViewMode ? null : (
|
return !currentUserView ? null : (
|
||||||
<ViewMode.Provider value={{ currentViewMode, setViewMode }}>{children}</ViewMode.Provider>
|
<UserView.Provider value={{ currentUserView, setUserView }}>{children}</UserView.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useViewMode() {
|
export function useUserView() {
|
||||||
return useContext(ViewMode);
|
return useContext(UserView);
|
||||||
}
|
}
|
||||||
|
|
||||||
const DarkMode = createContext(null);
|
const DarkMode = createContext(null);
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import WebRtcPlayer from '../components/WebRtcPlayer';
|
|||||||
import '../components/MsePlayer';
|
import '../components/MsePlayer';
|
||||||
import CameraControlPanel from '../components/CameraControlPanel';
|
import CameraControlPanel from '../components/CameraControlPanel';
|
||||||
import { baseUrl } from '../api/baseUrl';
|
import { baseUrl } from '../api/baseUrl';
|
||||||
import ViewOption from '../components/ViewOption'
|
import UserViewer from '../components/UserViewer'
|
||||||
|
|
||||||
const emptyObject = Object.freeze({});
|
const emptyObject = Object.freeze({});
|
||||||
|
|
||||||
@ -110,9 +110,9 @@ export default function Camera({ camera }) {
|
|||||||
label="Regions"
|
label="Regions"
|
||||||
labelPosition="after"
|
labelPosition="after"
|
||||||
/>
|
/>
|
||||||
<ViewOption requiredmode="admin">
|
<UserViewer requiredmode="admin">
|
||||||
<Link href={`/cameras/${camera}/editor`}>Mask & Zone creator</Link>
|
<Link href={`/cameras/${camera}/editor`}>Mask & Zone creator</Link>
|
||||||
</ViewOption>
|
</UserViewer>
|
||||||
</div>
|
</div>
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
|
|||||||
@ -8,8 +8,8 @@ import MotionIcon from '../icons/Motion';
|
|||||||
import SnapshotIcon from '../icons/Snapshot';
|
import SnapshotIcon from '../icons/Snapshot';
|
||||||
import { useAudioState, useDetectState, useRecordingsState, useSnapshotsState } from '../api/ws';
|
import { useAudioState, useDetectState, useRecordingsState, useSnapshotsState } from '../api/ws';
|
||||||
import { useMemo } from 'preact/hooks';
|
import { useMemo } from 'preact/hooks';
|
||||||
import { useViewMode } from '../context'
|
import { useUserView } from '../context'
|
||||||
import { ViewModeTypes } from '../components/ViewOptionEnum';
|
import { UserViewTypes } from '../context/UserViewTypes';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
|
|
||||||
export default function Cameras() {
|
export default function Cameras() {
|
||||||
@ -101,14 +101,14 @@ function Camera({ name, config }) {
|
|||||||
[config, audioValue, sendAudio, detectValue, sendDetect, recordValue, sendRecordings, snapshotValue, sendSnapshots]
|
[config, audioValue, sendAudio, detectValue, sendDetect, recordValue, sendRecordings, snapshotValue, sendSnapshots]
|
||||||
);
|
);
|
||||||
|
|
||||||
const { currentViewMode } = useViewMode();
|
const { currentUserView } = useUserView();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
buttons={buttons}
|
buttons={buttons}
|
||||||
href={href}
|
href={href}
|
||||||
header={cleanName}
|
header={cleanName}
|
||||||
icons={!currentViewMode || currentViewMode >= ViewModeTypes["admin"] ? icons : []}
|
icons={!currentUserView || currentUserView >= UserViewTypes["admin"] ? icons : []}
|
||||||
media={<CameraImage camera={name} stretch />}
|
media={<CameraImage camera={name} stretch />}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -30,7 +30,7 @@ import TimeAgo from '../components/TimeAgo';
|
|||||||
import Timepicker from '../components/TimePicker';
|
import Timepicker from '../components/TimePicker';
|
||||||
import TimelineSummary from '../components/TimelineSummary';
|
import TimelineSummary from '../components/TimelineSummary';
|
||||||
import TimelineEventOverlay from '../components/TimelineEventOverlay';
|
import TimelineEventOverlay from '../components/TimelineEventOverlay';
|
||||||
import ViewOption from '../components/ViewOption';
|
import UserViewer from '../components/UserViewer';
|
||||||
|
|
||||||
const API_LIMIT = 25;
|
const API_LIMIT = 25;
|
||||||
|
|
||||||
@ -658,13 +658,13 @@ export default function Events({ path, ...props }) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<ViewOption requiredmode="admin">
|
<UserViewer requiredmode="admin">
|
||||||
<Delete
|
<Delete
|
||||||
className="h-6 w-6 cursor-pointer"
|
className="h-6 w-6 cursor-pointer"
|
||||||
stroke="#f87171"
|
stroke="#f87171"
|
||||||
onClick={(e) => onDelete(e, event.id, event.retain_indefinitely)}
|
onClick={(e) => onDelete(e, event.id, event.retain_indefinitely)}
|
||||||
/>
|
/>
|
||||||
</ViewOption>
|
</UserViewer>
|
||||||
|
|
||||||
<Download
|
<Download
|
||||||
className="h-6 w-6 mt-auto"
|
className="h-6 w-6 mt-auto"
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import Dialog from '../components/Dialog';
|
|||||||
import TimeAgo from '../components/TimeAgo';
|
import TimeAgo from '../components/TimeAgo';
|
||||||
import copy from 'copy-to-clipboard';
|
import copy from 'copy-to-clipboard';
|
||||||
import { About } from '../icons/About';
|
import { About } from '../icons/About';
|
||||||
import ViewOption from '../components/ViewOption';
|
import UserViewer from '../components/UserViewer';
|
||||||
|
|
||||||
const emptyObject = Object.freeze({});
|
const emptyObject = Object.freeze({});
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ export default function System() {
|
|||||||
{config && (
|
{config && (
|
||||||
<span class="p-1">
|
<span class="p-1">
|
||||||
go2rtc {go2rtc && `${go2rtc.version} `}
|
go2rtc {go2rtc && `${go2rtc.version} `}
|
||||||
<ViewOption requiredmode="admin">
|
<UserViewer requiredmode="admin">
|
||||||
<Link
|
<Link
|
||||||
className="text-blue-500 hover:underline"
|
className="text-blue-500 hover:underline"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@ -108,7 +108,7 @@ export default function System() {
|
|||||||
>
|
>
|
||||||
dashboard
|
dashboard
|
||||||
</Link>
|
</Link>
|
||||||
</ViewOption>
|
</UserViewer>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user