mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Show snapshots on events page (#3763)
* Add tabs to show snapshot or thumbnail as part of event details, even if event has a clip available. * Add ability for TextTab to render as disabled.
This commit is contained in:
parent
bdfe4a961a
commit
14faf0b2f6
@ -27,12 +27,14 @@ export function Tabs({ children, selectedIndex: selectedIndexProp, onChange, cla
|
||||
);
|
||||
}
|
||||
|
||||
export function TextTab({ selected, text, onClick }) {
|
||||
const selectedStyle = selected
|
||||
export function TextTab({ selected, text, onClick, disabled }) {
|
||||
const selectedStyle = disabled
|
||||
? 'text-gray-400 dark:text-gray-600 bg-transparent'
|
||||
: selected
|
||||
? 'text-white bg-blue-500 dark:text-black dark:bg-white'
|
||||
: 'text-black dark:text-white bg-transparent';
|
||||
return (
|
||||
<button onClick={onClick} className={`rounded-full px-4 py-2 ${selectedStyle}`}>
|
||||
<button onClick={onClick} disabled={disabled} className={`rounded-full px-4 py-2 ${selectedStyle}`}>
|
||||
<span>{text}</span>
|
||||
</button>
|
||||
);
|
||||
|
@ -2,6 +2,7 @@ import { h, Fragment } from 'preact';
|
||||
import { route } from 'preact-router';
|
||||
import ActivityIndicator from '../components/ActivityIndicator';
|
||||
import Heading from '../components/Heading';
|
||||
import { Tabs, TextTab } from '../components/Tabs';
|
||||
import { useApiHost } from '../api';
|
||||
import useSWR from 'swr';
|
||||
import useSWRInfinite from 'swr/infinite';
|
||||
@ -54,6 +55,7 @@ export default function Events({ path, ...props }) {
|
||||
});
|
||||
const [uploading, setUploading] = useState([]);
|
||||
const [viewEvent, setViewEvent] = useState();
|
||||
const [eventDetailType, setEventDetailType] = useState('clip');
|
||||
const [downloadEvent, setDownloadEvent] = useState({
|
||||
id: null,
|
||||
has_clip: false,
|
||||
@ -235,6 +237,10 @@ export default function Events({ path, ...props }) {
|
||||
}
|
||||
};
|
||||
|
||||
const handleEventDetailTabChange = (index) => {
|
||||
setEventDetailType(index == 0 ? 'clip' : 'image');
|
||||
};
|
||||
|
||||
if (!config) {
|
||||
return <ActivityIndicator />;
|
||||
}
|
||||
@ -495,9 +501,15 @@ export default function Events({ path, ...props }) {
|
||||
{viewEvent !== event.id ? null : (
|
||||
<div className="space-y-4">
|
||||
<div className="mx-auto max-w-7xl">
|
||||
{event.has_clip ? (
|
||||
<>
|
||||
<Heading size="lg">Clip</Heading>
|
||||
<div className='flex justify-center w-full py-2'>
|
||||
<Tabs selectedIndex={event.has_clip && eventDetailType == 'clip' ? 0 : 1} onChange={handleEventDetailTabChange} className='justify'>
|
||||
<TextTab text='Clip' disabled={!event.has_clip} />
|
||||
<TextTab text={event.has_snapshot ? 'Snapshot' : 'Thumbnail'} />
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{((eventDetailType == 'clip') && event.has_clip) ? (
|
||||
<VideoPlayer
|
||||
options={{
|
||||
preload: 'auto',
|
||||
@ -512,23 +524,22 @@ export default function Events({ path, ...props }) {
|
||||
seekOptions={{ forward: 10, back: 5 }}
|
||||
onReady={() => {}}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
) : null }
|
||||
|
||||
{((eventDetailType == 'image') || !event.has_clip) ? (
|
||||
<div className="flex justify-center">
|
||||
<div>
|
||||
<Heading size="sm">{event.has_snapshot ? 'Best Image' : 'Thumbnail'}</Heading>
|
||||
<img
|
||||
className="flex-grow-0"
|
||||
src={
|
||||
event.has_snapshot
|
||||
? `${apiHost}/api/events/${event.id}/snapshot.jpg`
|
||||
: `data:image/jpeg;base64,${event.thumbnail}`
|
||||
: `${apiHost}/api/events/${event.id}/thumbnail.jpg`
|
||||
}
|
||||
alt={`${event.label} at ${(event.top_score * 100).toFixed(0)}% confidence`}
|
||||
/>
|
||||
</div>
|
||||
) : null }
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
Loading…
Reference in New Issue
Block a user