Passwords for the release keystore were committed in plaintext to a
public repo. Move them to gitignored local.properties with an
environment-variable fallback. Keystore file itself stays in $HOME.
Add a full-screen update checker accessible from a button at the
bottom of the settings page. It queries the fork's GitHub latest
release and can download + install the APK in place.
- UpdateRepository (core/data): fetch releases/latest via GitHub API,
parse tag/description/APK asset, stream APK download to cacheDir
- VersionComparator (core/domain): compare 4.4.6-ba7opf.N style tags
(base version first, then build number; v-prefix tolerant) + tests
- IMainContainer/MainContainer: inject updateRepo
- UpdateCheckerScreen (feature/settings): shows current version,
checks for updates, displays latest version + release notes, and a
Download & install button; FileProvider hands the APK to the
system installer
- SettingsScreen: bottom entry button, full-screen page toggle
- AndroidManifest: REQUEST_INSTALL_PACKAGES permission + FileProvider
- i18n strings (en/zh)
Port the upstream drag-reorder pattern (dragHandle/draggedVisual/
autoScroll/DragRowState) so custom data source rows can be reordered
by long-pressing the handle icon, replacing the old move-up button.
- Add 40dp drag-handle box at row start with long-press gesture
- Live reorder while dragging (neighbour squeeze + spring settle)
- Edge auto-scroll during drag
- Keep per-source enabled checkbox + HTTP status label
This file also carries the #242 data-source dialog UI (enabled
checkbox, status code label, restore-default button) which shares
the same sourceSection function and cannot be cleanly split.
- onStationAGrid/onStationBGrid store the trimmed upper-cased grid instead
of the raw input (ol63 used to stay lowercase in the UI)
- drop the local latLonToGrid/gridToLatLon copies and reuse the domain
QthConverter, removing the drift risk between two implementations
- inject computeDispatcher (default Dispatchers.Default, no behaviour
change) so the pass computation is unit-testable on a test scheduler
- add MutualViewModelTest (15 cases): init prefill, grid/lat-lon linkage,
error paths, main-list reuse, fallback search, sorting, clearError
- Point the built-in SatNOGS source at db.satnogs.org/api/tle/?format=3le
(the CelesTrak satnogs group is a separate, slower subset); rename the
old CelesTrak source to 'CelesTrak SatNOGS'.
- Add a one-time migration in SettingsRepo: installed apps that already
persisted a satelliteUrls list containing the old CelesTrak SatNOGS URL
get the real SatNOGS TLE URL inserted right after it.
- Dedupe imported satellites by catnum and radios by uuid in
DatabaseRepo.updateFromRemote so multiple sources don't insert the
same primary key twice.
- Test: importing JAMX-0825b (NORAD 98248) from the real SatNOGS source.
Replace the radar page calendar action with the map icon and route the action through the Passes map flow so the Passes navigation item remains selected.
Start AMSAT status prefetch when the app enters foreground and share the in-flight request with the status page fetch path to avoid duplicate network requests.
When adjusting RX in passband mode (via +/- buttons or slider), the old
code used TransponderMapper.mapDownlinkToUplink (pure passband mapping
without Doppler compensation), producing ~10kHz error at LEO velocities.
Fix: use DopplerFrequencyCalculator.computeUplinkFromDownlinkWithOffset
for the full TX-from-RX round-trip, matching the RX→PASSBAND button
onClick logic. Also fixed frame mismatch: position now uses txLow/txRange
(Doppler-shifted frame) consistently.
Store the offset (kHz) per NORAD catalog id in SharedPreferences so
each satellite's last entered offset is restored when reopening the
frequency calculator.
- Adjust ic_satellite_alt translateY from -226.13 to -230.5 so icon
is centered vertically (not clipped at bottom)
- Replace ic_match with ic_radio_tower (MDI) for Mutual page
Port upstream PR #234 to fork main:
- New feature:status module (SatStatusScreen, SatStatusViewModel)
- New AmSatRepository + IAmSatRepository + SatStatus models
- RemoteSource: AMSAT API methods (getAmSatCatalog, getAmSatReports)
- MainContainer/IMainContainer: DI injection
- MainTheme: AMSAT status colors (tertiary slots)
- Chinese translations added for all AMSAT strings
- 26 unit tests passing
Note: navigation entry not included — upstream PR #234 intentionally
left it out pending UI restructuring. Add AMSAT to your nav bar or
menu as desired.
Use combine(selectedIds, stationPosition) in SatelliteRepo.initRepository
so that passes are recalculated on either satellite selection change or
station position change. StateFlow already emits distinct values.
- isNamedLinearTransponder: match ' Lin' prefix (AO-7 style) and
add fallback branch (hasLinearName && hasLinearMode) for entries
with 'Linear'/'Lin' but no 'transponder' word (AO-7, AO-73)
- add deduplicateTransponders: merge entries sharing the same
uplink/downlink frequency range, preferring non-CW entry
(AO-7 Mode A had separate SSB and CW entries; JO-97 had
separate CW and SSB Transponder entries)
- apply dedup in CalculatorPage filter chain
- 6 new tests, 23 total, all passing
Match page UI:
- Always show a meaningful status line in the top bar instead of leaving the second row blank on first entry.
- Add a compact status chip for waiting, calculating, result, no-match, and error states.
- Remove the duplicate intro card so the first screen starts directly with station inputs.
Pass list sun times:
- Compute sunrise/sunset from each visible date group's 00:00 in the selected timezone.
- Avoid using an arbitrary pass AOS as the rise/set search start, which could jump later-day headers to the following day's events.