Commit Graph

21 Commits

Author SHA1 Message Date
748df761bf data: add CalendarPrefs (hidden calendar ids in DataStore) 2026-06-08 17:47:55 +02:00
d13f2f07a5 data: add CalendarRepository + Impl with SharedFlow re-emit on data-source ticks 2026-06-08 17:47:13 +02:00
7abb2e6ab4 data: add CalendarDataSource seam returning domain lists (not Cursors)
Deviation from Plan 02: changing from Cursor-returning interface to
domain-returning interface so the repository unit tests can use a simple
fake without constructing ContentObserver/Handler/Looper on the JVM
(which would either crash or no-op via the mockable.jar stubs).
2026-06-08 17:44:19 +02:00
fb003d8806 data: add ColumnReader.toEventDetailCore() and toAttendee() mappers 2026-06-08 17:42:42 +02:00
40b531fa52 data: add ColumnReader.toEventInstance() with defensive validation (§8) 2026-06-08 17:41:29 +02:00
0e4c47febe data: add ColumnReader abstraction + Cursor.toCalendarSource mapper
Deviation from Plan 02: the JVM mockable-android.jar stubs every Cursor
method even with isReturnDefaultValues=true (returns null/0 regardless of
the underlying MatrixCursor backing). Introduce an internal ColumnReader
interface so mappers stay pure-Kotlin and JVM-testable via MapColumnReader,
while production reads through CursorColumnReader.
2026-06-08 17:40:37 +02:00
fb723fba68 data: add CalendarContract column projections + indices
Some checks failed
Build and Release to F-Droid / ci (push) Has been cancelled
Build and Release to F-Droid / build-and-deploy (push) Has been cancelled
2026-06-08 17:37:23 +02:00
af75965a31 domain: add pure-Kotlin models (CalendarSource, EventInstance, EventDetail, …) 2026-06-08 17:36:39 +02:00
1b456d2133 data: add TimeBridge helpers for epoch-millis ↔ kotlin.time.Instant 2026-06-08 17:35:49 +02:00
a826e82bdc build: add kotlinx-datetime, coroutines, turbine, hilt-nav-compose, lifecycle-compose 2026-06-08 17:32:45 +02:00
Jean-Luc Makiola
ee14706d91 fix(build): revert ui-tooling-preview to implementation scope
Some checks failed
CI / ci (push) Successful in 10m50s
Build and Release to F-Droid / ci (push) Failing after 14m22s
Build and Release to F-Droid / build-and-deploy (push) Has been skipped
The previous batch fix tried to move ui-tooling-preview to
debugImplementation per a reviewer suggestion, but @Preview is used
in MainActivity.kt which lives in the main source set, so the
annotation class must be available at release-build compile time.

Moving @Preview composables to a debug-only source set would let the
dep stay debug-scoped - that is a Plan 02+ refactor, not foundation
work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 16:06:49 +02:00
Jean-Luc Makiola
376663b0d8 chore: batch fix final-review findings on Plan 01
- ROADMAP: mark v0.1 (Foundation & CI) as complete
- REQUIREMENTS: move Foundation & CI from Active to Validated (shipped)
- AndroidManifest: drop redundant android:label and android:theme on
  MainActivity - both inherited from <application>
- build.gradle.kts: move ui-tooling-preview to debugImplementation
  (@Preview annotations are dev-only; release APK stays smaller)

All foundation verification (lint + test + assembleDebug) still green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 16:04:23 +02:00
Jean-Luc Makiola
686aee9109 build: wire signing config from key.properties when present
The release workflow (release.yaml) drops a key.properties at project
root and an upload-keystore.jks in app/ from Gitea secrets. This
commit makes Gradle read them when present, configure a 'release'
signing config, and attach it to the release build type. When the
files are absent (local debug builds, fresh clones), the signing
config block is skipped and release builds emit unsigned APKs - that
is the intended local behavior; only CI tags signed releases.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:52:40 +02:00
Jean-Luc Makiola
0593b9c60f test: add UI smoke test for MainActivity placeholder
createAndroidComposeRule<MainActivity>() launches the activity in the
test process and verifies both app_name and app_tagline texts render
on the placeholder screen. Uses JUnit 4 + AndroidJUnit4 runner -
instrumented tests on Android still don't support JUnit Jupiter.

Test compiles (assembleDebugAndroidTest passes); execution requires
an emulator/device, performed in CI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:45:17 +02:00
Jean-Luc Makiola
dea5490bcf feat: scaffold CalendulaApp + MainActivity with themed placeholder
CalendulaApp registers the Hilt component graph. MainActivity uses
enableEdgeToEdge() and renders a centered placeholder showing app
name + tagline via CalendulaTheme. PlaceholderPreview lets the IDE
preview the layout. Resolves the pre-existing MissingClass lint
error from the manifest reference.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:43:17 +02:00
Jean-Luc Makiola
4fe8cd12cb feat: M3 Expressive theme with dynamic color + fallback scheme from slate seed
CalendulaSeed (0xFF5C6B7A) anchors the design palette. Theme picks
Dynamic Color on API 31+ when enabled (default true) and falls back
to a hand-tuned Light/Dark scheme otherwise. CalendulaTypography is
the M3 Expressive default for V1 - custom type scale lands in a
later UI-design iteration.

ColorSchemeTest pins the seed value (3 unit tests, all pass).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:39:28 +02:00
Jean-Luc Makiola
e4f445ac75 fix(build): bump compileSdk 36 -> 37 for Material 3 Expressive alpha
Material 3 Expressive 1.5.0-alpha21 transitively requires
material-ripple-android:1.12.0-alpha03, which mandates compileSdk >= 37
via its AAR metadata. The Android SDK platform 37.0 was installed
locally (already available as a preview).

targetSdk stays at 36 - we compile against API 37 only for the new
material-ripple constants, not to opt into runtime behavior changes.
targetSdk will follow when API 37 reaches stable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:34:36 +02:00
Jean-Luc Makiola
defc7795ad feat: adaptive launcher icon - '1' on slate squircle (kalendae)
Static stylized '1' on a slate (0xFF5C6B7A) background. The numeral
references kalendae, the Latin word for 'first day of the month' that is
the etymological root of both 'Calendar' and 'Calendula'. Adaptive icon
spec: foreground vector path, monochrome variant for themed icons (API
33+), no PNG fallback needed (minSdk 29 > 26).

Visual refinement is expected during the UI design iteration; this is
the foundational shape and meaning.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:28:27 +02:00
Jean-Luc Makiola
b20da4d4c6 feat: add android manifest, strings (DE+EN), colors, base theme
READ_CALENDAR permission declared. Strings split into English master
(values/) and German (values-de/) with the Loading/Failure/Success
generic state strings used across screens. Backup rules let DataStore
back up by default with no file-based content. Theme stub delegates
real theming to Compose; the Activity-level XML theme only sets
transparent system bars and dark-mode hint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:23:52 +02:00
Jean-Luc Makiola
8312bc6e0c chore(gradle): fix code-review findings on app module setup
- Restore 4-space indent on kotlin-compose plugin alias (regression from
  the previous cleanup commit)
- Fix invalid ProGuard rule: HiltAndroidApp is an annotation type, not
  a class - use '-keep @dagger.hilt.android.HiltAndroidApp class *' to
  actually retain the @HiltAndroidApp-annotated Application
- Remove vectorDrawables.useSupportLibrary - dead config since minSdk 29
  (native VectorDrawable support since API 21)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:22:07 +02:00
Jean-Luc Makiola
a9c141f146 chore: configure :app module gradle build
Compose with Material 3 Expressive (1.5.0-alpha21 explicit override of
BOM stable), Hilt 2.59.2 + KSP 2.3.9, DataStore. Single-module project.
JVM 17 + Kotlin 2.3.21. JUnit Jupiter 6.1.0 unified (jupiter + platform).
testOptions opts into JUnit Platform so JUnit5/6 tests get discovered.

Note: kotlin-android plugin removed — AGP 9.0+ provides built-in Kotlin
support and the plugin now hard-errors when applied alongside AGP 9.x.
kotlin-compose plugin retained (separate Compose compiler plugin).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 15:16:36 +02:00