mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-26 19:06:11 +01:00
UI tweaks (#14088)
* fix squashed alert thumbnails in filmstrip * add genai debug logs * consistent themed image loading indicator background color * improve image loading skeleton in object lifecycle pane * less rounding when screen is smaller * use browser back button to dismiss review pane * initial state
This commit is contained in:
parent
141cf39368
commit
fafe5623d1
@ -137,6 +137,9 @@ class EmbeddingMaintainer(threading.Thread):
|
||||
or set(event.zones) & set(camera_config.genai.required_zones)
|
||||
)
|
||||
):
|
||||
logger.debug(
|
||||
f"Description generation for {event}, has_snapshot: {event.has_snapshot}"
|
||||
)
|
||||
if event.has_snapshot and camera_config.genai.use_snapshot:
|
||||
with open(
|
||||
os.path.join(CLIPS_DIR, f"{event.camera}-{event.id}.jpg"),
|
||||
@ -276,7 +279,9 @@ class EmbeddingMaintainer(threading.Thread):
|
||||
metadata = get_metadata(event)
|
||||
thumbnail = base64.b64decode(event.thumbnail)
|
||||
|
||||
logger.debug(f"Using ${source} regeneration for ${event}")
|
||||
logger.debug(
|
||||
f"Trying {source} regeneration for {event}, has_snapshot: {event.has_snapshot}"
|
||||
)
|
||||
|
||||
if event.has_snapshot and source == "snapshot":
|
||||
with open(
|
||||
|
@ -107,7 +107,7 @@ export function AnimatedEventCard({
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<div
|
||||
className="relative h-24 4k:h-32"
|
||||
className="relative h-24 flex-shrink-0 4k:h-32"
|
||||
style={{
|
||||
aspectRatio: alertVideos ? aspectRatio : undefined,
|
||||
}}
|
||||
@ -145,7 +145,7 @@ export function AnimatedEventCard({
|
||||
>
|
||||
{!alertVideos ? (
|
||||
<img
|
||||
className="size-full select-none"
|
||||
className="max-h-full select-none"
|
||||
src={`${apiHost}${event.thumb_path.replace("/media/frigate/", "")}`}
|
||||
loading={isSafari ? "eager" : "lazy"}
|
||||
onLoad={() => setIsLoaded(true)}
|
||||
|
@ -14,7 +14,7 @@ export default function ImageLoadingIndicator({
|
||||
}
|
||||
|
||||
return isSafari ? (
|
||||
<div className={cn("pointer-events-none bg-gray-300", className)} />
|
||||
<div className={cn("pointer-events-none bg-background_alt", className)} />
|
||||
) : (
|
||||
<Skeleton className={cn("pointer-events-none", className)} />
|
||||
);
|
||||
|
@ -77,6 +77,17 @@ export default function ObjectLifecycle({
|
||||
const [showControls, setShowControls] = useState(false);
|
||||
const [showZones, setShowZones] = useState(true);
|
||||
|
||||
const aspectRatio = useMemo(() => {
|
||||
if (!config) {
|
||||
return 16 / 9;
|
||||
}
|
||||
|
||||
return (
|
||||
config.cameras[event.camera].detect.width /
|
||||
config.cameras[event.camera].detect.height
|
||||
);
|
||||
}, [config, event]);
|
||||
|
||||
const getZoneColor = useCallback(
|
||||
(zoneName: string) => {
|
||||
const zoneColor =
|
||||
@ -240,7 +251,15 @@ export default function ObjectLifecycle({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="relative flex flex-row justify-center">
|
||||
<div
|
||||
className={cn(
|
||||
"relative mx-auto flex max-h-[50dvh] flex-row justify-center",
|
||||
!imgLoaded && aspectRatio < 16 / 9 && "h-full",
|
||||
)}
|
||||
style={{
|
||||
aspectRatio: !imgLoaded ? aspectRatio : undefined,
|
||||
}}
|
||||
>
|
||||
<ImageLoadingIndicator
|
||||
className="absolute inset-0"
|
||||
imgLoaded={imgLoaded}
|
||||
@ -263,7 +282,7 @@ export default function ObjectLifecycle({
|
||||
key={event.id}
|
||||
ref={imgRef}
|
||||
className={cn(
|
||||
"max-h-[50dvh] max-w-full select-none rounded-lg object-contain transition-opacity",
|
||||
"max-h-[50dvh] max-w-full select-none rounded-lg object-contain",
|
||||
)}
|
||||
loading={isSafari ? "eager" : "lazy"}
|
||||
style={
|
||||
|
@ -37,6 +37,7 @@ import {
|
||||
MobilePageHeader,
|
||||
MobilePageTitle,
|
||||
} from "@/components/mobile/MobilePage";
|
||||
import { useOverlayState } from "@/hooks/use-overlay-state";
|
||||
|
||||
type ReviewDetailDialogProps = {
|
||||
review?: ReviewSegment;
|
||||
@ -83,10 +84,15 @@ export default function ReviewDetailDialog({
|
||||
|
||||
// dialog and mobile page
|
||||
|
||||
const [isOpen, setIsOpen] = useState(review != undefined);
|
||||
const [isOpen, setIsOpen] = useOverlayState(
|
||||
"reviewPane",
|
||||
review != undefined,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setIsOpen(review != undefined);
|
||||
// we know that these deps are correct
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [review]);
|
||||
|
||||
const Overlay = isDesktop ? Sheet : MobilePage;
|
||||
@ -102,7 +108,7 @@ export default function ReviewDetailDialog({
|
||||
return (
|
||||
<>
|
||||
<Overlay
|
||||
open={isOpen}
|
||||
open={isOpen ?? false}
|
||||
onOpenChange={(open) => {
|
||||
if (!open) {
|
||||
setReview(undefined);
|
||||
|
@ -200,7 +200,7 @@ function ExploreThumbnailImage({
|
||||
<img
|
||||
ref={imgRef}
|
||||
className={cn(
|
||||
"absolute h-full w-full cursor-pointer rounded-lg object-cover transition-all duration-300 ease-in-out md:rounded-2xl",
|
||||
"absolute h-full w-full cursor-pointer rounded-lg object-cover transition-all duration-300 ease-in-out lg:rounded-2xl",
|
||||
)}
|
||||
style={
|
||||
isIOS
|
||||
|
Loading…
Reference in New Issue
Block a user