Skip to content

Commit 39b786a

Browse files
committed
v4.4.0 - Implemented CAT and SSTV support in RadarScreen
1 parent 79809aa commit 39b786a

4 files changed

Lines changed: 126 additions & 13 deletions

File tree

CLAUDE.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# CLAUDE.md
2+
3+
## Project Overview
4+
5+
Look4Sat is an open-source, fully offline Android satellite tracker and pass predictor. It tracks 9000+ active
6+
satellites using TLE/OMM data from Celestrak/SatNOGS, calculates orbital positions via SGP4/SDP4 models, and displays
7+
passes relative to the user's location. Features include polar radar visualization, SSTV image decoding, satellite
8+
ground track mapping, and pass predictions up to 10 days ahead. No ads, no tracking, no network required after initial
9+
data download.
10+
11+
## Architecture
12+
13+
**MVI (Model-View-Intent)** with unidirectional data flow:
14+
- `State` data class → exposed via `StateFlow` from ViewModel
15+
- `Action` sealed interface → user intents dispatched to ViewModel's `onAction()`
16+
- Jetpack Compose UI observes state and recomposes reactively
17+
18+
**Clean Architecture layers:**
19+
20+
| ------------------------ | --------------------------------------------------------------------- |
21+
| Module | Responsibility |
22+
|--------------------------|-----------------------------------------------------------------------|
23+
| `app` | Entry point. Aggregates all modules |
24+
| `core:data` | Android library. Room DB, OkHttp networking, repo implementations |
25+
| `core:domain` | Pure Kotlin (JVM). Orbital math (SGP4/SDP4), models, repo contracts |
26+
| `core:presentation` | Android library. Compose theme, shared UI components, NavKeys |
27+
| `feature:map` | OSMDroid map with ground tracks |
28+
| `feature:passes` | Pass predictions and upcoming events |
29+
| `feature:radar` | Polar radar view of satellite positions, SSTV image decoding |
30+
| `feature:satellites` | Satellite list, filtering, selection |
31+
| `feature:settings` | User preferences |
32+
| ------------------------ | --------------------------------------------------------------------- |
33+
34+
- `feature:*` modules depend only on `core:domain` + `core:presentation`. Features never depend on each other.
35+
36+
## Build & Run
37+
38+
```shell
39+
# Debug build
40+
./gradlew assembleDebug
41+
42+
# Release build (minified, shrunk resources)
43+
./gradlew assembleRelease
44+
45+
# Run tests
46+
./gradlew test
47+
```
48+
49+
- **Min SDK**: 24 | **Target SDK**: 36 | **JDK**: 17
50+
- **Gradle**: Uses version catalog (`gradle/libs.versions.toml`) + convention plugins in `build-logic/`
51+
52+
## Key Libraries
53+
54+
- **Compose** (BOM 2026.05.01) + Material3 Adaptive
55+
- **Navigation3** (type-safe, uses `@Serializable` NavKeys)
56+
- **Room** (KSP code generation) for local satellite/TLE storage
57+
- **OkHttp** 5.x for TLE downloads
58+
- **OSMDroid** for map rendering
59+
- **Kotlin Serialization** for navigation args and data parsing
60+
- **Coroutines** + `StateFlow` for async/reactive patterns
61+
62+
## Conventions
63+
64+
- **Minimal dependencies**: Avoid adding libraries when a simple manual solution exists. Fewer deps = less maintenance.
65+
- **DI**: Manual — ViewModels use companion `factory()` methods with `IMainContainer` interface.
66+
- **Navigation**: Type-safe Compose Navigation3 with `@Serializable` data classes as nav keys.
67+
- **State naming**: `<Feature>State` data class + `<Feature>Action` sealed interface per feature.
68+
- **No feature-to-feature deps**: All cross-feature communication goes through core layers.
69+
- **Localization**: 7 languages (en, es, ru, si, tr, uk, zh).
70+
71+
## Data Formats & Migration
72+
73+
**TLE vs. OMM/CSV format:**
74+
75+
Look4Sat supports both TLE and OMM (Orbit Mean-Elements Message) formats for backward compatibility:
76+
77+
- **TLE format**: Traditional 3-line element format (deprecated). NORAD catalog numbers are 5-digit integers, which
78+
are running out of space. Celestrak has signaled that TLE format will eventually be phased out.
79+
- **OMM/CSV format**: The future standard. CSV files contain the same orbital parameters as TLE but use ISO 8601
80+
timestamps and support larger NORAD IDs. Celestrak and SatNOGS already provide OMM data in CSV format.
81+
82+
**Current implementation:**
83+
- `DataParser.kt` handles both `parseTLEStream()` and `parseCSVStream()` seamlessly
84+
- TLE data is downloaded from configured sources and stored in Room database
85+
- When downloading satellite data, the app automatically detects format and parses accordingly
86+
- Both formats produce identical `OrbitalData` objects, ensuring transparent format switching
87+
88+
**Migration path:**
89+
As NORAD catalog space becomes constrained, OMM/CSV will become the primary format. Look4Sat is already positioned
90+
to handle this transition without code changes—existing users can continue using TLE files while new sources transition
91+
to OMM/CSV automatically.
92+
93+
## Code Style
94+
95+
- Prefer **short, focused functions** — single responsibility, easy to read.
96+
- **Exceptions**: Composable functions and math-heavy algorithms (SGP4/SDP4) may be longer.
97+
- Strict code style — no dead code, no unused imports, consistent formatting.
98+
99+
## Roadmap
100+
101+
- **KMP migration**: `core:domain` is to become a fully shareable KMM module. Keep it pure Kotlin/JVM.
102+
103+
## Gotchas
104+
105+
- Orbital math lives in `core:domain/predict/` — it's dense vector math (SGP4/SDP4). Tread carefully.
106+
- TLE/OMM data must be refreshed weekly for accurate predictions (satellite orbits decay). TLE format is legacy and
107+
will eventually be deprecated in favor of OMM/CSV as NORAD catalog numbers approach the 5-digit limit.
108+
- SSTV decoding in `feature:radar` is experimental; image quality depends on signal strength during satellite pass.
109+
- `build-logic/convention/` contains all shared Gradle configuration — edit there, not in individual modules.
110+
- ProGuard is enabled for release builds — don't add reflection-based libs or any other dependencies without asking.

core/presentation/src/main/res/values/strings.xml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@
4949
\n\nPlease update the database at least weekly to get accurate predictions.</string>
5050
<string name="pass_whatsnew_title" translatable="false">What\'s new in Look4Sat</string>
5151
<string name="pass_whatsnew_message" translatable="false">
52-
* Implemented Swipe-to-Focus behavior for passes - swipe right on a pass to focus it, and left - to unfocus
53-
\n\n* Implemented preserving the pass selection between the Radar and Map screens. Not every satellite has
54-
a pass overhead every day, so this should make it only slightly easier to keep track of certain satellites.
52+
* Merged RadarScreen and RadioControlScreen functionality
53+
\n\n* Added SSTV image decoding functionality to RadarScreen
54+
\n\n* Added colored elevation and decay check to satellite passes
5555
</string>
5656

5757
<!-- Radar screen -->
@@ -184,12 +184,14 @@
184184

185185
<string name="prefs_outro_title">I would like to say thanks to</string>
186186
<string name="prefs_outro_thanks" translatable="false">
187-
• Look4Sat users and contributors!
188-
\n• David A. B. Johnson (predict4java)
189-
\n• Dave Moten (predict4java)
190-
\n• Alexandru Csete (Gpredict)
191-
\n• Dr T.S. Kelso (Celestrak)
192-
\n• Libre Space Foundation (SatNOGS)</string>
187+
* Look4Sat users and contributors!
188+
\n* David A. B. Johnson (predict4java)
189+
\n* Dave Moten (predict4java)
190+
\n* Alexandru Csete (Gpredict)
191+
\n* Dr T.S. Kelso (Celestrak)
192+
\n* Libre Space Foundation (SatNOGS)
193+
\n* xdsopl and Robot36 contributors!
194+
</string>
193195
<string name="prefs_outro_license">The app comes with no warranty</string>
194196

195197
</resources>
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
* Implemented Swipe-to-Focus behavior for passes - swipe right on a pass to focus it, and left - to unfocus
2-
* 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.
1+
* Merged RadarScreen and RadioControlScreen functionality
2+
* Added SSTV image decoding functionality to RadarScreen
3+
* Added colored elevation and decay check to satellite passes

gradle/libs.versions.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
[versions]
22
#noinspection UnusedVersionCatalogEntry
3-
appVersionCode = "432"
3+
appVersionCode = "440"
44
#noinspection UnusedVersionCatalogEntry
5-
appVersionName = "4.3.2"
5+
appVersionName = "4.4.0"
66
#noinspection GradleDependency,UnusedVersionCatalogEntry
77
compileSdk = "36"
88
#noinspection UnusedVersionCatalogEntry

0 commit comments

Comments
 (0)