* Refactor aircraft photo and hero banner components to reset loading state on photo change - Updated Lightbox component to reset image loading state when navigating between photos. - Modified HeroBanner component to reset loading state when the photo changes. Clean up control panel search logic - Removed unnecessary hasResults variable in SearchContent component. Implement flight API client with fallback mechanism - Added flight-api-client to handle fetching flight data from multiple sources (airplanes.live, adsb.lol, OpenSky). - Introduced flight-api-parsing module to convert raw API responses into standardized FlightState objects. - Created flight-api-types for shared types between API responses. Refactor useFlights hook to utilize new flight API client - Updated useFlights hook to fetch flights using the new flight API client. - Removed credit management logic as it is no longer applicable with the new API structure. Fix useFlightMonitors to fetch flight data by hex address - Changed useFlightMonitors to use fetchFlightByHex instead of fetchFlightByIcao24. Update geo utility function for better readability - Refactored splitAtAntimeridian function to improve variable naming and clarity. Enhance OpenSky types with additional fields - Added typeCode and registration fields to FlightState type for better integration with readsb data. * fix: correct 6 files that diverged during rebase (iata code, globe mode ref, terrain attribution, cache eviction, opensky parsing) * fix: improve keyboard shortcuts help focus trapping feat: add showAirspace option to MapAttribution component fix: clear hideTimer on ScrollArea cleanup refactor: change pendingFpvRef to MutableRefObject in useFlightMonitors fix: handle sessionStorage availability in useFlightTrack refactor: increase POLL_INTERVAL_MS in useFlights for better performance fix: optimize keyboard shortcuts dialog check refactor: optimize useMergedTrails by caching selected flight position feat: extend Settings type with airspace options refactor: improve airline logo normalization functions refactor: enhance flight API client with serialized rate limiting refactor: optimize registration country lookup with pre-built maps refactor: enhance logo cache management with size limits feat: update map attribution to include airspace option fix: validate rawState in parseStateRow function refactor: improve utility functions with clamp implementation * feat: add ATC lookup functionality and GPU memory monitoring - Implemented ATC lookup functions in `atc-lookup.ts` for converting IATA to ICAO codes, finding nearby ATC feeds, and looking up ATC feeds by code. - Introduced `atc-types.ts` to define types and priorities for ATC feeds. - Added GPU memory monitoring in `gpu-memory-monitor.ts` to track WebGL resource allocations and provide memory reports. - Enhanced trail stitching logic in `trail-stitching.ts` by adding a function to clear the splined track cache and optimizing altitude checks. * feat: enhance flight data handling and improve API resilience - Implemented a maximum empty response streak guard in useFlights to prevent data loss during transient API failures. - Added immediate fetch on network reconnect in useFlights to ensure timely data retrieval. - Updated useMergedTrails to include timestamps for trail points. - Removed smoothAnimations setting from useSettings as it is no longer needed. - Enhanced useTrailHistory to preserve last-known trails during empty flight responses and added dynamic jump detection for tab resume scenarios. - Improved flight API client with a circuit breaker mechanism to handle provider failures and prevent excessive retries. - Updated flight API parsing to reject non-JSON responses from OpenSky and other providers. - Enhanced trail smoothing and stitching logic to ensure better continuity at junctions between historical and live data. * feat: migrate aircraft models to Cloudinary CDN and update mapping logic * fix: adjust UI component styles and improve trail smoothing parameters * fix: adjust base aircraft size for improved rendering * feat: update changelog with recent enhancements and modify data source attribution * fix: update model optimization details and remove Draco compression dependency * feat: update changelog with recent code review fixes and fallback provider adjustments
This commit is contained in:
73
README.md
73
README.md
@ -6,33 +6,28 @@ Aeris renders live air traffic over the world's busiest airspaces on a premium d
|
||||
|
||||
[Live Demo](https://aeris.edbn.me)
|
||||
|
||||
|
||||
<img width="2559" height="1380" alt="Screenshot 2026-02-15 112222" src="https://github.com/user-attachments/assets/9d1f50ed-be4e-4ef5-95ac-257e9129f8c8" />
|
||||
|
||||
|
||||
<img width="2555" height="1387" alt="image" src="https://github.com/user-attachments/assets/a1d2f673-dfdc-4c82-8ee2-7629d91ad94b" />
|
||||
|
||||
|
||||
|
||||
## Stack
|
||||
|
||||
| Layer | Technology |
|
||||
| --------- | ----------------------------------------------- |
|
||||
| Framework | Next.js 16 (App Router, Turbopack) |
|
||||
| Language | TypeScript |
|
||||
| Styling | Tailwind CSS v4 |
|
||||
| Map | MapLibre GL JS |
|
||||
| WebGL | Deck.gl 9 (IconLayer, PathLayer, MapboxOverlay) |
|
||||
| Animation | Motion (Framer Motion) |
|
||||
| Data | OpenSky Network API |
|
||||
| Hosting | Vercel |
|
||||
| Layer | Technology |
|
||||
| --------- | ---------------------------------------------------------------- |
|
||||
| Framework | Next.js 16 (App Router, Turbopack) |
|
||||
| Language | TypeScript |
|
||||
| Styling | Tailwind CSS v4 |
|
||||
| Map | MapLibre GL JS |
|
||||
| WebGL | Deck.gl 9 (ScenegraphLayer, IconLayer, PathLayer, MapboxOverlay) |
|
||||
| Animation | Motion (Framer Motion) |
|
||||
| Data | Airplanes.live / adsb.lol / OpenSky (3-tier fallback) |
|
||||
| Hosting | Vercel |
|
||||
|
||||
## Getting Started
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
cp .env.example .env.local
|
||||
# Optionally add OpenSky credentials — see .env.example
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
@ -46,12 +41,14 @@ src/
|
||||
│ ├── globals.css Tailwind config, theme vars
|
||||
│ ├── layout.tsx Root layout (Inter font)
|
||||
│ ├── page.tsx Entry — renders <FlightTracker />
|
||||
│ └── api/flights/route.ts OpenSky proxy with rate limiting + auth
|
||||
│ └── api/flights/route.ts adsb.lol reverse proxy (CORS workaround + rate limit)
|
||||
├── components/
|
||||
│ ├── flight-tracker.tsx Orchestrator — state, camera, layers, UI
|
||||
│ ├── map/
|
||||
│ │ ├── map.tsx MapLibre GL wrapper with React context
|
||||
│ │ └── flight-layers.tsx Deck.gl overlay — icons, trails, shadows, animation
|
||||
│ │ ├── flight-layers.tsx Deck.gl overlay — icons, trails, shadows, animation
|
||||
│ │ ├── aircraft-model-mapping.ts ADS-B category → 3D model key + bucketing
|
||||
│ │ └── aircraft-model-layers.ts Builds per-model ScenegraphLayers
|
||||
│ └── ui/
|
||||
│ ├── altitude-legend.tsx
|
||||
│ ├── control-panel.tsx Tabbed dialog — search, map style, settings
|
||||
@ -65,9 +62,13 @@ src/
|
||||
│ └── use-trail-history.ts Trail accumulation + Catmull-Rom smoothing
|
||||
└── lib/
|
||||
├── cities.ts Curated aviation hub presets
|
||||
├── flight-api.ts Barrel re-export for the 3-tier flight client
|
||||
├── flight-api-client.ts airplanes.live → adsb.lol → OpenSky fallback chain
|
||||
├── flight-api-parsing.ts readsb JSON → FlightState normalization
|
||||
├── flight-api-types.ts Shared types for ADS-B providers
|
||||
├── flight-utils.ts Altitude→color, unit conversions
|
||||
├── map-styles.ts Map style definitions
|
||||
├── opensky.ts OpenSky API client + types
|
||||
├── opensky.ts OpenSky API client + types (Tier 3 fallback)
|
||||
└── utils.ts cn() utility
|
||||
```
|
||||
|
||||
@ -75,6 +76,30 @@ src/
|
||||
|
||||
- **Dark-first**: CARTO Dark Matter base map, theme-aware UI
|
||||
- **3D depth**: 55° pitch, altitude-based z-displacement via Deck.gl
|
||||
|
||||
## Aircraft Models
|
||||
|
||||
Aeris renders 14 distinct aircraft silhouettes based on ADS-B emitter category and ICAO type code:
|
||||
|
||||
| Model Key | Represents | Assignment |
|
||||
| --------------- | ------------------------------- | ---------------------------------------------- |
|
||||
| `narrowbody` | A320, B737 family | Category 3 (Small), 4 (Large), 5 (High vortex) |
|
||||
| `widebody-2eng` | A330, A350, B777, B787 | Category 6 (Heavy) |
|
||||
| `widebody-4eng` | A380, B747, A340 | — |
|
||||
| `a380` | Airbus A380 | Type codes A38x |
|
||||
| `b737` | Boeing 737 family | Type codes B73x, B3xM |
|
||||
| `regional-jet` | CRJ, E-Jets, Fokker | — |
|
||||
| `light-prop` | Cessna, Piper, Cirrus | Category 2 (Light), 12 (Ultralight) |
|
||||
| `turboprop` | ATR, Dash-8, Saab | — |
|
||||
| `helicopter` | All rotorcraft | Category 8 (Rotorcraft) |
|
||||
| `bizjet` | Gulfstream, Citation, Learjet | — |
|
||||
| `glider` | Sailplanes | Category 9 (Glider) |
|
||||
| `fighter` | Military fast-movers | Category 7 (High-perf) |
|
||||
| `drone` | UAVs | Category 14 (UAV) |
|
||||
| `generic` | Fallback for unknown categories | Category 0, 1, default |
|
||||
|
||||
Models are optimised GLB files (no Draco compression — avoids external WASM decoder dependency) served from Cloudinary CDN (local backups in `public/models/aircraft/`). A second-tier mapping from ICAO type codes (A320, B738, etc.) refines the assignment when type data is available via the readsb feed.
|
||||
|
||||
- **Smooth animation**: Catmull-Rom spline trails, per-frame interpolation between polls
|
||||
- **Glassmorphism**: `backdrop-blur-2xl`, `bg-black/60`, `border-white/[0.08]`
|
||||
- **Spring physics**: All UI transitions use spring easing
|
||||
@ -84,15 +109,11 @@ src/
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Required | Description |
|
||||
| ----------------------- | -------- | ------------------------------- |
|
||||
| `OPENSKY_CLIENT_ID` | No | OAuth2 client ID (recommended) |
|
||||
| `OPENSKY_CLIENT_SECRET` | No | OAuth2 client secret |
|
||||
| `OPENSKY_USERNAME` | No | Basic auth username (legacy) |
|
||||
| `OPENSKY_PASSWORD` | No | Basic auth password (legacy) |
|
||||
| `NEXT_PUBLIC_GA_ID` | No | Google Analytics measurement ID |
|
||||
| Variable | Required | Description |
|
||||
| ------------------- | -------- | ------------------------------- |
|
||||
| `NEXT_PUBLIC_GA_ID` | No | Google Analytics measurement ID |
|
||||
|
||||
Without credentials, anonymous access is used (~10 requests/minute).
|
||||
No API keys are needed. Flight data comes from public ADS-B APIs with a built-in 3-tier fallback chain (airplanes.live → adsb.lol → OpenSky).
|
||||
|
||||
## License
|
||||
|
||||
|
||||
Reference in New Issue
Block a user