From 93ca38d974dd7664231ee0dea148d48e5d5764ed Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Wed, 1 Jul 2026 10:19:23 +0200 Subject: [PATCH] feat(contacts): declare READ_CONTACTS + read contact special-dates Codeberg #15, foundation for the contact special-dates calendars. Declares the optional, feature-gated READ_CONTACTS permission (never requested at startup) and adds the offline, read-only contacts reader. - AndroidManifest: READ_CONTACTS with a comment documenting the opt-in/offline one-way-mirror contract. - domain/contacts: SpecialDateType + ContactSpecialDate model and a pure parseContactEventDate covering full (yyyy-MM-dd), year-less (--MM-dd) and compact (yyyyMMdd) shapes, with Feb-29 handling via a leap anchor. - data/contacts: ContactSpecialDatesDataSource querying ContactsContract.Data Event rows, split by TYPE, deduped per (contact, type); returns empty without the permission so sync can degrade to a stalled state. Hilt-bound. - Unit tests for the date parser (full/year-less/compact/Feb-29/malformed). Co-Authored-By: Claude Opus 4.8 (1M context) --- app/src/main/AndroidManifest.xml | 9 ++ .../contacts/ContactSpecialDatesDataSource.kt | 98 ++++++++++++++ .../calendula/data/di/DataModule.kt | 8 ++ .../domain/contacts/ContactSpecialDate.kt | 122 ++++++++++++++++++ .../domain/contacts/ContactSpecialDateTest.kt | 64 +++++++++ 5 files changed, 301 insertions(+) create mode 100644 app/src/main/java/de/jeanlucmakiola/calendula/data/contacts/ContactSpecialDatesDataSource.kt create mode 100644 app/src/main/java/de/jeanlucmakiola/calendula/domain/contacts/ContactSpecialDate.kt create mode 100644 app/src/test/java/de/jeanlucmakiola/calendula/domain/contacts/ContactSpecialDateTest.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 29f9c5e..8ad7750 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,6 +5,15 @@ + +