From 39b786ae82bfab5cdc86a308c6bd4a684acf9cdd Mon Sep 17 00:00:00 2001 From: Arty Bishop Date: Tue, 2 Jun 2026 19:42:01 +0100 Subject: [PATCH] v4.4.0 - Implemented CAT and SSTV support in RadarScreen --- CLAUDE.md | 110 ++++++++++++++++++ .../src/main/res/values/strings.xml | 20 ++-- .../android/en-US/changelogs/default.txt | 5 +- gradle/libs.versions.toml | 4 +- 4 files changed, 126 insertions(+), 13 deletions(-) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..7048c4fc --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,110 @@ +# CLAUDE.md + +## Project Overview + +Look4Sat is an open-source, fully offline Android satellite tracker and pass predictor. It tracks 9000+ active +satellites using TLE/OMM data from Celestrak/SatNOGS, calculates orbital positions via SGP4/SDP4 models, and displays +passes relative to the user's location. Features include polar radar visualization, SSTV image decoding, satellite +ground track mapping, and pass predictions up to 10 days ahead. No ads, no tracking, no network required after initial +data download. + +## Architecture + +**MVI (Model-View-Intent)** with unidirectional data flow: +- `State` data class → exposed via `StateFlow` from ViewModel +- `Action` sealed interface → user intents dispatched to ViewModel's `onAction()` +- Jetpack Compose UI observes state and recomposes reactively + +**Clean Architecture layers:** + +| ------------------------ | --------------------------------------------------------------------- | +| Module | Responsibility | +|--------------------------|-----------------------------------------------------------------------| +| `app` | Entry point. Aggregates all modules | +| `core:data` | Android library. Room DB, OkHttp networking, repo implementations | +| `core:domain` | Pure Kotlin (JVM). Orbital math (SGP4/SDP4), models, repo contracts | +| `core:presentation` | Android library. Compose theme, shared UI components, NavKeys | +| `feature:map` | OSMDroid map with ground tracks | +| `feature:passes` | Pass predictions and upcoming events | +| `feature:radar` | Polar radar view of satellite positions, SSTV image decoding | +| `feature:satellites` | Satellite list, filtering, selection | +| `feature:settings` | User preferences | +| ------------------------ | --------------------------------------------------------------------- | + +- `feature:*` modules depend only on `core:domain` + `core:presentation`. Features never depend on each other. + +## Build & Run + +```shell +# Debug build +./gradlew assembleDebug + +# Release build (minified, shrunk resources) +./gradlew assembleRelease + +# Run tests +./gradlew test +``` + +- **Min SDK**: 24 | **Target SDK**: 36 | **JDK**: 17 +- **Gradle**: Uses version catalog (`gradle/libs.versions.toml`) + convention plugins in `build-logic/` + +## Key Libraries + +- **Compose** (BOM 2026.05.01) + Material3 Adaptive +- **Navigation3** (type-safe, uses `@Serializable` NavKeys) +- **Room** (KSP code generation) for local satellite/TLE storage +- **OkHttp** 5.x for TLE downloads +- **OSMDroid** for map rendering +- **Kotlin Serialization** for navigation args and data parsing +- **Coroutines** + `StateFlow` for async/reactive patterns + +## Conventions + +- **Minimal dependencies**: Avoid adding libraries when a simple manual solution exists. Fewer deps = less maintenance. +- **DI**: Manual — ViewModels use companion `factory()` methods with `IMainContainer` interface. +- **Navigation**: Type-safe Compose Navigation3 with `@Serializable` data classes as nav keys. +- **State naming**: `State` data class + `Action` sealed interface per feature. +- **No feature-to-feature deps**: All cross-feature communication goes through core layers. +- **Localization**: 7 languages (en, es, ru, si, tr, uk, zh). + +## Data Formats & Migration + +**TLE vs. OMM/CSV format:** + +Look4Sat supports both TLE and OMM (Orbit Mean-Elements Message) formats for backward compatibility: + +- **TLE format**: Traditional 3-line element format (deprecated). NORAD catalog numbers are 5-digit integers, which + are running out of space. Celestrak has signaled that TLE format will eventually be phased out. +- **OMM/CSV format**: The future standard. CSV files contain the same orbital parameters as TLE but use ISO 8601 + timestamps and support larger NORAD IDs. Celestrak and SatNOGS already provide OMM data in CSV format. + +**Current implementation:** +- `DataParser.kt` handles both `parseTLEStream()` and `parseCSVStream()` seamlessly +- TLE data is downloaded from configured sources and stored in Room database +- When downloading satellite data, the app automatically detects format and parses accordingly +- Both formats produce identical `OrbitalData` objects, ensuring transparent format switching + +**Migration path:** +As NORAD catalog space becomes constrained, OMM/CSV will become the primary format. Look4Sat is already positioned +to handle this transition without code changes—existing users can continue using TLE files while new sources transition +to OMM/CSV automatically. + +## Code Style + +- Prefer **short, focused functions** — single responsibility, easy to read. +- **Exceptions**: Composable functions and math-heavy algorithms (SGP4/SDP4) may be longer. +- Strict code style — no dead code, no unused imports, consistent formatting. + +## Roadmap + +- **KMP migration**: `core:domain` is to become a fully shareable KMM module. Keep it pure Kotlin/JVM. + +## Gotchas + +- Orbital math lives in `core:domain/predict/` — it's dense vector math (SGP4/SDP4). Tread carefully. +- TLE/OMM data must be refreshed weekly for accurate predictions (satellite orbits decay). TLE format is legacy and + will eventually be deprecated in favor of OMM/CSV as NORAD catalog numbers approach the 5-digit limit. +- SSTV decoding in `feature:radar` is experimental; image quality depends on signal strength during satellite pass. +- `build-logic/convention/` contains all shared Gradle configuration — edit there, not in individual modules. +- ProGuard is enabled for release builds — don't add reflection-based libs or any other dependencies without asking. diff --git a/core/presentation/src/main/res/values/strings.xml b/core/presentation/src/main/res/values/strings.xml index 7fe50177..979ebc62 100644 --- a/core/presentation/src/main/res/values/strings.xml +++ b/core/presentation/src/main/res/values/strings.xml @@ -49,9 +49,9 @@ \n\nPlease update the database at least weekly to get accurate predictions. What\'s new in Look4Sat - * Implemented Swipe-to-Focus behavior for passes - swipe right on a pass to focus it, and left - to unfocus - \n\n* Implemented preserving the pass selection between the Radar and Map screens. Not every satellite has - a pass overhead every day, so this should make it only slightly easier to keep track of certain satellites. + * Merged RadarScreen and RadioControlScreen functionality + \n\n* Added SSTV image decoding functionality to RadarScreen + \n\n* Added colored elevation and decay check to satellite passes @@ -184,12 +184,14 @@ I would like to say thanks to - • Look4Sat users and contributors! - \n• David A. B. Johnson (predict4java) - \n• Dave Moten (predict4java) - \n• Alexandru Csete (Gpredict) - \n• Dr T.S. Kelso (Celestrak) - \n• Libre Space Foundation (SatNOGS) + * Look4Sat users and contributors! + \n* David A. B. Johnson (predict4java) + \n* Dave Moten (predict4java) + \n* Alexandru Csete (Gpredict) + \n* Dr T.S. Kelso (Celestrak) + \n* Libre Space Foundation (SatNOGS) + \n* xdsopl and Robot36 contributors! + The app comes with no warranty diff --git a/fastlane/metadata/android/en-US/changelogs/default.txt b/fastlane/metadata/android/en-US/changelogs/default.txt index 22ccdaf6..efb1b75f 100644 --- a/fastlane/metadata/android/en-US/changelogs/default.txt +++ b/fastlane/metadata/android/en-US/changelogs/default.txt @@ -1,2 +1,3 @@ -* Implemented Swipe-to-Focus behavior for passes - swipe right on a pass to focus it, and left - to unfocus -* Implemented preserving the pass selection between the Radar and Map screens. Not every satellite has a pass overhead every day, so this should make it only slightly easier to keep track of certain satellites. +* Merged RadarScreen and RadioControlScreen functionality +* Added SSTV image decoding functionality to RadarScreen +* Added colored elevation and decay check to satellite passes diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d506f673..fe5949a1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,8 +1,8 @@ [versions] #noinspection UnusedVersionCatalogEntry -appVersionCode = "432" +appVersionCode = "440" #noinspection UnusedVersionCatalogEntry -appVersionName = "4.3.2" +appVersionName = "4.4.0" #noinspection GradleDependency,UnusedVersionCatalogEntry compileSdk = "36" #noinspection UnusedVersionCatalogEntry