Play/pause flyover
Tests / backend-test (pull_request) Successful in 6s
Tests / frontend-test (pull_request) Failing after 8s
Tests / e2e-test (pull_request) Failing after 1m29s

This commit is contained in:
(jenkins)
2026-04-17 00:26:05 +01:00
parent 0bba5b1abe
commit 76eed69c8f
2 changed files with 102 additions and 12 deletions
+43 -12
View File
@@ -372,6 +372,9 @@ const APP = () => {
setIsPlaying(false);
setFlightSpeed(1.0);
}
flightProgressRef.current = 0;
setCurrentCityIndex(-1);
currentCityIndexRef.current = -1;
if (popupRef.current) {
popupRef.current.remove();
popupRef.current = null;
@@ -458,14 +461,11 @@ const APP = () => {
if (animationRef.current) cancelAnimationFrame(animationRef.current);
setIsPlaying(false);
setFlightSpeed(1.0);
setCurrentCityIndex(-1);
currentCityIndexRef.current = -1;
return;
}
setIsPlaying(true);
setCurrentCityIndex(-1);
currentCityIndexRef.current = -1;
// Don't reset currentCityIndex here, so it resumes correctly
if (popupRef.current) popupRef.current.remove();
const coordinates = lineOfSightData.line_coordinates.map(c => [c.lon, c.lat]);
@@ -474,7 +474,7 @@ const APP = () => {
let lastFetchedDist = flightProgressRef.current;
let currentProgress = flightProgressRef.current;
flightProgressRef.current = 0;
// Removed: flightProgressRef.current = 0; - We keep the ref to resume.
let lastTimestamp = performance.now();
let currentSpeedMultiplier = 1.0;
let frameCount = 0;
@@ -583,6 +583,7 @@ const APP = () => {
}
}
flightProgressRef.current = currentProgress;
animationRef.current = requestAnimationFrame(animate);
}
@@ -749,6 +750,10 @@ const APP = () => {
console.error('Error fetching line of sight:', error);
} finally {
setLoading(false);
// Reset flight progress for a new line calculation
flightProgressRef.current = 0;
setCurrentCityIndex(-1);
currentCityIndexRef.current = -1;
}
};
@@ -841,13 +846,39 @@ const APP = () => {
</button>
) : (
<>
<button
className="action-btn"
onClick={startFlyOver}
style={{ backgroundColor: isPlaying ? '#e74c3c' : '#3498db' }}
>
{isPlaying ? `⏹ Stop Flight (${flightSpeed.toFixed(1)}x)` : '✈️ Fly Over Route'}
</button>
<div className="fly-controls">
<button
className={`fly-button ${isPlaying ? 'pause' : 'play'}`}
onClick={startFlyOver}
disabled={!lineOfSightData}
>
{isPlaying ? `Pause Flyover (${flightSpeed.toFixed(1)}x)` : (flightProgressRef.current > 0 ? 'Resume Flyover' : 'Start Flyover')}
</button>
<button
className="reset-flight-btn"
onClick={() => {
cancelAnimationFrame(animationRef.current);
setIsPlaying(false);
setFlightSpeed(1.0);
flightProgressRef.current = 0;
setCurrentCityIndex(-1);
currentCityIndexRef.current = -1;
// Move camera back to start
if (mapRef.current) {
mapRef.current.flyTo({
center: [selectedPoint.lon, selectedPoint.lat],
zoom: 4,
pitch: 0,
bearing: 0
});
}
}}
disabled={!lineOfSightData || (flightProgressRef.current === 0 && !isPlaying)}
title="Reset flight to beginning"
>
Reset
</button>
</div>
<button className="action-btn-secondary" onClick={handleStartAgain}>
🔄 Start Again
</button>
+59
View File
@@ -463,3 +463,62 @@
font-size: 13px;
margin-bottom: 8px;
}
.fly-controls {
display: flex;
gap: 8px;
margin-top: 10px;
}
.fly-button {
flex: 3;
padding: 12px;
border: none;
border-radius: 6px;
color: white;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.fly-button.play {
background: #3498db;
}
.fly-button.play:hover {
background: #2980b9;
}
.fly-button.pause {
background: #e74c3c;
}
.fly-button.pause:hover {
background: #c0392b;
}
.reset-flight-btn {
flex: 1;
padding: 12px;
background: #95a5a6;
color: white;
border: none;
border-radius: 6px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
}
.reset-flight-btn:hover:not(:disabled) {
background: #7f8c8d;
}
.reset-flight-btn:disabled {
background: #ecf0f1;
color: #bdc3c7;
cursor: not-allowed;
}