This commit is contained in:
2026-08-17 23:55:16 +08:00
parent 224004365c
commit eaaa1c0049
+3 -6
View File
@@ -1,7 +1,7 @@
import MoreHorizIcon from "@mui/icons-material/MoreHoriz";
import RefreshIcon from "@mui/icons-material/Refresh";
import {Box,Button,Card,CardActions,CardContent,CardHeader,Chip,Stack,Typography} from "@mui/material";
import {useEffect,useRef,useState} from "react";
import {useEffect} from "react";
import type {Gallery_Case,Gallery_Dashboard,Gallery_Frame_Mode} from "../protocol/gallery_types";
import {use_plot_session} from "../hooks/use_plot_session";
import type {Gallery_Plot_Session} from "../session/gallery_plot_session";
@@ -13,12 +13,9 @@ import {Kernel_Observer_Summary} from "../plot/kernel_observer_summary";
export interface Selected_Plot {session:Gallery_Plot_Session;}
export function Plot_Card({gallery_case,frame_mode,frame_modes,dashboard,active,streams_paused,on_register,on_open_inspector}:{gallery_case:Gallery_Case;frame_mode:Gallery_Frame_Mode;frame_modes:Gallery_Frame_Mode[];dashboard:Gallery_Dashboard;active:boolean;streams_paused:boolean;on_register:(session:Gallery_Plot_Session,mount:boolean)=>void;on_open_inspector:(plot:Selected_Plot)=>void}) {
const [session,snapshot]=use_plot_session(gallery_case,frame_mode,frame_modes);
const card_ref=useRef<HTMLDivElement|null>(null);
const [in_viewport,set_in_viewport]=useState(false);
useEffect(()=>{on_register(session,true);return()=>on_register(session,false);},[session,on_register]);
useEffect(()=>{const element=card_ref.current;if(!element)return;const observer=new IntersectionObserver(entries=>set_in_viewport(Boolean(entries[0]?.isIntersecting)),{rootMargin:"320px 0px"});observer.observe(element);return()=>observer.disconnect();},[]);
useEffect(()=>session.set_activity(active&&in_viewport,streams_paused),[session,active,in_viewport,streams_paused]);
return <Card ref={card_ref} sx={{overflow:"hidden",display:"flex",flexDirection:"column",minWidth:0}} onContextMenu={event=>{event.preventDefault();if(snapshot.ready)on_open_inspector({session});}}>
useEffect(()=>session.set_activity(active,streams_paused),[session,active,streams_paused]);
return <Card sx={{overflow:"hidden",display:"flex",flexDirection:"column",minWidth:0}} onContextMenu={event=>{event.preventDefault();if(snapshot.ready)on_open_inspector({session});}}>
<CardHeader title={gallery_case.title} subheader={gallery_case.component} avatar={<Chip size="small" label={gallery_case.category}/>} action={<Plot_Status snapshot={snapshot} active={active&&!streams_paused}/>}/>
<Plot_Canvas session={session}/><Performance_Strip telemetry={snapshot.telemetry} dashboard={dashboard}/>{frame_mode.observer_visible&&<Kernel_Observer_Summary telemetry={snapshot.telemetry} dashboard={dashboard}/>}<CardContent sx={{flexGrow:1}}><Typography color="text.secondary">{gallery_case.description}</Typography>{snapshot.notice&&<Typography variant="caption" color="secondary.main">{snapshot.notice}</Typography>}</CardContent>
<CardActions sx={{justifyContent:"space-between",px:2,pb:2}}><Stack direction="row" spacing={2}><Typography variant="caption">{snapshot.controls.length} </Typography><Typography variant="caption">{snapshot.actions.length} </Typography><Typography variant="caption">{snapshot.frame_count} </Typography></Stack><Box>{session.frame_mode.id==="manual"&&<Button size="small" startIcon={<RefreshIcon/>} onClick={()=>session.request_frame(performance.now(),true)}>{session.frame_mode.frame_button_label}</Button>}<Button size="small" startIcon={<MoreHorizIcon/>} disabled={!snapshot.ready} onClick={()=>on_open_inspector({session})}></Button></Box></CardActions>