mirror of
https://github.com/pawelorzech/SunZones.git
synced 2026-01-29 19:54:26 +00:00
55 lines
3 KiB
Markdown
55 lines
3 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
## Build Commands
|
||
|
||
**Requires Java 17** — the system default may be Java 25 which Gradle 8.11.1 doesn't support:
|
||
```bash
|
||
export JAVA_HOME="/opt/homebrew/Cellar/openjdk@17/17.0.18/libexec/openjdk.jdk/Contents/Home"
|
||
./gradlew assembleDebug
|
||
```
|
||
|
||
Clean build:
|
||
```bash
|
||
./gradlew clean assembleDebug
|
||
```
|
||
|
||
Android SDK is at `~/Library/Android/sdk` (set in `local.properties`).
|
||
|
||
## Architecture
|
||
|
||
Clean MVVM with Hilt DI. Single-activity Compose app — no navigation library, just one screen with a modal bottom sheet.
|
||
|
||
**Data flow:**
|
||
```
|
||
Room DB (Flow) → LocationDao → LocationRepository → GetLocationsUseCase
|
||
→ maps each LocationEntity through CalculateSunTimesUseCase → SunLocation
|
||
→ MainViewModel (StateFlow<MainUiState>) → Compose (collectAsState)
|
||
```
|
||
|
||
**Layer responsibilities:**
|
||
- `data/local/` — Room entity, DAO, database. `LocationEntity` stores lat/lng, timezone ID string, display order
|
||
- `data/repository/` — Thin wrapper over DAO, adds `replaceCurrentLocation` (delete old + insert)
|
||
- `domain/usecase/` — `CalculateSunTimesUseCase` uses `commons-suncalc` library to compute sunrise/sunset/progress for a given entity and its stored timezone. `GetLocationsUseCase` maps the Room Flow through calculations
|
||
- `domain/model/` — `SunLocation` is the UI-ready model with computed fields (dayLengthFormatted, sunProgress 0–1, isDaytime)
|
||
- `ui/main/` — `MainViewModel` collects locations flow + refreshes every 60s. `MainScreen` is a `HorizontalPager` of `SunCard` composables with a FAB
|
||
- `ui/addlocation/` — `AddLocationViewModel` handles Geocoder search and GPS via `FusedLocationProviderClient`. Timezone is resolved using `android.icu.util.TimeZone.getAvailableIDs(countryCode)` from the Geocoder's Address
|
||
- `di/AppModule.kt` — Provides Room DB, DAO, Geocoder, FusedLocationProviderClient as Hilt singletons
|
||
|
||
**Key design decisions:**
|
||
- Timezone stored per location as IANA string (e.g. "Asia/Tokyo"). Resolved at save time via Android ICU + Geocoder country code (NOT `timezonemap` library — that crashes on Android due to missing `zstd-jni` native libs)
|
||
- Sun progress (0–1 float) calculated against the location's local time, not device time
|
||
- SunCard gradient background changes by time-of-day bucket (sunrise/morning/midday/afternoon/sunset/twilight/night)
|
||
- Long-press on card to delete (avoids gesture conflict with HorizontalPager swipe)
|
||
|
||
## Key Dependencies
|
||
|
||
- `org.shredzone.commons:commons-suncalc:3.11` — sunrise/sunset/sun position calculations
|
||
- `com.google.android.gms:play-services-location` — FusedLocationProviderClient for GPS
|
||
- Android `Geocoder` — forward search (city name → lat/lng) and reverse geocode (lat/lng → city name + country code)
|
||
- `android.icu.util.TimeZone` — built-in Android API for country code → timezone ID lookup (no extra dependency)
|
||
|
||
## i18n
|
||
|
||
English default in `res/values/strings.xml`, Polish translations in `res/values-pl/strings.xml`. All user-visible strings use `stringResource(R.string.*)`.
|