Commit Graph
7 Commits
Author SHA1 Message Date
Jean-Luc Makiolaandmakiolaj ffc5900db4 Fix widget class merge, ru date crash, widget padding, form label clipping and SRV discovery (#96)
Fixes four of the five open bug reports, plus #97 (mailbox.org sign-in, reported by email).

- **#92 widgets reverting / "Can't load content"**: R8's horizontal class merging folded `TodayWidget`, `UpNextWidget`, `ListsWidget` and `WeekWidget` into one class. Glance maps providers to receivers by class name, so `TodayWidget().updateAll()` also targeted every Up Next, Lists and Week slot. Any slot without a running session got Today's composition, which is why widgets turned into the Today ring. In a 4x1 slot the ring size goes negative and Glance shows its error layout. A keep rule for `GlanceAppWidget` subclasses stops the merge. I checked the fresh `fullReleaseTest` mapping: all five classes are separate and none has a `$r8$classId`.
- **#70 crash in ru-RU**: fixed in floret-kit (jlmakiola/floret-kit#20). Its year-stripping regex broke `d MMM y 'г'.` into an unterminated quote. The new version also keeps the dot that closes the day-month part (de-DE `05.03.`). That PR is merged; the submodule points at its tip, which is on floret-kit main.
- **#86 widget padding**: when the Tasks widget drops its redundant section label (e.g. the Today list), a spacer above the list now puts the first row 8dp under the header (one `widget_tasks_header_gap` dimen shared with the preview), as in the preview, instead of 2dp.
- **#76 "Starts" clipped**: the label and values in the task form's Starts/Due rows share one line when they fit. Otherwise the values move to their own end-aligned line, using a `FlowRow` rather than a custom layout. The time can wrap under the date, and the clear button always keeps its 40dp.
- **#97 mailbox.org sign-in ("isn't a CalDAV server")**: the SRV/TXT lookup never reached the network. dnsjava was never set up for Android, so every lookup came back empty. mailbox.org's server is only published by SRV (`dav.mailbox.org`), so discovery fell back to `mailbox.org/.well-known/caldav`, which redirects to `auto.mailbox.org` and answers 405. Posteo (SRV-only, port 8443) hit the same dead end. Lookups now go through `android.net.DnsResolver.rawQuery` (minSdk is 29), so they follow the current network and honour Private DNS. SRV and TXT are queried at once under one 10s deadline, and a failure reads as no records. The wait stops as soon as the sign-in is cancelled, and answered lookups are kept for a minute so the signed-in pass does not ask again. `:caldav` only parses the raw answers (`DnsAnswers`, which replaces `DnsJavaResolver`). PRIVACY.md now says so.
  - If an email address still finds no server, the address step switches straight to a server-address field with its own explanation, rather than ending at an error. That also happens when nothing answered for the domain (a mail-only domain), with the error left visible in case it was a typo or no network, and after a sign-in on the email domain. The email (without a `mailto:` prefix) is kept as the username for the sign-in step, and Back returns to the email.

Not included: **#75** (ticking in the 2x2 widget does nothing). The widget is most likely Today, which was one of the merged classes, so this may fix it too. I couldn't show the link from the code, so the issue stays open until it's checked on a device.

Closes #70, closes #76, closes #86, closes #92, closes #97

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/agendula/pulls/96
2026-10-25 19:55:03 +01:00
7c943f4831 Start-based reminders and timed all-day reminders (#72, #78) (#88)
Beta — Codeberg pre-release / detect (push) Successful in 5s
Beta — Codeberg pre-release / beta (push) Skipped
Reminders can count from a task's start as well as its due date (#72), and each reminder on an all-day task can have its own time (#78).

## Changes
- A reminder counts from the start or the due date. Tasks with only a start date get reminders. Defaults in Settings can mix both, globally and per list.
- Each reminder on an all-day task can have its own time of day. Reminders without one ring at the all-day time set in Settings. 00:00 can't be stored, so it becomes 00:01.
- The editor shows the defaults a new task, or a newly added date, will get, and keeps them in step with dates, list and all-day until you change a reminder. What it shows is what gets saved. Removing the shown defaults now leaves the task without a reminder (Room store only; OpenTasks mode still falls back to the default).
- Switching between timed and all-day converts the reminders right away in the editor. Switching straight back restores them.
- Labels name the date when a task has both: "15 minutes before the start", "On the due date at 09:00". New reminders preselect the start.
- Defaults that have already passed don't ring when the task is saved.
- Sync: reminders rounded to whole days by builds before 1.2 pick up their real time of day on the next download.

## Deviations from the issues
- The start/due anchor lives in floret-kit (`ReminderLead`, floret-kit#19) rather than being packed into minute values. That PR is additive, so Calendula is unaffected.
- `error_reminder_without_due` was renamed to `error_reminder_without_date`, and the "(before start)/(before due)" strings were replaced by full sentences. The stale keys were deleted from the translation files so lint passes, and Weblate needs to offer the new strings to translators.
- The dead single-reminder API (`setAlarm`, `alarms()`, `editable()`, `reminderFor`) was removed.
- `AlarmLift` is back to its frozen 2→3 migration state.

## Release branch
`release/v1.2.0` is merged into this branch. Through it, this PR also brings main's commits the release branch was missing, including the reminder sync from #81 that this work builds on. I resolved conflicts in the data source interface, `TaskAlarmDao`, CHANGELOG, PRIVACY.md and the floret-kit pointer by keeping both sides.

Closes #72
Closes #78

Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Sup99999 <alelmnour1o234@proton.me>
Co-authored-by: Robin Schanbacher <robin@schanbros.de>
Co-authored-by: Knee8811 <mk-weby@protonmail.com>
Co-authored-by: Sonja Kraus <klein.felix@pm.me>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/agendula/pulls/88
2026-10-21 18:40:28 +02:00
Jean-Luc Makiolaandmakiolaj cff6308018 Let other apps write to the own store through the provider (#64)
Beta — Codeberg pre-release / detect (push) Successful in 6s
Beta — Codeberg pre-release / beta (push) Skipped
Builds on the read-only provider (#62) and makes it writable for other apps, as long as Agendula uses its own store.

- `tasks`: insert, update and delete. Writes follow the same rules as the app's own edits. Status, progress and completion time stay consistent, a subtree moves and deletes as one, and a write that changes nothing doesn't mark the task for sync.
- `instances`: completion columns complete, cancel or reopen that one occurrence. Other content columns edit the whole series. Changing a time column is rejected, so a series is moved through `tasks`.
- `properties`: alarms and categories can be inserted, updated and deleted.
- `tasklists` stays read-only. Batches run in one transaction.
- A client can write back a row it read. Columns it carries unchanged are ignored, and so are rdate/exdate values in the shape they were synced in.
- A task inserted with a time but no `tz` is floating, as in OpenTasks.
- Deleting a task now takes its whole subtree in the app as well, including "this and following" from the first occurrence and in External mode.

Deviation: tag property ids stay stable, with one rare exception. If two tags on one task have hash-colliding spellings, removing one can shift the other's id. Avoiding that would mean storing the ids, which didn't seem worth it at about a 1 in 2³¹ chance.

Closes #63

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/agendula/pulls/64
2026-10-15 16:16:51 +02:00
Jean-Luc Makiolaandmakiolaj e7bf23e276 Publish the own store through a read-only OpenTasks provider (#43) (#62)
Beta — Codeberg pre-release / detect (push) Successful in 7s
Beta — Codeberg pre-release / beta (push) Skipped
In Own storage mode, Agendula now publishes its Room store as a ContentProvider that follows the OpenTasks contract. It serves `tasklists`, `tasks`, `instances` and `properties` (reminders and tags) at `<package>.tasks`, behind a dangerous-level `<package>.permission.READ_TASKS` that the user grants per app. An app that already reads OpenTasks or tasks.org only has to change the authority and the permission.

On a query, the provider lays the Room store out in OpenTasks' columns and loads that into an in-memory SQLite database, so a client's selection, arguments and sort order run as real SQL. The snapshot is rebuilt after a write, after a storage mode switch, or once it is an hour old, because instance ids and `distance_from_current` move with the clock. Observers on the authority get one notification per burst of changes. In External mode every table is empty.

Recurrence expansion moved out of `RoomTasksDataSource` into shared functions, so the app and the provider expand a series the same way.

`docs/CONTENT_PROVIDER.md` describes the contract for client developers, with the authority and permission for each build. README, CHANGELOG and the privacy policy mention the new permission.

Where this differs from the issue: the issue asked for read and write permissions, and this PR is read-only. Insert, update and delete throw. Accepting writes from other apps means deciding what happens to the fields Agendula keeps verbatim for CalDAV round-tripping, which was the issue's second open question, and that needs its own design. That is tracked in #63.

Closes #43

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/agendula/pulls/62
2026-10-15 13:25:48 +02:00
Jean-Luc Makiolaandmakiolaj ac01993d41 Release 1.0.0 (#20)
First stable release. Merging this bumps versionName to 1.0.0 and triggers the release pipeline (F-Droid, Codeberg, Play).

**App**
- CalDAV sync built in, with Agendula's own task store; OpenTasks / tasks.org stay available and can be copied over in Settings → Storage
- repeating tasks, several reminders per task, lists managed in the app, iCalendar import/export, widget and Quick Settings tile
- a list can be kept out of the smart lists (#18) and gets its own notification channel (#17)
- duplicate a task with its subtasks (#16)
- HTML descriptions shown as plain text (#15)
- relative day words in reminder notifications (#14)
- asks for exact-alarm access instead of claiming USE_EXACT_ALARM, and re-arms reminders when that access changes

**Release plumbing**
- floret-kit bumped to v0.4.0; the old pin was never pushed, so a clean clone couldn't check out the submodule. 0.4.0 drops CrashConfig.issueTitle (crash issues are always filed in English)
- prebuilt .so files ship unstripped, so the build no longer depends on whether an NDK is installed; now checked by check_reproducible_release.sh
- official F-Droid recipe in docs/fdroid-official/, to submit to fdroiddata once v1.0.0 is tagged
- Google Play: fastlane uploads the AAB and every locale's What's New after the F-Droid release; a separate listing lane pushes text and graphics from the fastlane tree, which CI now checks against Play's limits
- store listing: title "Agendula: Tasks" in every locale, icon, feature graphic, screenshots and 1.0.0 changelogs in en-US, en-GB, de-DE and pt-BR

crash_report_issue_title is now unused but stays until Weblate removes the translated copies.

Closes #14, closes #15, closes #16, closes #17, closes #18

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/agendula/pulls/20
2026-09-24 16:36:49 +02:00
Jean-Luc Makiola 44489c5665 privacy: point the controller contact at support@ (#13)
Release — F-Droid repo + Gitea/Codeberg release / detect (push) Successful in 30s
Release — F-Droid repo + Gitea/Codeberg release / release (push) Skipped
2026-09-15 21:00:52 +02:00
Jean-Luc Makiolaandmakiolaj 633ec5b5d3 Move the privacy policy into the repo (#12)
Release — F-Droid repo + Gitea/Codeberg release / detect (push) Successful in 8s
Release — F-Droid repo + Gitea/Codeberg release / release (push) Skipped
The policy had no copy in this repository — it existed only inside the Astro page on jeanlucmakiola.de. This file becomes the single copy: the website build checks this repo out beside itself and renders `docs/PRIVACY.md` through a content collection, so the published page and the app's own documentation cannot drift. Same arrangement as calendula#293.

Shaped as the content entry the site expects: `title` / `description` / `updated` frontmatter, an HTML maintainer note that cannot render, and a body starting below the `h1` the page supplies.

The text is the published page carried over in full — controller and postal address, the two storage modes, CalDAV sync (what is stored, what is transmitted, RFC 6764 discovery, Nextcloud Login Flow v2, the user-CA trade-off), reminders and export, backups, crash reports, external links, permissions, distribution channels, deletion paths and GDPR rights.

Two things differ from the older short version that lived on `feat/caldav-sync`:

- Contact is `business@jeanlucmakiola.de`, matching the site and Calendula's policy, rather than `mail@`.
- Cleartext HTTP is described as refused outright. `CalDavDiscovery.allowCleartext` is `false` with nothing wiring it true, and `network_security_config.xml` sets `cleartextTrafficPermitted="false"`, so the previous "unless you explicitly opt in for a specific account" described a feature that does not exist. It goes back if a per-account opt-in ships.

Split out of `feat/caldav-sync` so the website change is not waiting on the whole sync branch. No issue to close — there is no open privacy/policy issue to reference.

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/agendula/pulls/12
2026-09-09 16:52:17 +02:00