11/*
2- Floating ESC telemetry widget (same positioning + UI pattern as VideoWidget)
2+ Floating ESC telemetry widget (row-positioned like VideoWidget)
33*/
44import { useMemo , useState } from "react"
55import { ActionIcon , Text } from "@mantine/core"
6- import {
7- IconBolt ,
8- IconMaximize ,
9- IconMinus ,
10- IconResize ,
11- } from "@tabler/icons-react"
6+ import { IconBolt , IconMaximize , IconMinus , IconResize } from "@tabler/icons-react"
127import { useSelector } from "react-redux"
138import GetOutsideVisibilityColor from "../../helpers/outsideVisibility"
149import { selectEscTelemetry } from "../../redux/slices/droneInfoSlice"
@@ -32,12 +27,7 @@ function EscTile({ esc }) {
3227 return (
3328 < div className = "rounded-md border border-falcongrey-700 bg-falcongrey-900 p-2" >
3429 < div className = "flex flex-row items-center justify-between mb-1" >
35- < div className = "text-slate-200 text-xs font-semibold" >
36- ESC { esc . escId }
37- </ div >
38- < div className = "text-slate-500 text-[10px]" >
39- { esc . timestamp ? new Date ( esc . timestamp ) . toLocaleTimeString ( ) : "—" }
40- </ div >
30+ < div className = "text-slate-200 text-xs font-semibold" > ESC { esc . escId } </ div >
4131 </ div >
4232
4333 < div className = "flex flex-col gap-y-0.5" >
@@ -49,10 +39,6 @@ function EscTile({ esc }) {
4939 < div className = "text-slate-500 text-[10px]" > A</ div >
5040 < div className = "text-slate-200 text-xs" > { fmt ( esc . current , 2 ) } </ div >
5141 </ div >
52- < div className = "flex flex-row items-center justify-between" >
53- < div className = "text-slate-500 text-[10px]" > V</ div >
54- < div className = "text-slate-200 text-xs" > { fmt ( esc . voltage , 2 ) } </ div >
55- </ div >
5642 < div className = "flex flex-row items-center justify-between" >
5743 < div className = "text-slate-500 text-[10px]" > °C</ div >
5844 < div className = "text-slate-200 text-xs" > { fmtTemp ( esc . temperature ) } </ div >
@@ -62,31 +48,54 @@ function EscTile({ esc }) {
6248 )
6349}
6450
65- export default function EscTelemetryWidget ( { telemetryPanelWidth } ) {
66- const escs = useSelector ( selectEscTelemetry )
51+ export default function EscTelemetryWidget ( {
52+ telemetryPanelWidth, // unused now, kept so your callsites don’t break
53+ onMaximizedChange,
54+ } ) {
55+ //const escs = useSelector(selectEscTelemetry)
56+ const realEscs = useSelector ( selectEscTelemetry )
57+
58+ const escs = Array . from ( { length : 8 } ) . map ( ( _ , i ) => ( {
59+ escId : i + 1 ,
60+ rpm : Math . floor ( Math . random ( ) * 6000 ) ,
61+ current : ( Math . random ( ) * 20 ) . toFixed ( 2 ) ,
62+ temperature : Math . floor ( 30 + Math . random ( ) * 20 )
63+ } ) )
6764
6865 const [ isMaximized , setIsMaximized ] = useState ( false )
6966 const [ scale , setScale ] = useState ( 1 )
7067
71- const dimensions = useMemo ( ( ) => {
72- const baseWidth = 350
73- const width = baseWidth * scale
74- // make it a bit taller than video default so 2 rows of tiles fit nicely
75- const height = Math . round ( ( 197 * 1.15 ) * scale )
76- return { width, height }
77- } , [ scale ] )
68+ const setMaximized = ( next ) => {
69+ setIsMaximized ( next )
70+ onMaximizedChange ?. ( next )
71+ }
7872
7973 const hasAnyData =
8074 Array . isArray ( escs ) &&
8175 escs . some (
8276 ( e ) =>
8377 e &&
84- ( e . rpm != null ||
85- e . current != null ||
86- e . voltage != null ||
87- e . temperature != null ) ,
78+ ( e . rpm != null || e . current != null || e . temperature != null ) ,
8879 )
8980
81+ const dimensions = useMemo ( ( ) => {
82+ const baseWidth = 350
83+ const width = baseWidth * scale
84+
85+ const cols = 4
86+ const count = Array . isArray ( escs ) ? escs . length : 0
87+ const rows = Math . max ( 1 , Math . ceil ( count / cols ) )
88+
89+ const tileH = 74 * scale
90+ const gapH = 8 * scale
91+ const paddingH = 32 * scale
92+
93+ const height = Math . round ( rows * tileH + ( rows - 1 ) * gapH + paddingH )
94+ const clampedHeight = Math . max ( 180 * scale , Math . min ( 420 * scale , height ) )
95+
96+ return { width, height : clampedHeight }
97+ } , [ scale , escs ] )
98+
9099 function handleResizeStart ( e ) {
91100 const startX = e . clientX
92101 const startScale = scale
@@ -111,17 +120,23 @@ export default function EscTelemetryWidget({ telemetryPanelWidth }) {
111120 // Minimized view
112121 if ( ! isMaximized ) {
113122 return (
114- < div className = "rounded-md" style = { { background : GetOutsideVisibilityColor ( ) } } >
123+ < div
124+ className = "rounded-md"
125+ style = { { background : GetOutsideVisibilityColor ( ) } }
126+ >
115127 < div className = "p-2 flex items-center gap-2" >
116- < IconBolt size = { 16 } className = { hasAnyData ? "text-slate-200" : "text-slate-500" } />
128+ < IconBolt
129+ size = { 16 }
130+ className = { hasAnyData ? "text-slate-200" : "text-slate-500" }
131+ />
117132 < Text size = "sm" className = "truncate max-w-[150px]" >
118133 { hasAnyData ? "ESC telemetry" : "No ESC telemetry" }
119134 </ Text >
120135
121136 < ActionIcon
122137 size = "sm"
123138 variant = "subtle"
124- onClick = { ( ) => setIsMaximized ( true ) }
139+ onClick = { ( ) => setMaximized ( true ) }
125140 className = "text-slate-400 hover:text-slate-200"
126141 title = "Maximize ESC widget"
127142 >
@@ -132,21 +147,18 @@ export default function EscTelemetryWidget({ telemetryPanelWidth }) {
132147 )
133148 }
134149
135- // Full view
150+ // Full view (make it stretch nicely when parent uses items-stretch)
136151 return (
137- < div
138- className = "min-w-[350px] rounded-md"
139- style = { { background : GetOutsideVisibilityColor ( ) } }
140- >
141- < div className = "p-2" >
152+ < div className = "min-w-[350px] min-h-[225px] rounded-md flex flex-col" style = { { background : GetOutsideVisibilityColor ( ) } } >
153+ < div className = "p-2 h-full flex flex-col" >
142154 < div className = "flex items-center justify-between mb-2" >
143155 < Text > ESC telemetry</ Text >
144156
145157 < div className = "flex items-center gap-1" >
146158 < ActionIcon
147159 size = "sm"
148160 variant = "subtle"
149- onClick = { ( ) => setIsMaximized ( false ) }
161+ onClick = { ( ) => setMaximized ( false ) }
150162 className = "text-slate-400 hover:text-slate-200"
151163 title = "Minimize ESC widget"
152164 >
@@ -166,7 +178,7 @@ export default function EscTelemetryWidget({ telemetryPanelWidth }) {
166178 </ div >
167179
168180 < div
169- className = "rounded overflow-hidden mx-auto"
181+ className = "rounded overflow-hidden mx-auto flex-1 "
170182 style = { {
171183 width : `${ dimensions . width } px` ,
172184 height : `${ dimensions . height } px` ,
0 commit comments