SunZones/CLAUDE.md
2026-01-27 16:33:25 +01:00

55 lines
3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 01, 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 (01 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.*)`.