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
+39 -8
View File
@@ -372,6 +372,9 @@ const APP = () => {
setIsPlaying(false); setIsPlaying(false);
setFlightSpeed(1.0); setFlightSpeed(1.0);
} }
flightProgressRef.current = 0;
setCurrentCityIndex(-1);
currentCityIndexRef.current = -1;
if (popupRef.current) { if (popupRef.current) {
popupRef.current.remove(); popupRef.current.remove();
popupRef.current = null; popupRef.current = null;
@@ -458,14 +461,11 @@ const APP = () => {
if (animationRef.current) cancelAnimationFrame(animationRef.current); if (animationRef.current) cancelAnimationFrame(animationRef.current);
setIsPlaying(false); setIsPlaying(false);
setFlightSpeed(1.0); setFlightSpeed(1.0);
setCurrentCityIndex(-1);
currentCityIndexRef.current = -1;
return; return;
} }
setIsPlaying(true); setIsPlaying(true);
setCurrentCityIndex(-1); // Don't reset currentCityIndex here, so it resumes correctly
currentCityIndexRef.current = -1;
if (popupRef.current) popupRef.current.remove(); if (popupRef.current) popupRef.current.remove();
const coordinates = lineOfSightData.line_coordinates.map(c => [c.lon, c.lat]); const coordinates = lineOfSightData.line_coordinates.map(c => [c.lon, c.lat]);
@@ -474,7 +474,7 @@ const APP = () => {
let lastFetchedDist = flightProgressRef.current; let lastFetchedDist = flightProgressRef.current;
let currentProgress = flightProgressRef.current; let currentProgress = flightProgressRef.current;
flightProgressRef.current = 0; // Removed: flightProgressRef.current = 0; - We keep the ref to resume.
let lastTimestamp = performance.now(); let lastTimestamp = performance.now();
let currentSpeedMultiplier = 1.0; let currentSpeedMultiplier = 1.0;
let frameCount = 0; let frameCount = 0;
@@ -583,6 +583,7 @@ const APP = () => {
} }
} }
flightProgressRef.current = currentProgress;
animationRef.current = requestAnimationFrame(animate); animationRef.current = requestAnimationFrame(animate);
} }
@@ -749,6 +750,10 @@ const APP = () => {
console.error('Error fetching line of sight:', error); console.error('Error fetching line of sight:', error);
} finally { } finally {
setLoading(false); 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>
) : ( ) : (
<> <>
<div className="fly-controls">
<button <button
className="action-btn" className={`fly-button ${isPlaying ? 'pause' : 'play'}`}
onClick={startFlyOver} onClick={startFlyOver}
style={{ backgroundColor: isPlaying ? '#e74c3c' : '#3498db' }} disabled={!lineOfSightData}
> >
{isPlaying ? `⏹ Stop Flight (${flightSpeed.toFixed(1)}x)` : '✈️ Fly Over Route'} {isPlaying ? `Pause Flyover (${flightSpeed.toFixed(1)}x)` : (flightProgressRef.current > 0 ? 'Resume Flyover' : 'Start Flyover')}
</button> </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}> <button className="action-btn-secondary" onClick={handleStartAgain}>
🔄 Start Again 🔄 Start Again
</button> </button>
+59
View File
@@ -463,3 +463,62 @@
font-size: 13px; font-size: 13px;
margin-bottom: 8px; 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;
}