All checks were successful
CI / ci (push) Successful in 4m38s
Documentation pass after the 2.0 milestone:
- docs/ARCHITECTURE.md — principles (provider as single source of truth,
observer-driven UI, JVM-first tests, no network), layer + reminder
mermaid diagrams, navigation (overlay/held-key, no nav lib), and the
provider lessons (recurring-write invariants, conflict snapshots)
- docs/README.md — map of what documentation lives where, incl. the
convention that superpowers/ plans are historical artifacts while
.planning/ stays current
- README.md — showcase layout (centered header, badges, screenshot
gallery from the fastlane assets, grouped features, install/build/
architecture/roadmap sections); renders on Gitea
- .planning/{PROJECT,REQUIREMENTS,STATE}.md unstaled: read-only-V1 talk
removed, V1/V2 checklists marked shipped, state points at v3 + the
Locations & People go/no-go
release.yaml gains a gitea-release job: on every tag push it extracts the
tag's CHANGELOG section and creates a Gitea release with it as the notes.
No APK assets — distribution stays with the F-Droid repo. Idempotent
(skips an existing release), gated on the test job only so notes appear
even when the F-Droid upload hiccups.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
104 lines
4.3 KiB
Markdown
104 lines
4.3 KiB
Markdown
<div align="center">
|
||
|
||
<img src="fdroid-metadata/de.jeanlucmakiola.calendula/en-US/icon.png" width="112" alt="Calendula icon">
|
||
|
||
<h1>Calendula</h1>
|
||
|
||
<p><strong>A modern Material 3 Expressive calendar for Android.</strong><br>
|
||
Reads, writes, and reminds — on top of the system calendar, with zero network access.</p>
|
||
|
||
<p>
|
||
<a href="https://gitea.jeanlucmakiola.de/makiolaj/calendula/actions"><img src="https://gitea.jeanlucmakiola.de/makiolaj/calendula/actions/workflows/ci.yaml/badge.svg?branch=main" alt="CI"></a>
|
||
<img src="https://img.shields.io/badge/Android-10%2B-3DDC84?logo=android&logoColor=white" alt="Android 10+">
|
||
<img src="https://img.shields.io/badge/Kotlin-Compose-7F52FF?logo=kotlin&logoColor=white" alt="Kotlin + Compose">
|
||
<img src="https://img.shields.io/badge/Material%203-Expressive-4285F4" alt="Material 3 Expressive">
|
||
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-green" alt="MIT License"></a>
|
||
</p>
|
||
|
||
<p>
|
||
<img src="fdroid-metadata/de.jeanlucmakiola.calendula/en-US/phoneScreenshots/01-week.png" width="19%" alt="Week view">
|
||
<img src="fdroid-metadata/de.jeanlucmakiola.calendula/en-US/phoneScreenshots/02-month.png" width="19%" alt="Month view">
|
||
<img src="fdroid-metadata/de.jeanlucmakiola.calendula/en-US/phoneScreenshots/04-detail.png" width="19%" alt="Event detail">
|
||
<img src="fdroid-metadata/de.jeanlucmakiola.calendula/en-US/phoneScreenshots/05-edit.png" width="19%" alt="Event form">
|
||
<img src="fdroid-metadata/de.jeanlucmakiola.calendula/en-US/phoneScreenshots/06-onboarding.png" width="19%" alt="Reminder onboarding">
|
||
</p>
|
||
|
||
</div>
|
||
|
||
Calendula is named after the flower whose name — like the word *calendar* —
|
||
comes from the Latin *kalendae*, the first day of the month. It lives
|
||
entirely on top of Android's `CalendarContract`: any calendar synced to your
|
||
device (CalDAV via DAVx5, Google, local, WebCal subscriptions, …) simply
|
||
appears, and everything you create or edit syncs back the same way. No own
|
||
database, no sync stack reinvented.
|
||
|
||
## ✨ Features
|
||
|
||
**Calendar**
|
||
|
||
- Month, week, and day views with a one-tap view switcher
|
||
- Full event details — attendees and their responses, reminders, recurrence
|
||
(humanized), availability, visibility, foreign time zones
|
||
- Per-calendar visibility toggle, grouped by account
|
||
|
||
**Editing**
|
||
|
||
- Create, edit, and delete events — including recurring events with scoped
|
||
writes: *only this event*, *this and all following*, or *the whole series*
|
||
- Recurrence picker with one-tap presets and custom rules (interval, weekday
|
||
toggles, end conditions); rules it can't express are preserved verbatim
|
||
- Conflict-safe saves: if an event changed elsewhere while you were editing,
|
||
Calendula asks instead of silently overwriting
|
||
- Read-only calendars (WebCal, birthdays) are detected and respected
|
||
|
||
**Reminders**
|
||
|
||
- Event reminders delivered by Calendula itself as notifications —
|
||
essential when it's your only calendar app, since Android delegates
|
||
reminder delivery to calendar apps
|
||
- Tap a reminder to land on the event
|
||
|
||
**Design & privacy**
|
||
|
||
- Real Material 3 Expressive throughout — dynamic color (Android 12+),
|
||
expressive motion and shapes, light/dark theme
|
||
- German and English UI, per-app language setting
|
||
- **Zero telemetry, zero analytics, no internet permission** — your data
|
||
never leaves the device
|
||
|
||
## 📦 Install
|
||
|
||
Calendula ships through a self-hosted F-Droid repository (releases are
|
||
built and published automatically from version tags). Alternatively, build
|
||
from source — see below.
|
||
|
||
## 🛠 Building
|
||
|
||
Requires Android SDK 36+ and JDK 17. The Gradle wrapper is checked in:
|
||
|
||
```bash
|
||
./gradlew assembleDebug # debug APK
|
||
./gradlew test # JVM unit tests
|
||
./gradlew lint # Android lint
|
||
```
|
||
|
||
If your default JDK is not 17, set `JAVA_HOME` explicitly.
|
||
|
||
## 🏗 Architecture
|
||
|
||
Single-activity Compose app, layered `UI → Repository → DataSource →
|
||
CalendarContract`, observer-driven refresh, JVM-first tests. The full tour —
|
||
including the recurring-write and reminder pipelines — lives in
|
||
[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
|
||
|
||
## 🗺 Roadmap
|
||
|
||
Shipped: read (v1.0), write (v1.1–v2.0), reminder delivery (v1.4).
|
||
Next up: power-user features — widget, search, tablet layouts. The living
|
||
roadmap is in [.planning/ROADMAP.md](.planning/ROADMAP.md), the release
|
||
history in [CHANGELOG.md](CHANGELOG.md).
|
||
|
||
## 📜 License
|
||
|
||
[MIT](LICENSE) — Jean-Luc Makiola, 2026
|