mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 01:21:20 -04:00
feex
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -11,8 +11,8 @@
|
|||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
|
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
|
||||||
<title>Multi Roomba Rover</title>
|
<title>Multi Roomba Rover</title>
|
||||||
<script type="module" crossorigin src="/assets/index-f56Apeln.js"></script>
|
<script type="module" crossorigin src="/assets/index-MsCzfGxI.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-DMYOk2Xw.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-C97A4E-6.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@@ -220,7 +220,9 @@ function MiniSummaryContent() {
|
|||||||
const frames = useTelemetryFrames();
|
const frames = useTelemetryFrames();
|
||||||
const roster = session?.roster ?? [];
|
const roster = session?.roster ?? [];
|
||||||
const [index, setIndex] = useState(0);
|
const [index, setIndex] = useState(0);
|
||||||
const [prewarmRoverId, setPrewarmRoverId] = useState(null);
|
const [primaryRoverId, setPrimaryRoverId] = useState(null);
|
||||||
|
const [secondaryRoverId, setSecondaryRoverId] = useState(null);
|
||||||
|
const [visibleSlot, setVisibleSlot] = useState('primary');
|
||||||
const prewarmTimer = useRef(null);
|
const prewarmTimer = useRef(null);
|
||||||
const activeDrivers = session?.activeDrivers || {};
|
const activeDrivers = session?.activeDrivers || {};
|
||||||
const driverRoster = useMemo(
|
const driverRoster = useMemo(
|
||||||
@@ -281,6 +283,12 @@ function MiniSummaryContent() {
|
|||||||
setIndex(0);
|
setIndex(0);
|
||||||
}, [rotationKey]);
|
}, [rotationKey]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setPrimaryRoverId(rotationPool[0]?.rover?.id || null);
|
||||||
|
setSecondaryRoverId(null);
|
||||||
|
setVisibleSlot('primary');
|
||||||
|
}, [rotationKey, rotationPool]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!rotationPool.length) return undefined;
|
if (!rotationPool.length) return undefined;
|
||||||
const timer = setInterval(() => {
|
const timer = setInterval(() => {
|
||||||
@@ -289,37 +297,63 @@ function MiniSummaryContent() {
|
|||||||
return () => clearInterval(timer);
|
return () => clearInterval(timer);
|
||||||
}, [rotationPool.length, rotationKey]);
|
}, [rotationPool.length, rotationKey]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setPrewarmRoverId(null);
|
|
||||||
}, [rotationKey]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
clearTimeout(prewarmTimer.current);
|
clearTimeout(prewarmTimer.current);
|
||||||
if (!canSpectateVideo || rotationPool.length < 2) {
|
if (!canSpectateVideo || rotationPool.length < 2) {
|
||||||
setPrewarmRoverId(null);
|
setSecondaryRoverId(null);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
const nextIndex = (index + 1) % rotationPool.length;
|
const nextIndex = (index + 1) % rotationPool.length;
|
||||||
const delay = Math.max(0, ROTATE_MS - PREWARM_MS);
|
const delay = Math.max(0, ROTATE_MS - PREWARM_MS);
|
||||||
prewarmTimer.current = setTimeout(() => {
|
prewarmTimer.current = setTimeout(() => {
|
||||||
const nextEntry = rotationPool[nextIndex];
|
const nextEntry = rotationPool[nextIndex];
|
||||||
setPrewarmRoverId(nextEntry?.rover?.id || null);
|
const nextId = nextEntry?.rover?.id || null;
|
||||||
|
if (!nextId) {
|
||||||
|
setSecondaryRoverId(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (visibleSlot === 'primary') {
|
||||||
|
setSecondaryRoverId(nextId);
|
||||||
|
} else {
|
||||||
|
setPrimaryRoverId(nextId);
|
||||||
|
}
|
||||||
}, delay);
|
}, delay);
|
||||||
return () => clearTimeout(prewarmTimer.current);
|
return () => clearTimeout(prewarmTimer.current);
|
||||||
}, [index, rotationPool, canSpectateVideo]);
|
}, [index, rotationPool, canSpectateVideo, visibleSlot]);
|
||||||
|
|
||||||
const activeEntry = rotationPool.length ? rotationPool[index % rotationPool.length] : null;
|
const activeEntry = rotationPool.length ? rotationPool[index % rotationPool.length] : null;
|
||||||
const activeRover = activeEntry?.type === 'rover' ? activeEntry.rover : null;
|
const activeRover = activeEntry?.type === 'rover' ? activeEntry.rover : null;
|
||||||
const prewarmRover = prewarmRoverId
|
const activeRoverId = activeRover?.id || null;
|
||||||
? rotationPool.find((entry) => entry.rover?.id === prewarmRoverId)?.rover || null
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!activeRoverId) return;
|
||||||
|
if (activeRoverId === primaryRoverId) {
|
||||||
|
setVisibleSlot('primary');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (activeRoverId === secondaryRoverId) {
|
||||||
|
setVisibleSlot('secondary');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setPrimaryRoverId(activeRoverId);
|
||||||
|
setVisibleSlot('primary');
|
||||||
|
}, [activeRoverId, primaryRoverId, secondaryRoverId]);
|
||||||
|
|
||||||
|
const primaryRover = primaryRoverId
|
||||||
|
? rotationPool.find((entry) => entry.rover?.id === primaryRoverId)?.rover || null
|
||||||
|
: null;
|
||||||
|
const secondaryRover = secondaryRoverId
|
||||||
|
? rotationPool.find((entry) => entry.rover?.id === secondaryRoverId)?.rover || null
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const activeSnapshot = !canSpectateVideo && activeRover ? snapshotFeeds[activeRover.id] || null : null;
|
const activeSnapshot = !canSpectateVideo && activeRover ? snapshotFeeds[activeRover.id] || null : null;
|
||||||
const activeVideo = canSpectateVideo && activeRover ? videoSources[activeRover.id] || null : null;
|
const activeVideo = canSpectateVideo && activeRover ? videoSources[activeRover.id] || null : null;
|
||||||
const prewarmVideo = canSpectateVideo && prewarmRover ? videoSources[prewarmRover.id] || null : null;
|
const primaryVideo = canSpectateVideo && primaryRover ? videoSources[primaryRover.id] || null : null;
|
||||||
|
const secondaryVideo = canSpectateVideo && secondaryRover ? videoSources[secondaryRover.id] || null : null;
|
||||||
const activeAudio = activeRover ? audioSources[`${activeRover.id}-audio`] || null : null;
|
const activeAudio = activeRover ? audioSources[`${activeRover.id}-audio`] || null : null;
|
||||||
const activeFrame = activeRover ? frames[activeRover.id] || null : null;
|
const activeFrame = activeRover ? frames[activeRover.id] || null : null;
|
||||||
const prewarmFrame = prewarmRover ? frames[prewarmRover.id] || null : null;
|
const primaryFrame = primaryRover ? frames[primaryRover.id] || null : null;
|
||||||
|
const secondaryFrame = secondaryRover ? frames[secondaryRover.id] || null : null;
|
||||||
const driverLabel = activeRover ? formatDriverLabel({ roverId: activeRover.id, session }) : null;
|
const driverLabel = activeRover ? formatDriverLabel({ roverId: activeRover.id, session }) : null;
|
||||||
|
|
||||||
if (inLockdown) {
|
if (inLockdown) {
|
||||||
@@ -375,31 +409,38 @@ function MiniSummaryContent() {
|
|||||||
<FitViewportFrame>
|
<FitViewportFrame>
|
||||||
{canSpectateVideo ? (
|
{canSpectateVideo ? (
|
||||||
<div className="relative h-full w-full">
|
<div className="relative h-full w-full">
|
||||||
<div className="absolute inset-0">
|
{primaryRover ? (
|
||||||
<VideoTile
|
<div
|
||||||
sessionInfo={activeVideo}
|
className={`absolute inset-0 ${visibleSlot === 'primary' ? 'opacity-100' : 'opacity-0 pointer-events-none'}`}
|
||||||
videoMode="whep"
|
>
|
||||||
snapshotFeed={null}
|
|
||||||
audioSessionInfo={activeAudio}
|
|
||||||
label={activeRover.name || activeRover.id}
|
|
||||||
telemetryFrame={activeFrame}
|
|
||||||
batteryConfig={activeRover.battery}
|
|
||||||
layoutFormat="mobile"
|
|
||||||
hudVariant="none"
|
|
||||||
fitParent
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{prewarmRover && prewarmRover.id !== activeRover.id ? (
|
|
||||||
<div className="absolute inset-0 opacity-0 pointer-events-none">
|
|
||||||
<VideoTile
|
<VideoTile
|
||||||
sessionInfo={prewarmVideo}
|
sessionInfo={primaryVideo}
|
||||||
videoMode="whep"
|
videoMode="whep"
|
||||||
snapshotFeed={null}
|
snapshotFeed={null}
|
||||||
audioSessionInfo={null}
|
audioSessionInfo={visibleSlot === 'primary' ? activeAudio : null}
|
||||||
forceMute
|
forceMute={visibleSlot !== 'primary'}
|
||||||
label={prewarmRover.name || prewarmRover.id}
|
label={primaryRover.name || primaryRover.id}
|
||||||
telemetryFrame={prewarmFrame}
|
telemetryFrame={primaryFrame}
|
||||||
batteryConfig={prewarmRover.battery}
|
batteryConfig={primaryRover.battery}
|
||||||
|
layoutFormat="mobile"
|
||||||
|
hudVariant="none"
|
||||||
|
fitParent
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{secondaryRover ? (
|
||||||
|
<div
|
||||||
|
className={`absolute inset-0 ${visibleSlot === 'secondary' ? 'opacity-100' : 'opacity-0 pointer-events-none'}`}
|
||||||
|
>
|
||||||
|
<VideoTile
|
||||||
|
sessionInfo={secondaryVideo}
|
||||||
|
videoMode="whep"
|
||||||
|
snapshotFeed={null}
|
||||||
|
audioSessionInfo={visibleSlot === 'secondary' ? activeAudio : null}
|
||||||
|
forceMute={visibleSlot !== 'secondary'}
|
||||||
|
label={secondaryRover.name || secondaryRover.id}
|
||||||
|
telemetryFrame={secondaryFrame}
|
||||||
|
batteryConfig={secondaryRover.battery}
|
||||||
layoutFormat="mobile"
|
layoutFormat="mobile"
|
||||||
hudVariant="none"
|
hudVariant="none"
|
||||||
fitParent
|
fitParent
|
||||||
|
|||||||
Reference in New Issue
Block a user