# 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) → 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.*)`.