Commit Graph
793 Commits
Author SHA1 Message Date
Jean-Luc Makiolaandmakiolaj 0121aa5b1d Keep the edit form's results from landing on the next one (#178) (#397)
Beta — Codeberg pre-release / detect (push) Successful in 7s
Beta — Codeberg pre-release / beta (push) Skipped
Follow-up to #394, from two review passes on the tap-opens-editor change.

- The edit form's view model is reused between opens, so work still running for a closed form could land on the next one. Backing out of a slow load and tapping another event showed the old event, and Save wrote to it. A delete finishing after back closed the next editor. Results from a closed form are now dropped.
- Back is ignored while a save or delete runs. The write can't be called back, so the form waits for the result and then closes or reports the error.
- Unsaved changes are now measured against the form as it opened, defaults included, instead of a flag every setter had to set.
- Taps read the setting and whether the calendar takes writes when they happen, so a tap right after a cold start or a return to the app opens the right screen.
- Without write access, the first tap asks once. A refusal opens the details from then on, until the permission is granted.
- Pinning an event to the tapped occurrence lives in one helper (`EventDetail.atOccurrence`), used by the detail, edit and selection-bar paths.

Closes #178

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/397
2026-10-14 17:49:53 +02:00
Jean-Luc Makiolaandmakiolaj cf3c4e96cd Add a black theme for AMOLED screens (#181) (#399)
Beta — Codeberg pre-release / detect (push) Successful in 7s
Beta — Codeberg pre-release / beta (push) Skipped
Settings → Appearance → Theme gets a fourth option, Black, next to System, Light and Dark. It's the dark theme with pure black backgrounds, and it works with Material You as well as Calendula's own palette.

- The month cells and the hour grid are `surfaceContainer` tiles on a `surface` ground, so making every container black would erase the grid lines. floret-kit's `toPureBlack()` sets the ground to #000 and scales the containers down to about #13, #1A, #25 and #30. The tiles stay a shade above black, and sheets and menus still stand out from the page.
- Black always means dark. It's an option in the theme picker, so it doesn't follow the system's light/dark setting.
- Event colours read `isSystemInDarkTheme()` in 15 places, so an in-app Dark or Black on a phone in light mode got light-theme tints. They now read `LocalFloretDarkTheme`, the theme's own decision. The bug also affected Dark, so the changelog has a Fixed entry for it.
- The window backdrop came from the night resource qualifier, so an in-app theme flashed the system's light or dark background before the first frame. `WindowThemeCache` keeps a SharedPreferences copy of the theme choice, and `onCreate` reads it to set the backdrop and bar icons. The copy is written when the stored setting loads, so the first cold start after updating still shows the old backdrop.
- Widgets keep their current themes. They get their theme work in the next milestone.

Needs jlmakiola/floret-kit#13, which is merged. The submodule is pinned to its merge commit on floret-kit `main` (`b1905da`).

Tested with new unit tests for the transform and for saving and reloading `BLACK`, and by hand on the emulator.

Closes #181

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/399
2026-10-14 17:41:34 +02:00
Jean-Luc Makiola 0dd7e07aa0 Show HTML event descriptions as formatted text (#271) (#398)
Beta — Codeberg pre-release / detect (push) Successful in 6s
Beta — Codeberg pre-release / beta (push) Skipped
Event descriptions from Exchange/Outlook and Google Calendar are often HTML. The detail view now renders them instead of showing the raw markup.

- A new converter in `domain/HtmlText.kt` turns HTML into text plus styles and links. It only kicks in when the description has real tags, so plain text with `<3` or `<https://…>` is left alone.
- Kept: bold, italic, underline, strikethrough, super/subscript, monospace, line breaks, paragraphs, lists (bullets, numbers, `start`, nesting) and `<a href>` links (http(s), mailto, tel). Dropped: fonts, sizes, colours, images, and `<head>`/`<style>`/`<script>`/comments.
- Each table row becomes one line with its cells joined by " · ", and empty spacer cells disappear. There's no real grid yet; one can go on top later if invites need it.
- URL and phone autolinking runs on the rendered text and skips text that's already a link.
- Long-press copy gives the rendered text, with each link's address in brackets after it.
- Search matches the rendered text and link addresses, and snippets show clean text.
- The edit form still shows the raw HTML, as discussed in the issue, so saving never breaks the formatting.

The issue suggested a settings toggle that strips tags. Following the discussion in the comments, this renders HTML automatically instead, with no setting.

Known limit: the SQL pre-filter in search still runs on the raw column. A word that's stored as an entity (`R&amp;D`) or split by tags (`<b>Kick</b>off`) isn't found.

I wrote my own parser instead of using `AnnotatedString.fromHtml`, because that goes through `android.text.Html`, which is stubbed in JVM unit tests, and search lives in the Compose-free domain layer.

Closes #271
2026-10-14 17:30:16 +02:00
Jean-Luc Makiolaandmakiolaj 2b2a31ecda Create an event from shared or selected text (#306) (#396)
Beta — Codeberg pre-release / detect (push) Successful in 6s
Beta — Codeberg pre-release / beta (push) Skipped
Shared text, or text picked with the new "Create event" entry in the selection menu, opens the new-event form prefilled. The share's subject becomes the title, or the first line if there is no subject, and the rest of the text goes into the description. Start and length use the usual defaults (next full hour, default duration). Calendula doesn't try to read a date out of the text.

Differences from the plan in the issue comment:
- The line used as the title is left out of the description, so it doesn't show up twice.
- Titles are capped at 255 characters. If a title gets cut, the full text stays in the description.
- Sharing a plain-text file no longer sends it to the .ics importer.
- A saved or dismissed prefilled form no longer reopens after rotating the phone. This also fixes it for "add to calendar" requests from other apps.
- If a second request comes in while a prefilled form is open, it replaces the form when nothing was changed. Otherwise the save / discard / keep editing prompt comes first.
- If Calendula was started just for the request, closing or saving the form takes you back to the app you came from.

Closes #306

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/396
2026-10-14 15:57:32 +02:00
Jean-Luc Makiolaandmakiolaj 0f75d2638b Show events at their real time on days the clocks change (#387) (#393)
Beta — Codeberg pre-release / detect (push) Successful in 6s
Beta — Codeberg pre-release / beta (push) Skipped
On the day the clocks change, the day, 3-day and week views placed events by the time elapsed since midnight, so every event after the change sat an hour off. A 14:45 event on 25 October showed at 15:45. Blocks are now placed by wall clock.

When the clocks go back, 02:00 to 03:00 happens twice, and a wall-clock time alone can't say which of the two it means. This branch keeps track of it:

- The event form holds each time as a `FormTime`, the wall clock plus its UTC offset when that time is in the repeated hour. Validation and saving read the real instants from it, so a span ending in the repeated hour is valid and switching between the two passes is saved.
- A time picked in the form or dragged with a resize handle goes back to the event's original pass when it's set back to its original time. Otherwise it moves in the direction it was moved, stays after the start, and takes a pass the grid can draw where it was dropped.
- A drop onto a repeated time lands on the first pass, unless the event was already on the second.
- A block that runs into the repeated hour from before it is drawn to 03:00, and its label shows its real end.
- The editor, the event details and the pinned zone's "local time" line add the zone abbreviation (CEST or CET) to a time in the repeated hour.
- A recurring series that starts in the repeated hour keeps its pass when it's edited.

Also in this PR:

- `ZoneSource`, provided through Hilt, gives the timeline, the event form and reschedules the device zone. The timeline lays its pages out again when the zone changes.
- A drafted block (#153) opens the form at its exact start and end.
- A day move onto the spring-forward day keeps its wall-clock start, so moving a weekly series there is still offered for all events.

## Testing

The 1,258 unit tests pass. The instrumented suite has the same two failures as `release/v2.23.0` (`CalendarRepositorySmokeTest` and `PermissionScreenTest`), so nothing new.

I also checked it by hand on an emulator in Europe/Berlin, with the clock moved to each DST day:

- 25 October: the event from the issue (14:45, Europe/Brussels) is drawn at 14:45. A run from 02:10 CEST to 02:20 CET is drawn to 03:00 and labelled with its real end.
- Pulling the end of a 02:30 to 03:30 CET event up to 02:45 saves 02:45 CET, after its start.
- Pulling the end of a 01:00 CEST to 04:00 CET event up to 02:15 saves 02:15 CEST, and the block stays where it was dropped.
- 29 March: a 01:00 to 04:00 run and a 14:00 event both sit at their own times.

Picking times in the form and moving a series in the month view are covered by unit tests only.

Closes #387

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/393
2026-10-14 15:54:14 +02:00
Jean-Luc Makiolaandmakiolaj 9fe1ebb0fb Tap a phone number in an event to call it (#339) (#395)
Beta — Codeberg pre-release / detect (push) Successful in 6s
Beta — Codeberg pre-release / beta (push) Skipped
Phone numbers in an event's title, location and description are now links. Tapping one opens the dialer with the number filled in. Nothing is called until you press call, so the app needs no new permission.

- Android's own matcher finds the numbers (Linkify, backed by libphonenumber and the SIM's region). Its loose setting links too much in event text, so a cleanup step drops meeting IDs and PINs after a label, dates, dotted times like "9.30 – 12.00", amounts, anything under 7 digits and digits inside URLs.
- "+49 (0)151 …" dials without the (0). An extension ("ext. 567") becomes a pause, and a Zoom-style dial-in suffix (",,850…#") is kept.
- Detection runs in the detail ViewModel while the event loads, so the links are there on the first frame and survive rotation.
- Long-pressing a field copies it even when the press lands on a link. Before, the link swallowed the press.
- PhoneLinksTest covers the cleanup on the JVM. PhoneLinksPlatformTest (androidTest) runs the real matcher and passes on an emulator with a US SIM.

Known limit: on a device without a SIM (Wi-Fi tablets, some emulators) Android gives the matcher no region, so only numbers starting with + are linked.

Closes #339

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/395
2026-10-14 15:24:03 +02:00
Jean-Luc Makiolaandmakiolaj 951ad9cd6d Tapping an event can open the edit form (#178) (#394)
Beta — Codeberg pre-release / detect (push) Successful in 6s
Beta — Codeberg pre-release / beta (push) Skipped
New setting under Settings → Views → Events: "Tapping an event opens" Details (default) or Edit form. The long-press toggle moves into the same group.

- Taps in the views and in search open the editor directly for events in writable calendars. Read-only events, reminder notifications and widgets always open the details.
- Installs without write access are asked for it on the tap; refusing opens the details instead.
- The editor gets a back guard: with unsaved changes it asks to save, discard or keep editing; otherwise it closes silently.
- The editor gets Duplicate, Share and Delete in an overflow menu, so skipping the details doesn't lose them.
- If the event can't be loaded, the details screen opens and shows why.
- Each editor overlay (create, edit, duplicate/import) now has its own ViewModel. Duplicating from an edited form previously reused the edit form's state.
- Deletes from the details screen, the editor and the selection bar share one error mapping. Deleting an event that's already gone counts as deleted in the details screen and the editor.

Deviation from the issue: it asked for back to save automatically. Following the discussion in the comments, auto-save isn't in this PR. Back asks only when something actually changed, and Details stays the default.

Closes #178

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/394
2026-10-14 14:33:38 +02:00
makiolaj 6cb2f62627 Release v2.23.0-beta.3 (#153)
Beta — Codeberg pre-release / detect (push) Successful in 5s
Beta — Codeberg pre-release / beta (push) Successful in 36m8s
v2.23.0-beta.3
2026-10-12 22:48:23 +02:00
Jean-Luc Makiolaandmakiolaj 427e87c6e6 Long press an empty slot to draft an event (#153) (#390)
Beta — Codeberg pre-release / detect (push) Successful in 6s
Beta — Codeberg pre-release / beta (push) Skipped
Long press on free time in the day, 3-day and week views drops a block of the default event length there. It can be moved while still held, or dragged and resized with its handles after letting go. The tick opens the new-event form at that span; the ✕, a tap elsewhere or back discards it. The draft is a stand-in event that reuses the #141 selection, drag and resize machinery, so nothing is written until the form saves.

Also smooths the lift handover for all selected blocks: no one-frame dip when letting go, no bounce on the handles or on a block landing after a drop or resize, and the floating copy's time label now matches the block's so the text doesn't shift on pickup.

Deviations from the issue / agreed design:
- An unresized draft opens the form with the length it shows (the global default) rather than the per-calendar default, so the form never opens at a different time than the block on screen.
- A draft dropped on a day off screen snaps back instead of moving there, since nothing would draw it.
- The in-editor timeline picker from the issue isn't included; per the issue comments it isn't needed for now.

Also moves the Gitea release/beta jobs onto the light/gradle runners.

Closes #153

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/390
2026-10-12 22:48:13 +02:00
makiolaj dce83005ea Release v2.23.0-beta.2 (#141)
Beta — Codeberg pre-release / detect (push) Successful in 5s
Beta — Codeberg pre-release / beta (push) Successful in 8m15s
v2.23.0-beta.2
2026-10-09 22:23:14 +02:00
Jean-Luc Makiola 1ac486cc4b Select, move and resize timeline events with a long press (#141) (#384)
Beta — Codeberg pre-release / detect (push) Successful in 12s
Beta — Codeberg pre-release / beta (push) Skipped
2026-10-09 22:23:06 +02:00
makiolaj 549ef1dfbf Release v2.23.0-beta.1 (#367)
Beta — Codeberg pre-release / detect (push) Successful in 5s
Beta — Codeberg pre-release / beta (push) Successful in 9m45s
v2.23.0-beta.1
2026-10-09 10:25:48 +02:00
Jean-Luc Makiolaandmakiolaj 164b5fb25d Scroll back into past days in the agenda (#367) (#382)
Beta — Codeberg pre-release / detect (push) Successful in 4s
Beta — Codeberg pre-release / beta (push) Skipped
The agenda opens on today, and scrolling up loads earlier days 30 at a time. Past days follow the past-events setting: Dim fades them, and with Hide the agenda still starts at today.

The agenda no longer picks up the day the month or day view was on, so "Next 30 days" always counts from today. That fixes the bug from the issue comment. It also means the agenda no longer follows the shared view date from #184 when you switch to it. Backing out of a day opened from the agenda keeps your scroll position.

Not in the issue: multi-day events that are still running now dim on the days already behind you, in the agenda, month, week and day views. Before, they stayed at full strength until the whole event ended. A spanning bar dims once the last day it covers in that row has passed.

The widget is unchanged and still starts at today.

Closes #367

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/382
2026-10-09 10:25:25 +02:00
Jean-Luc Makiolaandmakiolaj 6afcfd49f1 Release v2.22.5 (#381)
Renovate / renovate (push) Successful in 1m13s
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 6s
Beta — Codeberg pre-release / detect (push) Successful in 5s
Beta — Codeberg pre-release / beta (push) Skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Successful in 19m27s
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Successful in 1m2s
When you reopened the app the next morning, the month view still marked yesterday as today and still had the day you picked the evening before selected.

- New `TodaySource` gives the current date. It rechecks once a minute while a calendar is visible, and also reacts to the system's date, time and time-zone broadcasts. Month, Week/Day/3-day, Agenda and the shared date that every view opens on all use it.
- On a day change, a view still showing the old today moves to the new one, and Split clears the previous day's selection. A view you navigated elsewhere stays where it is.
- Month and Week take today from the live value instead of their cached page data.
- The issue only mentions the month view. The same stale today also affected Week, Day, Agenda and switching between views, so all of them are fixed.
- versionName 2.22.5 / versionCode 2220599, CHANGELOG, What's New in all 17 locales.

Closes #373

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/381
v2.22.5
2026-10-07 20:22:50 +02:00
Jean-Luc Makiolaandmakiolaj 5f77cac7ea Move to floret-kit 0.7.0 (#375)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 8s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Skipped
Renovate / renovate (push) Successful in 1m11s
Repoints the floret-kit submodule at the convergence merge (jlmakiola/floret-kit#11), which folds the clockula/vouch/glance branches back into floret-kit main so all four apps share one line again.

floret-kit's dependency bump requires Gradle >= 9.6 in the consuming build, so this also bumps Gradle 9.5.1 → 9.8.0, AGP 9.2.1 → 9.4.1 and Kotlin 2.3.21 → 2.4.20. No source changes were needed.

**Merge jlmakiola/floret-kit#11 first** so the pinned commit is on floret-kit main.

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/375
2026-10-07 09:56:00 +02:00
Jean-Luc Makiolaandmakiolaj 20a6548ac8 Release v2.22.4 (#374)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 9s
Renovate / renovate (push) Successful in 1m57s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Successful in 18m48s
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Successful in 1m19s
Promotes 2.22.4-beta.1 to stable. The app code is the same as the beta.

- versionName 2.22.4, versionCode 2220499 (new scheme)
- CHANGELOG.md: the Unreleased entries move under [2.22.4]
- What's New `changelogs/2220499.txt` in all 17 store locales

Includes #370 (re-query after own writes and on return to foreground) and #371 (widgets load only what they show).

Closes #363
Closes #364

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/374
v2.22.4
2026-10-07 09:05:32 +02:00
Jean-Luc Makiolaandmakiolaj 9c35712573 ci(release): beta releases as Codeberg-only pre-releases (#369)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 6s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Skipped
Renovate / renovate (push) Successful in 1m30s
Beta — Codeberg pre-release / detect (push) Successful in 5s
Beta — Codeberg pre-release / beta (push) Skipped
### What this changes

Adds beta releases, ported from Agendula (#38 and #40 there). Pushing a `release/*` branch whose `versionName` is `X.Y.Z-beta.N` runs the new `.gitea/workflows/beta.yaml`: unit tests, build + sign with the app key, then a **Codeberg pre-release** (APK + `.sha256`) and a Gitea pre-release (R8 mapping). F-Droid (self-hosted and official) and Play never get a beta; Obtainium only offers it with *Include prereleases* on.

- **New versionCode scheme**, derived in one place by `scripts/version_info.sh`. 2.22.3 is the last legacy version (`X*10000 + Y*100 + Z`); from **2.22.4** on it is `X*1000000 + Y*10000 + Z*100 + N` for a beta (N = 1–98) and `+ 99` for stable, so `2.22.4` → `2220499`, `2.23.0-beta.1` → `2230001`.
- **`scripts/release_gate.sh`** decides in both `detect` jobs whether the version still needs publishing. Tags are read by exact name via `git ls-remote`: Codeberg's `git/refs/tags/<name>` matches by prefix, so a beta tag would otherwise hide its stable release. A beta counts as done only once its Codeberg pre-release carries the APK (a failed publish is redone by the next push) and must be newer than the latest stable.
- **Shared scripts** `publish_codeberg_release.sh`, `publish_gitea_release.sh`, `release_notes.sh`, `write_keystore.sh`, and a local composite action `.gitea/actions/android-env` for the toolchain setup, used by both `release.yaml` and `beta.yaml`. The stable path behaves as before (Codeberg step stays best-effort).
- **Guards:** CI fails a PR whose `versionCode` doesn't match its `versionName`, or that brings a beta into `main`; `release.yaml` refuses a beta as a backstop; betas get no store What's New (`sync_changelog_to_fastlane.sh`, `check_changelog_lengths.sh`).
- **Docs:** versionCode table and "Cutting a beta" in `docs/RELEASING.md`, the Obtainium note in the README, `build.gradle.kts` comment.
- `gradle/gradle-daemon-jvm.properties` now points at JetBrains' own JBR 21.0.11 downloads instead of foojay, which dropped JetBrains 21 from its index (the pinned ids return 400, so a clean runner can't provision the daemon JVM).

### Why

To ship test builds of an upcoming version to opted-in testers before the stable release, without them reaching F-Droid or Play users.

Infra-only, so this targets `main` directly; no version bump. When cutting 2.22.4, its What's New file is `changelogs/2220499.txt`.

### Checklist

- [x] Targeting `main` (infra change, noted above)
- [x] No `values-*/strings.xml` touched
- [x] `CHANGELOG.md` not updated: release infrastructure, not a user-visible change
- [x] No planning or design documents committed

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/369
2026-10-06 18:43:45 +02:00
renovate-bot 4342c6ab6d fix(deps): update composebom to v2026.09.00 (#238)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 6s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Skipped
Renovate / renovate (push) Successful in 1m6s
This PR contains the following updates:

| Package | Type | Change | Age | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|---|
| [androidx.compose:compose-bom](https://developer.android.com/jetpack) | dependencies | `2026.06.01` → `2026.09.00` | 25 d | ![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/androidx.compose:compose-bom/2026.06.01/2026.09.00?slim=true) |

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Between 04:00 AM and 06:59 AM, only on Monday (`* 4-6 * * 1`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMzIuMCIsInVwZGF0ZWRJblZlciI6IjQzLjIzMi4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/238
2026-10-05 13:40:00 +02:00
renovate-bot 57bad5c74c fix(deps): update material3 (alpha) to v1.5.0-alpha29 (#274)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 7s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Skipped
Renovate / renovate (push) Canceled after 0s
This PR contains the following updates:

| Package | Type | Change | Age | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|---|
| [androidx.compose.material3:material3](https://developer.android.com/jetpack/androidx/releases/compose-material3#1.4.0) ([source](https://cs.android.com/androidx/platform/frameworks/support)) | dependencies | `1.5.0-alpha26` → `1.5.0-alpha29` | 11 d | ![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/androidx.compose.material3:material3/1.5.0-alpha26/1.5.0-alpha29?slim=true) |

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Between 04:00 AM and 06:59 AM, only on Monday (`* 4-6 * * 1`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMzIuMCIsInVwZGF0ZWRJblZlciI6IjQzLjIzMi4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/274
2026-10-05 13:39:41 +02:00
renovate-bot ebf833d0bd fix(deps): update glance to v1.2.0 (#275)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 6s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Skipped
Renovate / renovate (push) Successful in 1m10s
This PR contains the following updates:

| Package | Type | Change | Age | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|---|
| [androidx.glance:glance-material3](https://developer.android.com/jetpack/androidx/releases/glance#1.2.0) ([source](https://cs.android.com/androidx/platform/frameworks/support)) | dependencies | `1.1.1` → `1.2.0` | 39 d | ![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/androidx.glance:glance-material3/1.1.1/1.2.0?slim=true) |
| [androidx.glance:glance-appwidget](https://developer.android.com/jetpack/androidx/releases/glance#1.2.0) ([source](https://cs.android.com/androidx/platform/frameworks/support)) | dependencies | `1.1.1` → `1.2.0` | 39 d | ![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/androidx.glance:glance-appwidget/1.1.1/1.2.0?slim=true) |

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Between 04:00 AM and 06:59 AM, only on Monday (`* 4-6 * * 1`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMzIuMCIsInVwZGF0ZWRJblZlciI6IjQzLjIzMi4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/275
2026-10-05 13:39:03 +02:00
renovate-bot 2f24a9878c fix(deps): update lifecyclecompose to v2.11.0 (#277)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 8s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Skipped
Renovate / renovate (push) Successful in 1m5s
This PR contains the following updates:

| Package | Type | Change | Age | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|---|
| [androidx.lifecycle:lifecycle-runtime-compose](https://developer.android.com/jetpack/androidx/releases/lifecycle#2.11.0) ([source](https://cs.android.com/androidx/platform/frameworks/support)) | dependencies | `2.10.0` → `2.11.0` | 109 d | ![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/androidx.lifecycle:lifecycle-runtime-compose/2.10.0/2.11.0?slim=true) |

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Between 04:00 AM and 06:59 AM, only on Monday (`* 4-6 * * 1`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMzIuMCIsInVwZGF0ZWRJblZlciI6IjQzLjIzMi4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/277
2026-10-05 13:37:03 +02:00
Jean-Luc Makiolaandmakiolaj 2313671965 chore(renovate): rebase conflicted PRs on every merge to main (#366)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 30s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Skipped
Renovate / renovate (push) Successful in 1m29s
Renovate only rebases while it runs, and it ran once a week, so merging one dependency PR left the others conflicted until the next Monday.

- `renovate.yml`: also run on push to `main` (mirror syncs fire push events, like `release.yaml`).
- `renovate.json5`: new PRs only in a Monday window (`* 4-6 * * 1`) around the weekly cron; on-merge runs only rebase conflicted PRs (`rebaseWhen: "conflicted"`).

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/366
2026-10-05 13:33:59 +02:00
Jean-Luc Makiola e1b80d9f89 Release v2.22.3 (#362)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 8s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Successful in 14m42s
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Successful in 1m40s
Patch release for #361. No app changes.

- `title.txt` in every store locale is now "Calendula: Calendar", with "Calendar" taken from the app's own translation of the word (`event_detail_calendar`). Since 2.22.0 the Play listing is pushed from the repo, and the repo title was only "Calendula", which replaced the suffixed name from the Play Console.
- ja has no translation for that string yet, so it uses カレンダー. zh-CN has "Calendula" as its translation of "Calendar" on Weblate, so the title uses 日历 instead. That string should be fixed on Weblate.
- F-Droid reads the same `title.txt`, so the F-Droid listing gets the suffix too.

Plus the release commit: CHANGELOG section, versionName 2.22.3 / versionCode 22203, and the 22203 changelogs for every store locale. Merging this to main triggers the release pipeline.

Closes #361
v2.22.3
2026-10-02 22:14:34 +02:00
Jean-Luc Makiola 99bb6adf80 Release v2.22.2 (#360)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 6s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Successful in 14m8s
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Successful in 2m59s
Patch release for #359. No app changes.

- The Dutch store listing moved from `fastlane/metadata/android/nl` to `nl-NL`. Play rejects plain `nl`, so the Play upload of 2.22.0 and 2.22.1 failed with `nl - Invalid request`. F-Droid accepts either code.
- `check_store_listing.py` now checks every store code in `store-locales.txt` against the languages Play accepts, so CI catches this before a release.
- The 22202 "What's New" covers the 2.22 highlights, since Play users go straight from 2.21.0 to 2.22.2, and says the app is the same as 2.22.1.

Closes #359
v2.22.2
2026-10-02 20:41:17 +02:00
Jean-Luc Makiola 06ee010f07 Release v2.22.1 (#358)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 10s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Successful in 14m6s
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Failing after 1m28s
Patch release for #357.

- Tapping a meeting link in an event's location opened it in a maps app. Links in the location are now underlined and open in the browser, the same way description links do. Tapping the rest of the location still opens maps, so a location with both an address and a link works for both.
- Link detection moved into `WebLinks.kt` with unit tests. It now matches a capitalised scheme (`Https://`), lower-cases the scheme before launching, and leaves `<…>` out of the URL (the Outlook/Teams style). This applies to description links too.
- Links open with `CATEGORY_BROWSABLE` through one helper. A failed launch shows a "No app can open this link" toast instead of doing nothing or crashing on a `SecurityException`.
- The location's maps tap has an "Open in maps" accessibility label (new `onTapLabel` on `copyOnLongPress`).

The issue only asked for links to open in the browser. Inline links instead of switching the whole tap target came out of review: they keep the address reachable when a location holds both.

Plus the release commit: CHANGELOG section, versionName 2.22.1 / versionCode 22201, and the 22201 changelogs for every store locale. Merging this to main triggers the release pipeline.

Closes #357
v2.22.1
2026-10-02 18:45:38 +02:00
Jean-Luc Makiolaandmakiolaj 5f07adef2f Release v2.22.0 (#355)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 8s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Successful in 14m16s
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Failing after 1m26s
Views: navigation, transitions and split-view behaviour.

See CHANGELOG.md for the full list.

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/355
v2.22.0
2026-10-01 16:21:11 +02:00
Jean-Luc Makiola bfc05795f0 Translations update from Weblate (#333)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 8s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Skipped
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/333
2026-10-01 14:39:52 +02:00
N Donkersloot 9de5f3f00d Translated using Weblate (Dutch)
Currently translated at 100.0% (633 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/nl/
2026-09-30 11:00:32 +00:00
Weblate bfdbd49aa1 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/
2026-09-30 06:10:49 +00:00
N Donkersloot 844a3c22ff Added translation using Weblate (Dutch) 2026-09-30 06:10:49 +00:00
Sup99999 87a08a4d24 Translated using Weblate (Arabic)
Currently translated at 100.0% (633 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-09-30 06:10:48 +00:00
Sup99999 dc0637c37c Translated using Weblate (Arabic)
Currently translated at 100.0% (633 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-09-29 18:29:12 +00:00
Weblate 381eca6660 Translated using Weblate (Czech)
Currently translated at 100.0% (633 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/cs/
2026-09-29 07:07:16 +00:00
James Trivette 36018b3e52 Translated using Weblate (Czech)
Currently translated at 100.0% (633 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/cs/
2026-09-29 07:07:16 +00:00
Paulo Gomez 3c0324c071 Translated using Weblate (Portuguese (Brazil))
Currently translated at 90.2% (571 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/pt_BR/
2026-09-29 07:07:15 +00:00
Dmitri Gabinski a70108dff8 Translated using Weblate (Belarusian)
Currently translated at 89.7% (568 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/be/
2026-09-28 16:31:37 +00:00
makiolaj 83447ab68a Translated using Weblate (German)
Currently translated at 99.6% (631 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/de/
2026-09-28 16:31:36 +00:00
Sup99999 4ac937c54f Translated using Weblate (Arabic)
Currently translated at 99.8% (632 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-09-25 18:12:14 +00:00
Sup99999 b5f28929d7 Translated using Weblate (Arabic)
Currently translated at 99.8% (632 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-09-25 02:08:49 +00:00
Weblate d729a928ea Translated using Weblate (Arabic)
Currently translated at 99.8% (632 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-09-25 01:03:55 +00:00
Sup99999 01a4ad742b Translated using Weblate (Arabic)
Currently translated at 99.8% (632 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-09-25 01:03:55 +00:00
Weblate 6f77a5e12e Translated using Weblate (Arabic)
Currently translated at 97.4% (617 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-09-25 00:31:23 +00:00
Sup99999 e29c38d88c Translated using Weblate (Arabic)
Currently translated at 97.4% (617 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-09-25 00:31:23 +00:00
Weblate 04f509fc4c Translated using Weblate (Arabic)
Currently translated at 96.8% (613 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-09-25 00:24:30 +00:00
Sup99999 b6061f1384 Translated using Weblate (Arabic)
Currently translated at 96.8% (613 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-09-25 00:24:30 +00:00
Weblate 38c3a82b54 Translated using Weblate (Arabic)
Currently translated at 96.3% (610 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-09-25 00:13:36 +00:00
Sup99999 d3f1409503 Translated using Weblate (Arabic)
Currently translated at 96.3% (610 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-09-25 00:13:36 +00:00
Sup99999 3475a073ad Translated using Weblate (Arabic)
Currently translated at 94.9% (601 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-09-24 23:59:17 +00:00
Sup99999 643c61db65 Translated using Weblate (Arabic)
Currently translated at 94.7% (600 of 633 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-09-24 23:55:39 +00:00
James Trivette 1734b7863c Translated using Weblate (Czech)
Currently translated at 100.0% (590 of 590 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/cs/
2026-09-24 19:35:26 +00:00