Skip to content

Feature/procedural space background - #180

Open
SohammPawarr wants to merge 4 commits into
7-Blocks:mainfrom
SohammPawarr:feature/procedural-space-background
Open

Feature/procedural space background#180
SohammPawarr wants to merge 4 commits into
7-Blocks:mainfrom
SohammPawarr:feature/procedural-space-background

Conversation

@SohammPawarr

@SohammPawarr SohammPawarr commented Aug 8, 2026

Copy link
Copy Markdown

User description

Description

Replaced the current static space background with a fully procedural, animated space environment. Instead of relying on a fixed background image, this PR implements a highly performant HTML5 Canvas layered behind the Cesium globe that renders thousands of stars and softly animated nebulae.

  • Procedural Starfield & Nebulae: Generates 3 separate offscreen layers to optimize rendering of 3,000+ stars with varying brightness, colors, and subtle radial gradients for deep space nebulae.
  • Parallax Scrolling: Hooks into Cesium's preRender event to perfectly synchronize background offsets with camera heading and pitch.
  • Zoom Responsiveness: Implements subtle altitude-based shifting to provide a realistic sense of depth as users zoom in and out of the globe.
  • Bug Fix: Also resolved a fatal Vite bundling issue with CameraMode and CatalogObject TypeScript imports.

Related Issue: #171

Testing Details

  • Verified the offscreen canvas optimization maintains a stable 60fps framerate.
  • Ensured seamless coordinate wrapping (modulo arithmetic) so the user can spin the globe infinitely without the background breaking.
  • Verified TypeScript compilation (tsc) passes successfully.

CodeAnt-AI Description

Add live satellite flyby alerts, cinematic tracking views, and a procedural space backdrop

What Changed

  • Tracked satellites now generate flyby alerts for the user’s location and saved locations, including arrival time, altitude, speed, and peak elevation.
  • Alerts appear as on-screen notifications, can optionally play a sound or browser notification, and can open the satellite’s live tracking view.
  • A flyby history panel lets users review alerts, clear them, enable or disable sound, and choose a 5-, 10-, or 15-minute warning window.
  • Selected satellites can be viewed in Free, Chase, Cockpit, Earth Observer, or Orbital camera modes with smooth motion.
  • The globe now uses an animated, layered starfield and nebula background that shifts with camera movement and zoom.

Impact

✅ Earlier satellite flyby warnings
✅ Faster access to live satellite tracking
✅ Clearer orbital viewing modes
✅ Animated space backdrop

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Copilot AI lite review requested due to automatic review settings August 8, 2026 10:50
@codeant-ai

codeant-ai Bot commented Aug 8, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR 6de27f0 Aug 08, 2026 · 10:50 10:53

@codeant-ai

codeant-ai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@github-actions github-actions Bot added backend Backend development bug Something isn't working database Database and schema related changes enhancement New feature or request frontend Frontend development size/XL Very large or complex contribution. testing Tests added or improved type:backend Changes backend services or server-side logic. type:bug Fixes an existing bug or unexpected behavior. type:feature Introduces a new feature or enhancement. type:frontend Changes frontend or client-side code. type:testing Adds or updates automated tests. labels Aug 8, 2026
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@SohammPawarr, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 21 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e32c613b-b176-4376-a555-e7583bcae0a9

📥 Commits

Reviewing files that changed from the base of the PR and between 92321d4 and 6de27f0.

⛔ Files ignored due to path filters (27)
  • backend/api/v1/__pycache__/__init__.cpython-313.pyc is excluded by !**/*.pyc
  • backend/api/v1/endpoints/__pycache__/__init__.cpython-313.pyc is excluded by !**/*.pyc
  • backend/api/v1/endpoints/__pycache__/agents.cpython-313.pyc is excluded by !**/*.pyc
  • backend/api/v1/endpoints/__pycache__/auth.cpython-313.pyc is excluded by !**/*.pyc
  • backend/api/v1/endpoints/__pycache__/catalog.cpython-313.pyc is excluded by !**/*.pyc
  • backend/api/v1/endpoints/__pycache__/collisions.cpython-313.pyc is excluded by !**/*.pyc
  • backend/api/v1/endpoints/__pycache__/dashboard.cpython-313.pyc is excluded by !**/*.pyc
  • backend/api/v1/endpoints/__pycache__/satellites.cpython-313.pyc is excluded by !**/*.pyc
  • backend/api/v1/endpoints/__pycache__/weather.cpython-313.pyc is excluded by !**/*.pyc
  • backend/app/__pycache__/__init__.cpython-313.pyc is excluded by !**/*.pyc
  • backend/app/__pycache__/main.cpython-313.pyc is excluded by !**/*.pyc
  • backend/app/core/__pycache__/__init__.cpython-313.pyc is excluded by !**/*.pyc
  • backend/app/core/__pycache__/config.cpython-313.pyc is excluded by !**/*.pyc
  • backend/app/core/__pycache__/scheduler.cpython-313.pyc is excluded by !**/*.pyc
  • backend/app/core/__pycache__/security.cpython-313.pyc is excluded by !**/*.pyc
  • backend/database/__pycache__/__init__.cpython-313.pyc is excluded by !**/*.pyc
  • backend/database/__pycache__/session.cpython-313.pyc is excluded by !**/*.pyc
  • backend/models/__pycache__/__init__.cpython-313.pyc is excluded by !**/*.pyc
  • backend/models/__pycache__/db_models.cpython-313.pyc is excluded by !**/*.pyc
  • backend/orbital/__pycache__/__init__.cpython-313.pyc is excluded by !**/*.pyc
  • backend/orbital/providers/__pycache__/__init__.cpython-313.pyc is excluded by !**/*.pyc
  • backend/orbital/providers/__pycache__/base.cpython-313.pyc is excluded by !**/*.pyc
  • backend/orbital/providers/__pycache__/cache.cpython-313.pyc is excluded by !**/*.pyc
  • backend/orbital/providers/__pycache__/celestrak.cpython-313.pyc is excluded by !**/*.pyc
  • backend/orbital/providers/__pycache__/chain.cpython-313.pyc is excluded by !**/*.pyc
  • backend/orbital/providers/__pycache__/spacetrack.cpython-313.pyc is excluded by !**/*.pyc
  • backend/tests/__pycache__/test_backend.cpython-312-pytest-9.1.1.pyc is excluded by !**/*.pyc
📒 Files selected for processing (13)
  • .gitignore
  • frontend/src/components/EarthTwin.tsx
  • frontend/src/components/layouts/MainLayout.tsx
  • frontend/src/components/ui/CameraControls.tsx
  • frontend/src/components/ui/FlybyNotification.tsx
  • frontend/src/components/ui/NotificationCenter.tsx
  • frontend/src/components/ui/ProceduralSpaceBackground.tsx
  • frontend/src/hooks/useCinematicCamera.ts
  • frontend/src/hooks/useFlybyEngine.ts
  • frontend/src/store/notificationStore.ts
  • frontend/src/store/uiStore.ts
  • frontend/src/utils/orbitCalc.ts
  • frontend/tsconfig.app.json

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codeant-ai codeant-ai Bot added the size:XL This PR changes 500-999 lines, ignoring generated files label Aug 8, 2026
@github-actions github-actions Bot added AI Artificial Intelligence and Machine Learning documentation Improvements or additions to documentation type:documentation Improves project documentation. labels Aug 8, 2026
<div
className="relative w-full h-full overflow-hidden bg-bg-deep-space border-b border-border-panel"
>
<ProceduralSpaceBackground viewer={viewerInstance} />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The procedural canvas is mounted inside an EarthTwin container with an opaque bg-bg-deep-space background, while the canvas implementation places it at a negative stacking level. This can put the canvas behind its parent's background and make the new procedural stars and nebula invisible, leaving only the opaque panel visible. Keep the background canvas in the visible stacking context or remove the negative z-index. [css layout issue]

Severity Level: Major ⚠️
- ❌ Dashboard globe can show only a flat dark background.
- ⚠️ Procedural stars and nebulae disappear behind opaque layers.
- ⚠️ The advertised animated space environment is unavailable.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** frontend/src/components/EarthTwin.tsx
**Line:** 733:733
**Comment:**
	*Css Layout Issue: The procedural canvas is mounted inside an EarthTwin container with an opaque `bg-bg-deep-space` background, while the canvas implementation places it at a negative stacking level. This can put the canvas behind its parent's background and make the new procedural stars and nebula invisible, leaving only the opaque panel visible. Keep the background canvas in the visible stacking context or remove the negative z-index.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

</div>

<NotificationCenter />
<CameraControls />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Mounting CameraControls at the layout level makes the toolbar appear on every route whenever the global selectedSatelliteId is set. The Satellites page sets that same global selection, so users can see camera-mode controls on a page without a Cesium viewer, and the selected mode remains active when later opening the globe. Render this control only in the EarthTwin/dashboard context or clear/namespace the globe camera state on route changes. [api mismatch]

Severity Level: Major ⚠️
- ⚠️ Camera toolbar appears on non-globe pages.
- ⚠️ Satellites page controls can modify globe-only state.
- ⚠️ Dashboard may open with stale cinematic camera mode.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** frontend/src/components/layouts/MainLayout.tsx
**Line:** 417:417
**Comment:**
	*Api Mismatch: Mounting `CameraControls` at the layout level makes the toolbar appear on every route whenever the global `selectedSatelliteId` is set. The Satellites page sets that same global selection, so users can see camera-mode controls on a page without a Cesium viewer, and the selected mode remains active when later opening the globe. Render this control only in the EarthTwin/dashboard context or clear/namespace the globe camera state on route changes.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

try {
// Fetch data for all tracked satellites
const satPromises = selectedSatelliteIds.map(id => api.getCatalogObjectByNorad(id));
const responses = await Promise.allSettled(satPromises);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The asynchronous scan is not invalidated when this effect is cleaned up. If the selected satellites, bookmarks, or warning preference changes while Promise.allSettled is awaiting API responses, the old scan continues and can add notifications using stale inputs after the replacement scan has started. Track an active-run token or cancellation flag and check it before processing results and adding notifications. [race condition]

Severity Level: Major ⚠️
- ⚠️ Stale flyby alerts can appear after tracking changes.
- ⚠️ Bookmark edits can produce alerts for old locations.
- ⚠️ Preference changes do not invalidate pending scans.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** frontend/src/hooks/useFlybyEngine.ts
**Line:** 48:48
**Comment:**
	*Race Condition: The asynchronous scan is not invalidated when this effect is cleaned up. If the selected satellites, bookmarks, or warning preference changes while `Promise.allSettled` is awaiting API responses, the old scan continues and can add notifications using stale inputs after the replacement scan has started. Track an active-run token or cancellation flag and check it before processing results and adding notifications.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +12 to +15
if (obj.semimajor_axis == null || obj.inclination == null || obj.raan == null ||
obj.arg_of_perigee == null || obj.mean_anomaly == null || obj.mean_motion == null) {
return null;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The propagator rejects any catalog object whose mean_anomaly is null, even though CatalogObject permits that field to be null and computeOrbitPositions only requires mean_motion. As a result, those otherwise renderable satellites are skipped by EarthTwin and cannot be targeted or propagated by the flyby and camera features. Treat the missing anomaly consistently with the existing orbit-highlighting behavior or exclude such objects explicitly at the data-loading boundary. [api mismatch]

Severity Level: Major ⚠️
- ❌ Catalog objects are skipped by `EarthTwin` entity creation.
- ❌ Camera targeting receives no propagated position.
- ❌ Flyby propagation skips current catalog records.
- ⚠️ Fixing only mean anomaly is insufficient with current API serialization.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** frontend/src/utils/orbitCalc.ts
**Line:** 12:15
**Comment:**
	*Api Mismatch: The propagator rejects any catalog object whose `mean_anomaly` is null, even though `CatalogObject` permits that field to be null and `computeOrbitPositions` only requires `mean_motion`. As a result, those otherwise renderable satellites are skipped by `EarthTwin` and cannot be targeted or propagated by the flyby and camera features. Treat the missing anomaly consistently with the existing orbit-highlighting behavior or exclude such objects explicitly at the data-loading boundary.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

const AudioContext = window.AudioContext || (window as any).webkitAudioContext;
if (!AudioContext) return;

const ctx = new AudioContext();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Each alert creates a new AudioContext, but the context is never closed after the oscillator stops. Repeated flyby alerts can therefore accumulate open audio contexts and eventually hit browser resource limits. Close the context after playback completes or reuse a shared context. [resource leak]

Severity Level: Major ⚠️
- ⚠️ Long sessions retain one audio context per alert.
- ⚠️ Repeated flyby alerts increase browser audio-resource usage.
- ⚠️ Excessive contexts can cause later audio playback failures.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** frontend/src/components/ui/FlybyNotification.tsx
**Line:** 18:18
**Comment:**
	*Resource Leak: Each alert creates a new `AudioContext`, but the context is never closed after the oscillator stops. Repeated flyby alerts can therefore accumulate open audio contexts and eventually hit browser resource limits. Close the context after playback completes or reuse a shared context.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

} else if (Notification.permission !== 'denied') {
Notification.requestPermission();
}
}, [notification, preferences.soundEnabled]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: This effect is intended to alert once for a notification, but it also depends on preferences.soundEnabled. Changing the sound preference reruns the effect for every currently displayed notification and creates another browser notification, causing duplicate external alerts. Separate the one-time notification side effect from the sound preference or otherwise track which notification has already been announced. [state lifecycle]

Severity Level: Major ⚠️
- ⚠️ Audio preference changes replay existing flyby beeps.
- ⚠️ Browser users receive duplicate external flyby alerts.
- ⚠️ Notification settings produce unrelated alert side effects.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** frontend/src/components/ui/FlybyNotification.tsx
**Line:** 59:59
**Comment:**
	*State Lifecycle: This effect is intended to alert once for a notification, but it also depends on `preferences.soundEnabled`. Changing the sound preference reruns the effect for every currently displayed notification and creates another browser notification, causing duplicate external alerts. Separate the one-time notification side effect from the sound preference or otherwise track which notification has already been announced.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

return (
<canvas
ref={canvasRef}
className="fixed inset-0 pointer-events-none z-[-1]"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The background is rendered as a fixed viewport-sized canvas even though this component is mounted inside the smaller EarthTwin panel. It is not constrained to the panel's bounds, so it can paint a full-screen background from inside the globe component and its viewport-sized rendering does not match the panel layout. Size the canvas relative to the EarthTwin container and use absolute positioning within that container. [css layout issue]

Severity Level: Major ⚠️
- ⚠️ Procedural background extends beyond the EarthTwin panel.
- ⚠️ Dashboard sections can receive unintended background rendering.
- ⚠️ Globe-panel resizing does not resize the canvas to panel bounds.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** frontend/src/components/ui/ProceduralSpaceBackground.tsx
**Line:** 155:155
**Comment:**
	*Css Layout Issue: The background is rendered as a fixed viewport-sized canvas even though this component is mounted inside the smaller `EarthTwin` panel. It is not constrained to the panel's bounds, so it can paint a full-screen background from inside the globe component and its viewport-sized rendering does not match the panel layout. Size the canvas relative to the EarthTwin container and use absolute positioning within that container.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +26 to +33
if (mode === 'FREE' || !targetId) {
if (lastMode.current !== 'FREE') {
lastMode.current = 'FREE';
// Release any overrides if needed, but Cesium camera allows manual control natively
// when we stop overriding it in preRender.
}
return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Clearing selectedSatelliteId only causes this handler to return; it does not reset cameraMode. After a user selects a cinematic mode, clears the selection, and selects another satellite later, the old mode is still active and the handler immediately resumes overriding the camera for the new satellite. Reset the mode to FREE when the target is cleared, or make selection clearing perform that reset. [stale reference]

Severity Level: Major ⚠️
- ⚠️ Selecting a later satellite unexpectedly reactivates cinematic tracking.
- ⚠️ User camera control is overridden after clearing selection.
- ⚠️ Camera mode UI state disagrees with the user's cleared target.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** frontend/src/hooks/useCinematicCamera.ts
**Line:** 26:33
**Comment:**
	*Stale Reference: Clearing `selectedSatelliteId` only causes this handler to return; it does not reset `cameraMode`. After a user selects a cinematic mode, clears the selection, and selects another satellite later, the old mode is still active and the handler immediately resumes overriding the camera for the new satellite. Reset the mode to `FREE` when the target is cleared, or make selection clearing perform that reset.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

createdAt: new Date(),
};

return { notifications: [newNotification, ...state.notifications] };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Every non-duplicate notification is prepended to state.notifications, while dismissal only marks entries and does not remove them. The flyby engine runs every 30 seconds and the history UI renders the entire array, so a long-running session can accumulate unbounded history and progressively increase memory use and rendering cost. Retain a bounded history or remove old dismissed entries. [performance]

Severity Level: Major ⚠️
- ⚠️ Long-running sessions retain all dismissed flyby alerts.
- ⚠️ Flyby history rendering cost grows with session duration.
- ⚠️ Repeated alert creation increases client memory usage.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** frontend/src/store/notificationStore.ts
**Line:** 55:55
**Comment:**
	*Performance: Every non-duplicate notification is prepended to `state.notifications`, while dismissal only marks entries and does not remove them. The flyby engine runs every 30 seconds and the history UI renders the entire array, so a long-running session can accumulate unbounded history and progressively increase memory use and rendering cost. Retain a bounded history or remove old dismissed entries.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces the static space backdrop with a procedural, animated canvas background behind the Cesium globe, and adds new UX features for satellite tracking including flyby notifications, a flyby history/settings panel, and cinematic camera modes.

Changes:

  • Add a layered procedural starfield/nebula canvas synchronized to Cesium camera motion and zoom.
  • Introduce a flyby alert engine with notification UI, preferences, and history panel.
  • Add cinematic camera modes (Free/Chase/Cockpit/Earth Observer/Orbital) and shared orbital math utilities.

Reviewed changes

Copilot reviewed 12 out of 40 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
frontend/tsconfig.app.json Removes a TS ignoreDeprecations config entry.
frontend/src/utils/orbitCalc.ts Adds shared orbital math utilities used by flyby + camera features.
frontend/src/store/uiStore.ts Adds flyby panel UI state and camera mode state.
frontend/src/store/notificationStore.ts Adds Zustand store for flyby notifications + preferences.
frontend/src/hooks/useFlybyEngine.ts Adds periodic flyby checking and notification generation.
frontend/src/hooks/useCinematicCamera.ts Adds Cesium preRender-driven cinematic camera tracking modes.
frontend/src/components/ui/ProceduralSpaceBackground.tsx Adds procedural canvas background rendered behind the globe.
frontend/src/components/ui/NotificationCenter.tsx Adds global flyby toasts + history/settings panel UI.
frontend/src/components/ui/FlybyNotification.tsx Adds flyby toast UI with optional audio + browser notifications.
frontend/src/components/ui/CameraControls.tsx Adds on-screen camera mode switcher when a satellite is selected.
frontend/src/components/layouts/MainLayout.tsx Mounts NotificationCenter + CameraControls and adds a header toggle.
frontend/src/components/EarthTwin.tsx Integrates procedural background and cinematic camera into the Cesium viewer.
.gitignore Adds common Python ignores.
Suppressed comments (2)

frontend/src/components/ui/ProceduralSpaceBackground.tsx:109

  • drawTiled uses canvas.width/height for its tiling bounds. If the canvas is ever scaled (e.g., for devicePixelRatio), these values are in device pixels and will cause unnecessary extra tiling work. Use canvas.clientWidth/clientHeight for the loop bounds so the logic stays in CSS pixels.
    frontend/src/components/ui/ProceduralSpaceBackground.tsx:130
  • With the canvas potentially being device-pixel scaled, clearing via canvas.width/height mixes coordinate spaces and can do extra work. Clear using clientWidth/clientHeight (CSS pixels) to match the drawing coordinate system.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +71 to +90
const rE = EARTH_RADIUS_KM;
const rS = EARTH_RADIUS_KM + satelliteAltKm;

// Central angle between observer and satellite's nadir
const gammaRad = groundDistanceKm / rE;

// Slant range (distance from observer to satellite)
const d = Math.sqrt(rE ** 2 + rS ** 2 - 2 * rE * rS * Math.cos(gammaRad));

// Elevation angle calculation
const cosEl = (rS * Math.sin(gammaRad)) / d;

let elRad = Math.acos(cosEl);

// If gamma > 90 deg, the satellite is definitely below the horizon, but Math.acos handles 0 to PI.
// Actually, wait, a standard way is to use atan2 or just simple geometry:
// el = atan( (cos(gamma) - (rE / rS)) / sin(gamma) )

const el = Math.atan2(Math.cos(gammaRad) - (rE / rS), Math.sin(gammaRad));
return el * (180 / Math.PI);
Comment on lines +123 to +126

// Run immediately, then on interval
checkFlybys();
const intervalId = setInterval(checkFlybys, CHECK_INTERVAL_MS);
Comment on lines +52 to +54
// 2. Update physical entity position so it visibly moves!
entity.position = new Cesium.ConstantPositionProperty(p0);

Comment on lines +50 to +58
// Optional: Use browser notifications API if permitted
if (Notification.permission === 'granted') {
new Notification(`Flyby Alert: ${notification.satelliteName}`, {
body: `Approaching ${notification.locationName}. ETA: ${notification.eta.toLocaleTimeString()}`,
icon: '/vite.svg'
});
} else if (Notification.permission !== 'denied') {
Notification.requestPermission();
}
Comment on lines +153 to +157
<canvas
ref={canvasRef}
className="fixed inset-0 pointer-events-none z-[-1]"
style={{ background: '#030508' }}
/>
Comment on lines +42 to +44
// 1. Calculate precise real-time position and velocity
const now = new Date();
const p0_geo = keplerToLatLonAlt(catalogData, 0);
Comment on lines +18 to +33
const ctx = new AudioContext();
const osc = ctx.createOscillator();
const gainNode = ctx.createGain();

osc.type = 'sine';
osc.frequency.setValueAtTime(880, ctx.currentTime); // A5
osc.frequency.exponentialRampToValueAtTime(440, ctx.currentTime + 0.1); // Drop to A4

gainNode.gain.setValueAtTime(0.1, ctx.currentTime);
gainNode.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.5);

osc.connect(gainNode);
gainNode.connect(ctx.destination);

osc.start();
osc.stop(ctx.currentTime + 0.5);
Comment on lines +71 to +77
// Resize observer to keep main canvas full screen
const resizeObserver = new ResizeObserver(() => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
resizeObserver.observe(document.body);

@krishkhinchi

Copy link
Copy Markdown
Member

Hello @SohammPawarr, Please attach screenshots of the updates/changes along with your PR. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Artificial Intelligence and Machine Learning backend Backend development bug Something isn't working database Database and schema related changes documentation Improvements or additions to documentation enhancement New feature or request frontend Frontend development size/XL Very large or complex contribution. size:XL This PR changes 500-999 lines, ignoring generated files testing Tests added or improved type:backend Changes backend services or server-side logic. type:bug Fixes an existing bug or unexpected behavior. type:documentation Improves project documentation. type:feature Introduces a new feature or enhancement. type:frontend Changes frontend or client-side code. type:testing Adds or updates automated tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants