Write path: - realignRecurrence now handles weekly BYDAY only. What the rule must agree with is the series *anchor*, which moves by the same wall-clock shift as the dragged occurrence — weekday survives that (uniform mod 7), day-of-month does not. BYMONTHDAY=28 with a January anchor, occurrence Feb 28 dragged to Mar 1, produced a Jan 29 anchor under a BYMONTHDAY=1 rule: a DTSTART that is not an instance of its own rule. Also refuse when the shift is not a whole number of days, which would carry a late-enough anchor across an extra midnight. - The accepted parts are now a subset of parseSimpleRecurrence's, so anything realignable is a rule the UNTIL guard can actually read. FREQ=MONTHLY;BYDAY=MO previously slipped past it and could move a series past its own end. - The UNTIL check moved to write time and picks the date the chosen scope actually starts at: the anchor for a whole-series move, the occurrence for a split, nothing for a single occurrence. It used to test the occurrence in every case and refused the ordinary drag of a bounded series' last one. - shiftedByDays preserves the instant duration for timed events, as shiftedTo already did — a month drag onto a DST changeover rewrote the whole series' DURATION. - Guard against a second drop landing while one is in flight; the shifts would compound on the re-read anchor. Gestures: - A long press that never moved wrote a reschedule: the target snaps to the 15-minute grid at pickup, so an event at 09:07 resolved to 09:00 the instant it lifted. The drop is now refused when it lands on the slot it started from. - After pickup the gesture is driven and consumed on the initial pass. Pinching mid-drag used to zoom and drag at once, then write wherever the zoom left the block; the month grid's tap layer opened the day on lift. - RTL: pointer x was mapped to columns as if the grid were LTR, so a drop landed 6-n columns away, and both ghosts used the direction-aware offset with root coordinates, mirroring them across the screen. - The month drop passes the day delta instead of a date, so the grid and the view model no longer each resolve the event's first day in their own zone.
Documentation map
Where to look for what:
| Document | What it is |
|---|---|
../CONTRIBUTING.md |
How to contribute: issue-first workflow, which branch to target, translations, the rules a change is reviewed against |
BUILDING.md |
Building from source: submodule, JDK/SDK requirements, Gradle tasks, what CI runs |
ARCHITECTURE.md |
Orientation tour: principles, layers, navigation, recurring-write / conflict / reminder pipelines, testing |
RELEASING.md |
Release process: versioning, the merge-driven pipeline, the two-forge split, secrets, key custody |
../CHANGELOG.md |
Release history (Keep a Changelog, SemVer) |
| Issues + milestones | The roadmap. What's planned, in progress, and shipped — a milestone maps to its release/vX.Y.Z branch |
../.planning/PROJECT.md |
What the project is: core value, stack + version pins, constraints, naming, forge/release infrastructure |
design/ |
Per-feature design notes kept for features whose provider behaviour is worth recording |
../fastlane/metadata/android/ |
Store metadata (single source of truth): descriptions, title, icon, screenshots (DE + EN). Harvested directly by the official F-Droid repo; transformed into the self-hosted repo layout at release time by ../scripts/fastlane_to_fdroid_localized.sh |
../fdroid-metadata/ |
App-level F-Droid control file (*.yml: Categories, License, links) for the self-hosted repo's fdroid update |
fdroid-official/ |
Recipe + notes for publishing to the official F-Droid repo (reproducible build + developer-signed binary) |
Conventions: planning lives in the issue tracker, not in this repository. The
.planning/ files that predated it (a roadmap, a development-state snapshot, and
a per-milestone requirement checklist) are gone — issues and milestones say the
same thing without going stale. PROJECT.md is what remains, and it describes
the project rather than its plan.
ARCHITECTURE.md is the authoritative orientation tour: it is updated with the
code, and is the right place for a lesson learned about the calendar provider.