Compare commits

...

38 Commits

Author SHA1 Message Date
Jean-Luc Makiola
51a1d1e8ef Translations update from Weblate (#255)
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 5s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Has been skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Has been skipped
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/255
2026-08-31 21:05:58 +02:00
631c9da0a4 Translated using Weblate (Belarusian)
Currently translated at 70.2% (403 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/be/
2026-08-31 19:05:07 +00:00
Jean-Luc Makiola
5fa214b9ba Translations update from Weblate (#252)
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 5s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Has been skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Has been skipped
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/252
2026-08-31 19:52:03 +02:00
Jean-Luc Makiola
eb406c3132 Move EXDATE with the series when its times change (#248) (#249)
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 6s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Has been skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Has been skipped
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/249
2026-08-31 18:17:43 +02:00
Dmitri Gabinski
3a90e94958 Translated using Weblate (Belarusian)
Currently translated at 70.2% (403 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/be/
2026-08-31 14:59:59 +00:00
Jean-Luc Makiola
248842871b fix(deps): update work to v2.11.2 (#204)
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 6s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Has been skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Has been skipped
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/204
2026-08-31 09:12:47 +02:00
Jean-Luc Makiola
1cab023abc Translations update from Weblate (#250)
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 8s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Has been skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Has been skipped
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/250
2026-08-31 09:12:01 +02:00
9ca29bb797 fix(deps): update work to v2.11.2 2026-08-31 05:02:32 +00:00
JeanWenzel
13640751d2 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (574 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/zh_Hans/
2026-08-29 03:03:54 +00:00
JeanWenzel
0c7d1a97e2 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (574 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/zh_Hans/
2026-08-28 16:11:05 +00:00
Weblate
d0202783d4 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (574 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/zh_Hans/
2026-08-28 16:11:05 +00:00
JeanWenzel
f72f810e4f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (574 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/zh_Hans/
2026-08-28 16:11:05 +00:00
Weblate
13f4c86113 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-08-28 02:17:51 +00:00
James Trivette
65d9f95717 Translated using Weblate (Czech)
Currently translated at 47.7% (274 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/cs/
2026-08-28 02:17:51 +00:00
JeanWenzel
19fa8203f1 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 24.5% (141 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/zh_Hans/
2026-08-28 02:17:51 +00:00
Jean-Luc Makiola
0f1df4800d Translations update from Weblate (#247)
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 8s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Has been skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Has been skipped
Renovate / renovate (push) Successful in 1m54s
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/247
2026-08-27 20:38:38 +02:00
Weblate
7351b2d35c Translated using Weblate (Polish)
Currently translated at 100.0% (574 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/pl/
2026-08-27 18:24:01 +00:00
Bazyli Cyran
1a66a31563 Translated using Weblate (Polish)
Currently translated at 100.0% (574 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/pl/
2026-08-27 18:24:01 +00:00
Weblate
fe3c659804 Translated using Weblate (Polish)
Currently translated at 100.0% (574 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/pl/
2026-08-27 18:24:01 +00:00
Jean-Luc Makiola
a2172dce12 Google Play is live: README + production track (#244)
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 8s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Has been skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Has been skipped
Calendula is published on Google Play, so the pipeline and the docs stop treating it as pending.

**README**
- Google Play badge next to F-Droid/Obtainium, linking the store page.
- Install table: the Play row goes from "Coming soon / —" to a real channel.
- The "coming soon" section becomes a live one with the store link; the closed-testing "testers wanted" call drops out. The note that Play signs with Google's key (so switching channels needs an uninstall) stays, and the trailing shared-signing-key line now flags Play as the exception.

**Play track**
- Release uploads default to `production` instead of `internal` — in the lane (`fastlane/Fastfile`) and in the workflow default (`.gitea/workflows/release.yaml`). Merging a bumped versionName to main is already the human gate, so the manual Console promotion only added delay.
- `docs/RELEASING.md` updated to match, including the escape hatches (`PLAY_TRACK=internal` to stage, `PLAY_RELEASE_STATUS=draft` to hold).

Note: if a `PLAY_TRACK` repo variable is set on Gitea it still wins over the new default — needs checking there.

No issue for this one.

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/244
2026-08-27 19:09:04 +02:00
Jean-Luc Makiola
4099f66e91 Translations update from Weblate (#232)
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 7s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Has been skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Has been skipped
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/232
2026-08-27 19:08:28 +02:00
49112b11b3 fix(deps): update test dependencies to v6.1.3 (#202)
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 6s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Has been skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Has been skipped
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/202
2026-08-27 19:07:52 +02:00
1218bb523c fix(deps): update lifecycleruntime to v2.11.0 (#203)
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 5s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Has been skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Has been skipped
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/203
2026-08-27 19:07:29 +02:00
17600a3905 fix(deps): update material3 (alpha) to v1.5.0-alpha26 (#235)
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 7s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Has been skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Has been skipped
Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/235
2026-08-27 19:07:02 +02:00
Julie
db5104a7d0 Translated using Weblate (Slovak)
Currently translated at 32.0% (184 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/sk/
2026-08-27 03:40:53 +00:00
Julie
6306064fc3 Translated using Weblate (Slovak)
Currently translated at 25.0% (144 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/sk/
2026-08-26 23:38:37 +00:00
Julie
d5a4761f2c Translated using Weblate (Slovak)
Currently translated at 13.5% (78 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/sk/
2026-08-26 21:23:50 +00:00
Dmitri Gabinski
66d6681798 Translated using Weblate (Belarusian)
Currently translated at 24.9% (143 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/be/
2026-08-26 21:23:49 +00:00
Weblate
fb61169656 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-08-26 13:57:44 +00:00
Julie
62079fba0b Added translation using Weblate (Slovak) 2026-08-26 13:57:44 +00:00
Dmitri Gabinski
cc0fc8edc3 Translated using Weblate (Belarusian)
Currently translated at 23.8% (137 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/be/
2026-08-26 13:57:43 +00:00
Sup99999
62174fcd53 Translated using Weblate (Arabic)
Currently translated at 97.7% (561 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-08-25 16:03:15 +00:00
Dmitri Gabinski
55c1b2ac25 Translated using Weblate (Belarusian)
Currently translated at 4.5% (26 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/be/
2026-08-25 02:58:46 +00:00
Sup99999
0ccc610144 Translated using Weblate (Arabic)
Currently translated at 95.9% (551 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-08-25 02:58:45 +00:00
Weblate
5d009b7dc0 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-08-24 06:55:51 +00:00
Dmitri Gabinski
28924daf02 Added translation using Weblate (Belarusian) 2026-08-24 06:55:51 +00:00
Sup99999
e71fb2a625 Translated using Weblate (Arabic)
Currently translated at 92.6% (532 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ar/
2026-08-22 14:29:52 +00:00
SpiritOTHawk
aa5f76fc1b Translated using Weblate (Russian)
Currently translated at 28.2% (162 of 574 strings)

Translation: Calendula/Strings
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/calendula/strings/ru/
2026-08-22 14:29:52 +00:00
16 changed files with 2008 additions and 158 deletions

View File

@@ -551,12 +551,11 @@ jobs:
env:
VERSION: ${{ needs.detect.outputs.version }}
VERSION_CODE: ${{ needs.detect.outputs.version_code }}
# Where the bundle lands. `internal` by default so a release reaches
# testers rather than the public, and promotion to production stays a
# deliberate human action in the Play Console — the same posture as
# holding UI releases for on-device review. Override with the PLAY_TRACK
# repo variable once the flow is trusted.
PLAY_TRACK: ${{ vars.PLAY_TRACK || 'internal' }}
# Where the bundle lands. `production` — the release itself is already the
# gate (a bumped versionName only reaches main after on-device review), so
# a second manual promotion in the Play Console bought nothing but delay.
# Override with the PLAY_TRACK repo variable to stage a release instead.
PLAY_TRACK: ${{ vars.PLAY_TRACK || 'production' }}
PLAY_RELEASE_STATUS: ${{ vars.PLAY_RELEASE_STATUS || 'completed' }}
# Set PLAY_DRY_RUN=true to validate the edit against the API and discard
# it instead of committing — used to rehearse the first upload.

View File

@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Fixed
- **A deleted occurrence no longer comes back when the series is re-timed.**
Delete a single occurrence of a repeating event, then change the time of the
whole series, and the occurrence you had removed reappeared. Doing it the
other way round — "This and all following events" — lost every removal in the
part of the series being changed. Removals now travel with the event: they
keep their place in the series across a time change, a move to a different
day, a timezone change and a switch to or from an all-day event, and they
carry over when a series is split. Repeating events on your device's own
calendars are affected, including the birthday and anniversary calendars
Calendula creates from your contacts ([#248]).
## [2.19.3] — 2026-08-22
### Added
@@ -1471,3 +1483,4 @@ automatically, with zero telemetry and no internet permission.
[#192]: https://codeberg.org/jlmakiola/calendula/issues/192
[#196]: https://codeberg.org/jlmakiola/calendula/issues/196
[#214]: https://codeberg.org/jlmakiola/calendula/issues/214
[#248]: https://codeberg.org/jlmakiola/calendula/issues/248

View File

@@ -18,6 +18,8 @@ Reads, writes, and reminds — on top of the system calendar, with zero network
<p>
<a href="https://f-droid.org/packages/de.jeanlucmakiola.calendula/"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="56"></a>
&nbsp;
<a href="https://play.google.com/store/apps/details?id=de.jeanlucmakiola.calendula"><img src="https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png" alt="Get it on Google Play" height="56"></a>
&nbsp;
<a href="https://apps.obtainium.imranr.dev/redirect?r=obtainium://add/https://codeberg.org/jlmakiola/calendula"><img src="https://github.com/ImranR98/Obtainium/blob/main/assets/graphics/badge_obtainium.png?raw=true" alt="Get it on Obtainium" height="56"></a>
&nbsp;
<a href="https://ko-fi.com/jeanlucmakiola"><img src="https://storage.ko-fi.com/cdn/brandasset/v2/support_me_on_kofi_badge_beige.png" alt="Support me on Ko-fi" height="56"></a>
@@ -86,7 +88,7 @@ Pick whichever channel you already use — they all install the same app:
| [Official F-Droid](#f-droid-recommended) | On F-Droid's build schedule | Recommended; no extra setup |
| [Self-hosted F-Droid repo](#self-hosted-f-droid-repo-fastest-updates) | Minutes after a release | Fastest; needs the repo added once |
| [Codeberg release / Obtainium](#codeberg-release--obtainium) | Per release | Plain APK download, or automated by Obtainium |
| [Google Play](#google-play-coming-soon) | — | Coming soon |
| [Google Play](#google-play) | Per release | Signed with Google's key — see below |
| [Build from source](#build-from-source) | Whenever you build | Full control |
### F-Droid (recommended)
@@ -131,18 +133,14 @@ or do it by hand: *Add App* → paste `https://codeberg.org/jlmakiola/calendula`
→ *Add*. Either way, Obtainium tracks the releases and prompts you when a new
one appears.
### Google Play (coming soon)
### Google Play
Calendula is on its way to Google Play as an additional channel. It isn't live
yet — this section gets a link once it is. Play builds will be signed with
Google's key rather than mine, so switching between Play and any other channel
will require an uninstall.
Calendula is live on Google Play:
**[play.google.com/store/apps/details?id=de.jeanlucmakiola.calendula](https://play.google.com/store/apps/details?id=de.jeanlucmakiola.calendula)**.
> **Testers wanted.** Play requires a round of closed testing before the app can
> go public, and I'm still looking for testers. If you'd like to help, email
> **[business@jeanlucmakiola.de](mailto:business@jeanlucmakiola.de)** with the
> Google account address you want to use — that address is what I need to add you
> to the closed test.
Play builds are signed with Google's key rather than mine, so switching between
Play and any other channel requires an uninstall (and with it, a fresh start for
app settings — your events live in the system calendar and are unaffected).
### Build from source
@@ -151,7 +149,7 @@ The build is a plain Gradle build with no proprietary dependencies — see
<sub>Official F-Droid, the self-hosted repo, and the Codeberg releases all share
the same signing key, so you can switch freely between them without
reinstalling.</sub>
reinstalling. Google Play is the exception — see above.</sub>
## 📚 Documentation

View File

@@ -976,10 +976,12 @@ class AndroidCalendarDataSource @Inject constructor(
updated: EventForm,
allDayReminderTimeMinutes: Int,
) {
val row = querySeriesRow(eventId)
val values = buildEventUpdateValues(
original = original,
updated = updated,
seriesDtStartMillis = querySeriesRow(eventId).dtStartMillis,
seriesDtStartMillis = row.dtStartMillis,
seriesExdate = row.exdate,
zone = ZoneId.systemDefault(),
)
if (values.isNotEmpty()) {
@@ -1228,10 +1230,66 @@ class AndroidCalendarDataSource @Inject constructor(
}
// Insert the new series first: if it fails, the original is untouched.
val newEventId = insertEvent(updated, allDayReminderTimeMinutes)
carrySplitExdate(newEventId, row, beginMillis, original, updated)
truncateSeries(eventId, row, beginMillis)
return newEventId
}
/**
* Carry the [parent]'s exclusions for occurrences past [beginMillis] onto the
* series [newEventId] that now owns them, re-timed by the shift the split
* applied ([shiftedExdate]/[exdateAfter]). [insertEvent] builds the new row
* from the form, which knows nothing about them, so without this every
* occurrence the user had deleted from the tail of the series comes back.
*
* The whole time/recurrence set rides along with EXDATE for the reason
* [buildOccurrenceExdateValues] documents: on its own the provider does not
* read an EXDATE write as a recurrence change, and leaves the instances it
* expanded on insert standing.
*
* A failure rolls the new series back and throws, so the split fails whole
* rather than landing with the exclusions quietly dropped — the parent is
* still untruncated at this point, so the event is left exactly as it was.
*/
private fun carrySplitExdate(
newEventId: Long,
parent: SeriesRow,
beginMillis: Long,
original: EventForm,
updated: EventForm,
) {
// Dropping the recurrence in the same save leaves a one-off tail, and an
// exclusion means nothing on a row that doesn't recur.
if (updated.rrule.isNullOrBlank()) return
val carried = shiftedExdate(
existingExdate = exdateAfter(parent.exdate, beginMillis, original.isAllDay),
original = original,
updated = updated,
zone = ZoneId.systemDefault(),
) ?: return
val row = querySeriesRow(newEventId)
val values = ContentValues().apply {
put(CalendarContract.Events.EXDATE, carried)
put(CalendarContract.Events.DTSTART, row.dtStartMillis)
put(CalendarContract.Events.RRULE, row.rrule)
put(CalendarContract.Events.DURATION, row.duration)
put(CalendarContract.Events.EVENT_TIMEZONE, row.timezone)
put(CalendarContract.Events.ALL_DAY, row.allDay)
}
try {
val rows = resolver.update(
ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, newEventId),
values, null, null,
)
if (rows == 0) {
throw WriteFailedException("carry exdate onto split series id=$newEventId")
}
} catch (t: Throwable) {
runCatching { deleteEvent(newEventId) }
throw t
}
}
override fun deleteEventFromOccurrence(eventId: Long, beginMillis: Long) {
val row = querySeriesRow(eventId)
// From the first occurrence on = the whole series; also the fallback

View File

@@ -10,6 +10,9 @@ import java.time.Duration
import java.time.Instant
import java.time.ZoneId
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.time.format.ResolverStyle
import java.time.LocalDate as JavaLocalDate
import java.time.LocalDateTime as JavaLocalDateTime
/** Provider-ready DTSTART / DTEND / EVENT_TIMEZONE for an event write. */
@@ -134,18 +137,21 @@ internal fun buildEventInsertValues(
*
* Time fields travel together (the provider validates them as a unit):
* - unchanged times, all-day flag and rrule → no time columns at all;
* - non-recurring result → DTSTART/DTEND, DURATION and RRULE cleared;
* - non-recurring result → DTSTART/DTEND, DURATION, RRULE and EXDATE cleared;
* - recurring result → the *series* DTSTART moves by the same **wall-clock**
* shift the user applied to the displayed occurrence and is re-resolved in the
* event's zone ([seriesDtStartMillis] is the row's current DTSTART), DURATION
* replaces DTEND, RRULE is written. This keeps past occurrences intact when
* someone edits a later occurrence's time, and keeps the anchor's time-of-day
* stable across a DST boundary or a zone change between the two.
* replaces DTEND, RRULE is written, and the row's exclusions
* ([seriesExdate], the current EXDATE) travel with the anchor. This keeps past
* occurrences intact when someone edits a later occurrence's time, and keeps
* the anchor's time-of-day stable across a DST boundary or a zone change
* between the two.
*/
internal fun buildEventUpdateValues(
original: EventForm,
updated: EventForm,
seriesDtStartMillis: Long,
seriesExdate: String?,
zone: ZoneId,
): Map<String, Any?> = buildMap {
if (updated.title.trim() != original.title.trim()) {
@@ -185,6 +191,10 @@ internal fun buildEventUpdateValues(
put(CalendarContract.Events.DTEND, newTimes.dtEndMillis)
put(CalendarContract.Events.RRULE, null)
put(CalendarContract.Events.DURATION, null)
// The exclusions named occurrences of a series that no longer exists.
// Left behind they are dormant rather than harmless: adding a recurrence
// back later would punch the old holes into the new one.
put(CalendarContract.Events.EXDATE, null)
} else {
// Move the series anchor by the *wall-clock* shift the user applied to the
// displayed occurrence, then re-resolve it in the event's (possibly new)
@@ -206,6 +216,14 @@ internal fun buildEventUpdateValues(
put(CalendarContract.Events.DTEND, null)
put(CalendarContract.Events.RRULE, updated.rrule)
put(CalendarContract.Events.DURATION, newTimes.toRfc2445Duration(updated.isAllDay))
// An EXDATE stamp is an absolute instant, so it excludes an occurrence
// only while the series keeps generating one at exactly that instant. The
// anchor has just moved, so every occurrence regenerates elsewhere and a
// stamp left behind matches none of them — the occurrence the user deleted
// comes back. Move the stamps the same way the anchor moved.
shiftedExdate(seriesExdate, original, updated, zone)
?.takeIf { it != seriesExdate }
?.let { put(CalendarContract.Events.EXDATE, it) }
}
}
@@ -420,11 +438,7 @@ internal fun buildOccurrenceExdateValues(
allDay: Int,
): Map<String, Any?> {
val stamp = formatExdateStamp(occurrenceMillis, isAllDay = allDay != 0)
val existing = existingExdate?.split(',')
?.map { it.trim() }
?.filter { it.isNotEmpty() }
.orEmpty()
val merged = (existing + stamp).distinct().joinToString(",")
val merged = (exdateStamps(existingExdate) + stamp).distinct().joinToString(",")
return mapOf(
CalendarContract.Events.EXDATE to merged,
CalendarContract.Events.DTSTART to dtStartMillis,
@@ -435,22 +449,122 @@ internal fun buildOccurrenceExdateValues(
)
}
/**
* [existingExdate] with every stamp re-timed by the same **wall-clock** shift the
* series anchor takes from [original] to [updated] — the exclusions' half of the
* anchor move [buildEventUpdateValues] performs, and what carries them onto the
* new series when "this and following" splits one.
*
* A stamp is an absolute instant, so it keeps naming its occurrence only if it
* moves exactly as the occurrence does: shifted in wall clock and re-resolved in
* the event's (possibly new) zone. A millisecond delta would instead bake in the
* offset that happened to apply at the edited occurrence — an hour off for any
* exclusion on the far side of a DST boundary. All-day-ness is read from
* [original] and written from [updated], so the `VALUE=DATE` and date-time forms
* convert into each other when the event switches.
*
* Null when there is nothing to carry: no stamps, or a stamp in a form Calendula
* never writes (a `TZID=`-parameterised or floating one from a sync adapter). Those
* are left exactly as they are rather than guessed at — a stale stamp excludes
* nothing, but a mangled one could exclude the wrong occurrence.
*/
internal fun shiftedExdate(
existingExdate: String?,
original: EventForm,
updated: EventForm,
zone: ZoneId,
): String? {
val stamps = exdateStamps(existingExdate)
if (stamps.isEmpty()) return null
val fromZone = original.writeZone(zone)
val toZone = updated.writeZone(zone)
val wallClockShift = Duration.between(original.anchorLocal(), updated.anchorLocal())
return stamps
.map { stamp ->
val local = parseExdateStamp(stamp, original.isAllDay, fromZone) ?: return null
formatExdateStamp(local.plus(wallClockShift), updated.isAllDay, toZone)
}
.distinct()
.joinToString(",")
}
/**
* The stamps of [existingExdate] naming occurrences after [beginMillis] — the ones
* that belong to the *new* series once "this and following" splits a recurring
* event there. The parent keeps the full list; its stamps past the split point are
* simply inert once it stops generating those occurrences.
*
* The occurrence at [beginMillis] itself is never carried. It is the one the user
* is editing, so it exists by definition, and honouring a stale exclusion for it
* would swallow the edit whole.
*
* Null when nothing qualifies, or when a stamp can't be read (see [shiftedExdate]).
*/
internal fun exdateAfter(existingExdate: String?, beginMillis: Long, isAllDay: Boolean): String? {
val stamps = exdateStamps(existingExdate)
if (stamps.isEmpty()) return null
return stamps
.filter { stamp ->
val utc = parseExdateStamp(stamp, isAllDay, ZoneOffset.UTC) ?: return null
utc.toInstant(ZoneOffset.UTC).toEpochMilli() > beginMillis
}
.takeIf { it.isNotEmpty() }
?.joinToString(",")
}
/** The individual stamps of an EXDATE column value; it is a comma-separated list. */
private fun exdateStamps(exdate: String?): List<String> = exdate
?.split(',')
?.map { it.trim() }
?.filter { it.isNotEmpty() }
.orEmpty()
/**
* One EXDATE entry for the occurrence starting at [occurrenceMillis]. Both forms
* are UTC: the provider stores an all-day DTSTART at UTC midnight, so its date
* reads off the UTC calendar day.
*/
private fun formatExdateStamp(occurrenceMillis: Long, isAllDay: Boolean): String {
val utc = Instant.ofEpochMilli(occurrenceMillis).atZone(ZoneOffset.UTC)
return if (isAllDay) {
"%04d%02d%02d".format(utc.year, utc.monthValue, utc.dayOfMonth)
} else {
"%04d%02d%02dT%02d%02d%02dZ".format(
utc.year, utc.monthValue, utc.dayOfMonth,
utc.hour, utc.minute, utc.second,
private fun formatExdateStamp(occurrenceMillis: Long, isAllDay: Boolean): String =
formatExdateStamp(
local = Instant.ofEpochMilli(occurrenceMillis).atZone(ZoneOffset.UTC).toLocalDateTime(),
isAllDay = isAllDay,
zone = ZoneOffset.UTC,
)
/**
* One EXDATE entry for the occurrence whose wall clock in [zone] is [local]. An
* all-day entry keeps only the date (its time-of-day is the anchor's, not the
* occurrence's); a timed one is resolved in [zone] and written as a UTC instant.
*/
private fun formatExdateStamp(local: JavaLocalDateTime, isAllDay: Boolean, zone: ZoneId): String =
if (isAllDay) {
local.toLocalDate().format(ALL_DAY_EXDATE)
} else {
local.atZone(zone).withZoneSameInstant(ZoneOffset.UTC).format(TIMED_EXDATE)
}
}
/**
* [stamp] as the wall clock it names in [zone] — the inverse of
* [formatExdateStamp]. Null for anything but the two forms Calendula writes, so a
* caller can tell "not ours, leave it alone" from a value it may safely re-time.
*/
private fun parseExdateStamp(stamp: String, isAllDay: Boolean, zone: ZoneId): JavaLocalDateTime? =
runCatching {
if (isAllDay) {
JavaLocalDate.parse(stamp, ALL_DAY_EXDATE).atStartOfDay()
} else {
JavaLocalDateTime.parse(stamp, TIMED_EXDATE)
.atZone(ZoneOffset.UTC).withZoneSameInstant(zone).toLocalDateTime()
}
}.getOrNull()
/** `VALUE=DATE` EXDATE form, for an all-day series. */
private val ALL_DAY_EXDATE: DateTimeFormatter =
DateTimeFormatter.ofPattern("uuuuMMdd").withResolverStyle(ResolverStyle.STRICT)
/** UTC date-time EXDATE form, for a timed series. */
private val TIMED_EXDATE: DateTimeFormatter =
DateTimeFormatter.ofPattern("uuuuMMdd'T'HHmmss'Z'").withResolverStyle(ResolverStyle.STRICT)
/**
* The `EVENT_COLOR` / `EVENT_COLOR_KEY` columns for a colour selection. A

View File

@@ -38,7 +38,7 @@
<string name="settings_theme_system">النظام</string>
<string name="settings_theme_light">فاتح</string>
<string name="settings_theme_dark">داكن</string>
<string name="month_open_menu">افتح القائمة</string>
<string name="month_open_menu">فتح القائمة</string>
<string name="month_more_actions">المزيد من الإجراءات</string>
<string name="event_detail_edit">تعديل</string>
<string name="event_detail_delete">حذف</string>
@@ -176,7 +176,7 @@
<string name="reminder_at_time">في وقت الحدث</string>
<string name="event_untitled">(بدون عنوان)</string>
<string name="reminder_channel_name">تذكيرات الحدث</string>
<string name="reminder_channel_description">الإشعارات في أوقات التذكير الخاصه بأحداثك</string>
<string name="reminder_channel_description">الإشعارات في أوقات التذكير بأحداثك</string>
<string name="reminder_onboarding_title">لا تفوّت أي حدث أبدًا</string>
<string name="reminder_onboarding_body">أندرويد لا يعرض تذكيرات الأحداث من نفسه — بل يجب أن يقوم تطبيق تقويم بذلك. دع Calendula يتولى هذه المهمة.</string>
<string name="reminder_benefit_delivery_body">كل تذكير لأحداثك يصِل كإشعار، في الوقت المحدد تمامًا.</string>
@@ -238,7 +238,7 @@
<string name="settings_time_format_24h">٢٤-ساعة (١٤:٠٠)</string>
<string name="agenda_range_day">اليوم</string>
<string name="settings_agenda_show_today">إظهار اليوم دائمًا</string>
<string name="settings_agenda_show_today_hint">اترك اليوم في أعلى الجدول و ودجته، حتى بعد عدم وجود أي شيء اليوم.</string>
<string name="settings_agenda_show_today_hint">اترك اليوم في أعلى الجدول و أداته المصغرة، حتى بعد عدم وجود أي شيء اليوم.</string>
<string name="agenda_range_this_month">هذا الشهر</string>
<string name="agenda_range_this_week">هذا الأسبوع</string>
<string name="settings_past_events_show">إظهار</string>
@@ -249,7 +249,7 @@
<string name="event_edit_timezone_all">جميع المناطق الزمنية</string>
<string name="event_edit_timezone_none">لا منطقة زمنية تطابق ”%1$s“</string>
<string name="event_edit_timezone_local_time">%1$s توقيتك</string>
<string name="event_edit_timezone_recent">الأحدث</string>
<string name="event_edit_timezone_recent">الأخيرة</string>
<string name="event_edit_recurrence_incomplete">أدخل رقمًا من ١ إلى ٩٩٩</string>
<plurals name="duration_minutes">
<item quantity="zero">(%d) لا دقائق</item>
@@ -286,7 +286,7 @@
<string name="agenda_span_starts">يبدأ %1$s</string>
<string name="agenda_span_ends">ينتهي %1$s</string>
<string name="today_jump_action">الانتقال إلى اليوم</string>
<string name="widget_refresh">تحديث</string>
<string name="widget_refresh">إعادة تحميل</string>
<string name="settings_app_name">اسم التطبيق</string>
<string name="settings_dim_completed">تعتيم الأحداث المكتملة</string>
<string name="settings_dim_completed_summary">تعتيم الأحداث التي انتهت بالفعل في عرض الشهر والأسبوع</string>
@@ -335,8 +335,8 @@
<item quantity="many">%d يوم</item>
<item quantity="other">%d يوم</item>
</plurals>
<string name="settings_agenda_range_bar_hint">اعرض شريطًا في الجزء العلوي من الجدول يحدد التواريخ المعروضة، مع زر لتبديل النطاق للجلسة</string>
<string name="settings_agenda_range_bar">شريط النطاق</string>
<string name="settings_agenda_range_bar_hint">اعرض شريطًا في الجزء العلوي من الجدول يحدد التواريخ المعروضة، مع زر لتبديل المدى للجلسة</string>
<string name="settings_agenda_range_bar">شريط المدى</string>
<string name="settings_month_header">عرض الشهر</string>
<string name="month_style_continuous">تمرير الشهور</string>
<string name="month_style_dense">أسابيع سلسة</string>
@@ -424,7 +424,7 @@
<string name="settings_views_subtitle">العرض، التخطيط، الترتيب</string>
<string name="settings_event_form_subtitle">الخانات الافتراضية و السلوك</string>
<string name="settings_notifications_subtitle">التذكيرات و التسليم</string>
<string name="settings_special_dates_subtitle">أعياد ميلاد جهات الاتصال و احتفالات ذكرى</string>
<string name="settings_special_dates_subtitle">أعياد ميلاد جهات الاتصال و الذكرات السنوية</string>
<string name="settings_special_dates_type_birthday">أعياد الميلاد</string>
<string name="settings_special_dates_type_custom">تواريخ أخرى</string>
<string name="settings_license">الترخيص</string>
@@ -432,7 +432,7 @@
<string name="settings_special_dates_disable_confirm">إيقاف</string>
<string name="settings_special_dates_sync_now">زامن الآن</string>
<string name="settings_special_dates_never_synced">لم تتم المزامنة بعد</string>
<string name="settings_special_dates_paused_hint">لم يعد بإمكان Calendula قراءة جهات الاتصال الخاصة بك، لذلك لا يتم تحديث هذه التقويمات.</string>
<string name="settings_special_dates_paused_hint">لم يعد بإمكان Calendula قراءة جهات اتصالك، لذلك لا يتم تحديث هذه التقويمات.</string>
<string name="calendars_manage_in_app">الإدارة في التطبيق</string>
<string name="calendars_enable_all">تفعيل الكل</string>
<string name="calendars_disable_all">تعطيل الكل</string>
@@ -500,11 +500,11 @@
<string name="settings_qs_tile">إضافة مربع الإعدادات السريعة</string>
<string name="import_button">استيراد</string>
<string name="crash_dialog_dismiss">ليس الآن</string>
<string name="crash_report_copied">تم نسخ التقرير إلى الحافظة</string>
<string name="crash_report_open_failed">تعذّر فتح متتبع المشكلات. التقرير موجود في الحافظة الخاصة بك.</string>
<string name="crash_report_copied">تم نسخ التقرير إلى حافظتك</string>
<string name="crash_report_open_failed">تعذّر فتح متتبع المشكلات. التقرير موجود في حافظتك.</string>
<string name="crash_report_issue_title">تقرير العطل</string>
<string name="crash_report_clip_label">%1$s تقرير العطل</string>
<string name="crash_report_body_paste">_(كان التقرير طويلًا جدًا لهذا الرابط — الصقه من الحافظة هنا.)_</string>
<string name="crash_report_body_paste">_(كان التقرير طويلًا جدًا لهذا الرابط — الصقه من حافظتك هنا.)_</string>
<string name="special_dates_calendar_birthday">أعياد الميلاد</string>
<string name="special_dates_calendar_custom">التواريخ الخاصة</string>
<string name="event_edit_recurrence_next_none">هذه القاعدة لا تتكرر أبدًا</string>
@@ -515,18 +515,18 @@
<string name="month_split_expand">إظهار الشهر بأكمله</string>
<string name="settings_week_day_header">الأسبوع و اليوم</string>
<string name="settings_default_view_hint">طريقة العرض التي يفتحها Calendula عندما تقوم ببدءه.</string>
<string name="settings_week_start_hint">اليوم الذي يبدأ به كل أسبوع، في جميع طرق العرض والودجتز.</string>
<string name="settings_week_start_hint">اليوم الذي يبدأ به كل أسبوع، في جميع طُرق العرض والأدوات المصغّرة.</string>
<string name="settings_time_format_hint">كيف الأوقات تُكتب في جميع أنحاء التطبيق. تلقائيًا يتبع إعداد نظامك.</string>
<string name="settings_past_events_hint">ما الذي يفعله جدول بالأحداث التي انتهت بالفعل.</string>
<string name="calendars_visibility_a11y">إظهار \"%1$s\"</string>
<string name="calendars_visibility_notice_title">بعض التقويمات متوقفة</string>
<string name="calendars_visibility_notice_message">Calendula يعرض التقويمات التي تم تشغيلها لهذا الجهاز، وبعض من خاصتك متوقفة. لرؤية أحداثهم، قم بتشغيلهم ضمن الإعدادات ← التقويمات.</string>
<string name="calendar_picker_missing_title">تفتقد تقويمًا؟</string>
<string name="calendar_picker_missing_summary">قد يكون متوقفًا عن التشغيل، للقراءة فقط أو مملوءًا من جهات الاتصال الخاصة بك — يمكنك إدارة تقويماتك هنا.</string>
<string name="calendar_picker_missing_summary">قد يكون متوقفًا عن التشغيل، للقراءة فقط أو مملوءًا من جهات اتصالك — يمكنك إدارة تقويماتك هنا.</string>
<string name="calendars_state_read_only">للقراءة فقط</string>
<string name="calendars_state_not_synced">لم تتم المزامنة مع هذا الجهاز</string>
<string name="calendars_state_managed">تم ملؤه من جهات اتصالك</string>
<string name="calendars_managed_delete_locked">تم ملء هذا التقويم من جهات الاتصال الخاصة بك، لذلك سيقوم Calendula بإنشائه مرة أخرى في المزامنة التالية. قم بإيقاف تشغيل التواريخ الخاصة ضمن الإعدادات ← التواريخ الخاصة لحذفها.</string>
<string name="calendars_managed_delete_locked">تم ملء هذا التقويم من جهات اتصالك، لذلك سيقوم Calendula بإنشائه مرة أخرى في المزامنة التالية. قم بإيقاف تشغيل التواريخ الخاصة ضمن الإعدادات ← التواريخ الخاصة لحذفها.</string>
<string name="duration_custom_max">كحد أقصى %1$s</string>
<string name="settings_calendar_duration_inherits">الافتراضي (%1$s)</string>
<string name="settings_calendar_duration_use_default">استخدام المدة الافتراضية (%1$s)</string>
@@ -656,26 +656,53 @@
<string name="settings_special_dates_calendar_hint">اضبط لون كل تقويم وإمكانية ظهوره في إعدادات التقويمات.</string>
<string name="calendars_visibility_hint">قم بإيقاف تقويم لإخفائه على هذا الجهاز — تختفي أحداثه من التطبيق ويتوقف عن تذكيرك. هذا هو مفتاح التبديل نفسه الذي تستخدمه تطبيقات التقويم الأخرى خاصتك، لذلك تقوم بإخفائه أيضًا. لا شيء يتم حذفه، ولا يتأثر أي جهاز آخر، ويمكنك إعادة تشغيله من هنا في أي وقت.</string>
<string name="settings_allday_reminder_fires_at">يتم الإشعار في %1$s</string>
<string name="settings_agenda_widget_range">نطاق ودجت الجدول</string>
<string name="settings_widget_size">حجم ودجت الجدول</string>
<string name="settings_widgets_subtitle">ودجت الجدول، عنصر الإعدادات السريعة</string>
<string name="settings_agenda_widget_range">مدى أداة الجدول</string>
<string name="settings_widget_size">حجم أداة الجدول</string>
<string name="settings_widgets_subtitle">أداة الجدول، عنصر الإعدادات السريعة</string>
<string name="settings_drag_to_reschedule">السحب لتعديل الموعد</string>
<string name="settings_drag_to_reschedule_summary">انقل حدثًا عن طريق سحبه إلى يوم أو وقت آخر</string>
<string name="event_move_blocked_series_end">لا يمكن نقل حدث بعد نهاية سلسلته</string>
<string name="crash_dialog_report">تقرير</string>
<string name="settings_quick_switch_hint">اختر أي طُرق العرض التي يتم التنقل بينها باستخدام الزر الموجود في أعلى اليمين، واسحب لإعادة ترتيبها. تظل طرق العرض التي تم إيقاف تشغيلها متاحة من قائمة التنقل.</string>
<string name="settings_quick_switch_hint">اختر أي طُرق العرض التي يتم التنقل بينها باستخدام الزر في أعلى اليمين، واسحب لإعادة ترتيبهم. تظل طُرق العرض التي تم إيقافها متاحة من قائمة التنقل.</string>
<string name="calendars_account_from_source">%1$s (%2$s)</string>
<string name="duration_hours_minutes">%1$s %2$s</string>
<string name="settings_widgets_hint">إعدادات لوجدتز الشاشة الرئيسية وعنصر لوحة الإعدادات السريعة. أضف وجدت عن طريق الضغط لفترة طويلة على شاشتك الرئيسية.</string>
<string name="settings_widgets_hint">إعدادات لأدوات الشاشة الرئيسية وعنصر الإعدادات السريعة. أضف أداة عن طريق الضغط لفترة طويلة على شاشتك الرئيسية.</string>
<string name="import_warning_attendees">لم يتم استيراد قوائم الضيوف.</string>
<string name="settings_reliable_delivery_exempt">معفى من تحسين البطارية — تصل التذكيرات في الوقت المحدد.</string>
<string name="settings_reliable_delivery">توصيل موثوق</string>
<string name="settings_allday_reminder_time_hint">تنطلق التذكيرات لأحداث التي تستمر طوال اليوم عند %1$s</string>
<string name="agenda_range_override_hint">فقط للآن — يعيد التعيين إلى المدى المحفوظ الخاص بك عند إعادة فتح Calendula.</string>
<string name="agenda_range_override_hint">فقط للآن — يعيد التعيين للمدى المحفوظ خاصتك عند إعادة فتح Calendula.</string>
<string name="settings_past_events_sample_morning">مراجعة الفريق</string>
<string name="settings_past_events_sample_midday">غداء مع روبن</string>
<string name="settings_past_events_sample_evening">ممارسة الجوقة</string>
<string name="settings_special_dates_last_synced">آخر مزامنة %1$s</string>
<string name="settings_special_dates_disable_type_message">يؤدي هذا لحذف التقويم ”%1$s“ وأحداثه. سيتم فقدان أي تذكيرات أو ملاحظات أضفتها إليه.</string>
<string name="special_dates_default_title_birthday">عيد ميلاد {name} ({year})</string>
<string name="event_move_action">نقل…</string>
<string name="settings_font_specimen_heading">الخميس، 14 مايو</string>
<string name="settings_font_specimen_body">مراجعة الفريق في 10:00، ثم الغداء مع روبن في المقهى في ماركتبلاتز.</string>
<string name="settings_section_widgets">الأدوات المصغّرة والعناصر</string>
<string name="settings_widget_size_hint">مدى حجم النص الذي يعرضه جدول أداة الشاشة الرئيسية. أداة الشهر ليس لديه إعداد — تتناسب شبكته دائمًا نفسه للمساحة التي تمنحها إيّاه.</string>
<string name="settings_agenda_widget_range_hint">كم مدى يعرض جدول أداة الشاشة الرئيسية الأحداث.</string>
<string name="settings_agenda_range_hint">كم مدى يعرض شاشة الجدول الأحداث.</string>
<string name="app_name">Calendula</string>
<string name="font_atkinson_hyperlegible">Atkinson Hyperlegible</string>
<string name="settings_special_dates_show_year">إظهار السنة</string>
<string name="settings_special_dates_show_year_hint">تضمين {year} في العناوين عندما يكون معروفًا</string>
<string name="special_dates_default_title_custom">{name}</string>
<string name="special_dates_default_title_anniversary">ذكرى {name} السنوية ({year})</string>
<string name="special_dates_calendar_anniversary">الذكرات السنوية</string>
<string name="crash_dialog_message">أُغلق %1$s بشكل غير متوقع في المرة الأخيرة. يمكنك المساعدة في إصلاحه عن طريق إرسال هذا التقرير كمشكلة. سيبقى على جهازك حتى تختار مشاركته، ولا يتضمن أي بيانات شخصية أو محتوى تقويم — فقط التفاصيل الفنية أدناه.</string>
<string name="font_lora">Lora</string>
<string name="font_jetbrains_mono">JetBrains Mono</string>
<string name="onboarding_backup_benefit_folder_title">مجلد تختاره</string>
<string name="import_warning_timezone">منطقة زمنية غير معروفة ترجع إلى الخاصة بجهازك.</string>
<string name="settings_calendar_reminders_managed_hint">تعيين في تواريخ جهات الاتصال الخاصة</string>
<string name="settings_special_dates_disable_all_message">يؤدي هذا إلى حذف تقويمات تواريخ جهات الاتصال وأحداثها. سيتم فقدان أي تذكيرات أو ملاحظات أضفتها إليها.</string>
<string name="settings_special_dates_type_anniversary">الذكرات السنوية</string>
<string name="settings_special_dates_template_hint">استخدم {name} لجهة الاتصال و{year} للسنة (سنة الميلاد، أو سنة بدء الذكرى السنوية؛ مخفية عندما تكون غير معروفة).</string>
<string name="settings_special_dates_template">صيغة العنوان</string>
<string name="settings_calendar_reminders_hint">تجاوز الافتراضي لكل تقويم — بشكل منفصل للمحدد بوقت وأحداث طوال اليوم. يمكن لتقويم الاحتفاظ بالافتراضي، إسقاطه أو تعيين خاصّته.</string>
<string name="event_move_occurrence_only">سيؤدي نقل السلسلة بأكملها لتغيير الأيام التي تقع فيها، لذلك يمكن نقل هذا الحدث فقط.</string>
<string name="agenda_empty_title">أنت على اطلاع</string>
</resources>

View File

@@ -0,0 +1,474 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="backup_interval_units">
<item>Minutes</item>
<item>Hours</item>
<item>Days</item>
<item>Weeks</item>
</string-array>
<string name="app_tagline">Сучасны каляндар.</string>
<string name="state_loading">Загрузка…</string>
<string name="state_retry">Паўтарыць спробу</string>
<string name="state_failure_unknown">Узнікла нейкая праблема.</string>
<string name="state_failure_permission">Патрабуецца доступ да календара.</string>
<string name="state_failure_permission_action">Дазволіць доступ</string>
<string name="state_failure_no_calendars">Календары не сканфігураваныя.</string>
<string name="state_failure_no_calendars_action">Адкрыць сыстэмныя налады календароў</string>
<string name="state_failure_provider">Немагчыма прачытаць каляндар.</string>
<string name="permission_rationale_title">Прагляд усіх падзеяў у прыгожым выглядзе</string>
<string name="permission_rationale_body">Для паказу і кіраваньня падзеямі Calendula патрабуецца доступ да вашага календара.</string>
<string name="permission_request_button">Дазволіць доступ да календара</string>
<string name="permission_denied_title">Няма доступу да календара</string>
<string name="permission_denied_body">Calendula ня можа паказваць падзеі бяз доступу да календара.</string>
<string name="permission_open_settings_button">Адкрыць сыстэмныя налады</string>
<string name="permission_retry_button">Паўтарыць спробу</string>
<string name="permission_benefit_private_title">Распрацавана з акцэнтам на прыватнасьць</string>
<string name="permission_benefit_private_body">Бяз доступу да Інтэрнэту, без тэлемэтрыі — нічога і ніколі не пакідае ваш тэлефон.</string>
<string name="permission_benefit_sync_title">Усе вашы календары разам</string>
<string name="permission_benefit_sync_body">Google, CalDAV, лякальныя — паказваюцца ўсе, сынхранізаваныя з прыладай.</string>
<string name="permission_benefit_privacy_title">Ніякага адсочваньня, ніколі</string>
<string name="permission_benefit_privacy_body">Без тэлемэтрыі, без аналітыкі, без рэклямы.</string>
<string name="permission_privacy_footnote">Усё застаецца на прыладзе, доступ да Інтэрнэту не патрабуецца</string>
<string name="month_prev">Папярэдні месяц</string>
<string name="month_next">Наступны месяц</string>
<string name="month_today_action">Сёньня</string>
<string name="month_more_actions">Іншыя дзеяньні</string>
<string name="month_open_menu">Адкрыць мэню</string>
<string name="month_action_settings">Налады</string>
<string name="month_a11y_today_prefix">Сёньня</string>
<string name="week_today_action">Гэты тыдзень</string>
<string name="week_number_label">Тдз.</string>
<string name="day_today_action">Сёньня</string>
<string name="event_detail_back">Назад</string>
<string name="event_detail_edit">Праўка</string>
<string name="event_detail_delete">Выдаліць</string>
<string name="event_detail_share">Падзяліцца</string>
<string name="event_detail_duplicate">Дублікат</string>
<string name="event_share_chooser_title">Падзяліцца падзеяй</string>
<string name="event_share_failed">Не атрымалася падзяліцца гэтай падзеяй.</string>
<string name="event_delete_title">Выдаліць падзею?</string>
<string name="event_delete_body">Падзея выдаленая з вашага календара і з усіх прыладаў, зь якімі адбываецца сынхранізацыя.</string>
<string name="event_delete_recurring_title">Выдаліць пэрыядычную падзею</string>
<string name="event_delete_option_occurrence">Толькі гэтую падзею</string>
<string name="event_delete_option_following">Гэтую і ўсе наступныя падзеі</string>
<string name="event_delete_option_series">Усе падзеі ў пасьлядоўнасьці</string>
<string name="event_edit_recurring_title">Рэдагаваць пэрыядычную падзею</string>
<string name="event_delete_failed">Не атрымалася выдаліць падзею</string>
<string name="event_delete_write_denied">Для выдаленьня падзеяў Calendula патрабуецца дазвол на запіс</string>
<string name="event_move_action">Перанесці…</string>
<string name="event_move_recurring_title">Перанесці пэрыядычную падзею</string>
<string name="event_move_occurrence_only">Перанос усёй пасьлядоўнасьці зьменіць дні, на якія яна прыпадае, таму перанесці можна толькі гэтую падзею.</string>
<string name="event_move_done">Перанесена на %1$s</string>
<string name="event_move_undo">АдрабІць</string>
<string name="event_move_undone">Перанос скасаваны</string>
<string name="event_move_failed">Не атрымалася перанесьці падзею</string>
<string name="event_move_write_denied">Для пераносу падзеяў Calendula патрабуецца дазвол на запіс</string>
<string name="event_move_gone">Гэтай падзеі больш не існуе</string>
<string name="event_move_blocked_series_end">Нельга перанесьці падзею на дату пасьля заканчэньня яе пасьлядоўнасьці</string>
<string name="dialog_cancel">Адмена</string>
<string name="dialog_ok">ОК</string>
<string name="event_edit_new_title">Новая падзея</string>
<string name="event_edit_close">Закрыць</string>
<string name="event_edit_save">Захаваць</string>
<string name="event_edit_title_hint">Дадаць загаловак</string>
<string name="event_edit_managed_hint">Кіруецца «%1$s» — загаловак, дата і паўтор сынхранізуюцца з вашымі кантактамі. Напаміны, месцазнаходжаньне і нататкі даступныя вам для рэдагаваньня.</string>
<string name="event_edit_starts">Пачатак</string>
<string name="event_edit_ends">Заканчэньне</string>
<string name="event_edit_error_end_before_start">Заканчваецца раней, чым пачынаецца</string>
<string name="event_edit_error_no_calendar">Няма календара, у які дазволены запіс</string>
<string name="event_edit_save_failed">Не атрымалася захаваць падзею</string>
<string name="event_edit_write_denied">Для стварэньня падзеяў Calendula патрабуецца дазвол на запіс</string>
<string name="event_edit_more_fields">Дадатковыя палі</string>
<string name="event_edit_add">Дадаць</string>
<string name="event_edit_add_reminder">Дадаць напамін</string>
<string name="event_edit_remove_reminder">Выдаліць напамін</string>
<string name="event_edit_attendees">Наведвальнікі</string>
<string name="event_edit_add_guest">Дадаць наведвальніка</string>
<string name="event_edit_add_guest_hint">Дадаць наведвальніка праз электронную пошту…</string>
<string name="event_edit_add_guest_from_contacts">Дадаць з кантактаў</string>
<string name="event_edit_location_from_contacts">Выбраць адрас з кантактаў</string>
<string name="event_edit_remove_guest">Выдаліць наведвальніка</string>
<string name="event_edit_attendee_required">Неабходны</string>
<string name="event_edit_attendee_optional">Неабавязковы</string>
<string name="event_edit_attendees_note_synced">Calendula не рассылае запрашэньні. Наведвальнікі могуць атрымаць электронныя лісты з вашага ўліковага запісу календара пры сынхранізацыі.</string>
<string name="event_edit_attendees_note_local">Захавана на гэтай прыладзе. Ніхто не атрымаў абвесткі.</string>
<string name="event_edit_reminder_custom">Карыстальніцкі</string>
<string name="reminder_unit_minutes">хв.</string>
<string name="reminder_unit_hours">гадз.</string>
<string name="reminder_unit_days">сут.</string>
<string name="reminder_unit_weeks">тыд.</string>
<string name="event_edit_availability">Даступнасьць</string>
<string name="event_edit_visibility">Бачнасьць</string>
<string name="event_edit_timezone_device">Часавы пояс прылады</string>
<string name="event_edit_timezone_device_summary">Сочыць за вашым месцазнаходжаньнем</string>
<string name="event_edit_timezone_search">Пошук часавых паясоў</string>
<string name="event_edit_timezone_recent">Апошнія</string>
<string name="event_edit_timezone_all">Усе часавыя паясы</string>
<string name="event_edit_timezone_none">Няма часавага поясу, які адпавядае «%1$s»</string>
<string name="event_edit_timezone_local_time">%1$s паводле вашага часу</string>
<string name="event_edit_color">Колер</string>
<string name="event_edit_color_default">Колер календара</string>
<string name="event_edit_color_custom">Карыстальніцкі колер</string>
<string name="event_edit_color_reset">Скід</string>
<string name="event_edit_color_unsupported">Недаступна для гэтага календара</string>
<string name="event_edit_color_unsupported_hint">Для гэтага календара не апублікаваны набор колераў. Для падобных календароў у наладах можна задаць карыстальніцкія колеры.</string>
<string name="event_edit_color_sync_warning">Пры наступнай сынхранізацыі гэты каляндар можа страціць або перазапісаць колер.</string>
<string name="event_edit_conflict_title">Падзея зьмянілася ў іншым месцы</string>
<string name="event_edit_conflict_body">Падчас рэдагаваньня вамі гэтая падзея была зьменена ў выніку сынхранізацыі або іншай праграмай. Што адбудзецца з вашымі зьменамі?</string>
<string name="event_edit_conflict_overwrite">Захаваць мае змены</string>
<string name="event_edit_conflict_overwrite_hint">Толькі адрэдагаваныя вамі палі перазапішуць зьнешнія зьмены</string>
<string name="event_edit_conflict_discard">Адкінуць мае зьмены</string>
<string name="event_edit_conflict_discard_hint">Падзея застаецца такой, якой яна ёсьць зараз</string>
<string name="event_edit_gone_title">Падзея выдалена</string>
<string name="event_edit_gone_body">Гэтая падзея ўжо выдаленая, напрыклад на іншай прыладзе. Вашыя зьмены болей немагчыма захаваць.</string>
<string name="import_reminder_prompt_title">Ужыць напамін па змаўчаньні?</string>
<string name="import_reminder_prompt_body_none">Гэтая падзея была імпартаваная без напаміну.</string>
<plurals name="import_reminder_prompt_body_existing">
<item quantity="one">"Гэтая падзея была імпартаваная з наст. колькасьцю напамінаў: %1$d."</item>
<item quantity="few">"Гэтая падзея была імпартаваная з наст. колькасьцю напамінаў: %1$d."</item>
<item quantity="many">"Гэтая падзея была імпартаваная з наст. колькасьцю напамінаў: %1$d."</item>
<item quantity="other">"Гэтая падзея была імпартаваная з наст. колькасьцю напамінаў: %1$d."</item>
</plurals>
<string name="import_reminder_prompt_apply">Ужыць змаўчаньні</string>
<string name="import_reminder_prompt_keep">Пакінуць як ёсьць</string>
<string name="event_edit_recurrence_none">Не паўтараецца</string>
<string name="event_edit_recurrence_custom">Карыстальніцкі варыянт</string>
<string name="event_edit_recurrence_every">Кожн.</string>
<string name="recurrence_unit_days">сут.</string>
<string name="recurrence_unit_weeks">тыд.</string>
<string name="recurrence_unit_months">мес.</string>
<string name="recurrence_unit_years">год/гады</string>
<string name="event_edit_recurrence_incomplete">Увядзеце лік ад 1 да 999</string>
<string name="event_edit_recurrence_next">Наступ.: %1$s</string>
<string name="event_edit_recurrence_next_none">Гэтае правіла ніколі не паўтараецца</string>
<string name="event_edit_recurrence_ends">Заканчэньне</string>
<string name="event_edit_recurrence_end_never">Ніколі</string>
<string name="event_edit_recurrence_end_until">На дату</string>
<string name="event_edit_recurrence_end_count">Пасьля некалькіх разоў</string>
<string name="event_edit_recurrence_times">разы(оў)</string>
<string name="app_name">Calendula</string>
<string name="event_edit_error_recurrence_ends_before_start">Паўторы заканчваюцца да пачатку падзеі</string>
<string name="event_availability_busy">Заняты</string>
<string name="event_access_default">Па змаўчаньні</string>
<string name="event_access_public">Публічны</string>
<string name="event_detail_all_day">Цэлы дзень</string>
<string name="event_detail_calendar">Каляндар</string>
<string name="event_detail_calendar_unknown">Невядомы каляндар</string>
<string name="event_detail_location">Месцазнаходжаньне</string>
<string name="event_detail_description">Апісаньне</string>
<string name="event_detail_attendees">Удзельнікі</string>
<string name="event_detail_recurrence">Паўтор</string>
<string name="event_detail_recurring">Паўтаральная падзея</string>
<string name="recurrence_daily">Кожны дзень</string>
<string name="recurrence_weekly">Кожны тыдзень</string>
<string name="recurrence_monthly">Кожны месяц</string>
<string name="recurrence_yearly">Кожны год</string>
<string name="recurrence_every_n_days">Кожныя %1$d сут.</string>
<string name="recurrence_every_n_weeks">Кожныя %1$d тыд.</string>
<string name="recurrence_every_n_months">Кожныя %1$d мес.</string>
<string name="recurrence_every_n_years">Кожныя %1$d гады(оў)</string>
<string name="recurrence_on_days">%1$s у %2$s</string>
<string name="recurrence_with_until">з %1$s да %2$s</string>
<string name="recurrence_with_count">%1$s, %2$d разы(оў)</string>
<string name="event_detail_not_found">Гэтай падзеі больш не існуе.</string>
<string name="event_attendee_accepted">Прынята</string>
<string name="event_attendee_declined">Адхілена</string>
<string name="event_attendee_tentative">Пад пытаньнем</string>
<string name="event_attendee_needs_action">Няма адказу</string>
<string name="event_attendee_unknown"></string>
<string name="event_detail_reminders">Напаміны</string>
<string name="event_detail_timezone">Часавы пояс</string>
<string name="event_status_tentative">Пад пытаньнем</string>
<string name="event_status_cancelled">Скасавана</string>
<string name="event_availability_free">Свабодна</string>
<string name="event_access_private">Прыватна</string>
<string name="event_access_confidential">Канфідэнцыйна</string>
<string name="event_access_default_summary">Што звычайна робіць гэты каляндар</string>
<string name="event_access_public_summary">Поўныя зьвесткі могуць бачыць усе, хто мае доступ</string>
<string name="event_access_private_summary">Іншыя бачаць толькі тое, што вы занятыя</string>
<string name="event_access_confidential_summary">Пазначана як канфідэнцыйнае: што гэта значыць, залежыць ад уліковага запісу календара</string>
<string name="event_attendee_organizer">Арганізатар</string>
<string name="event_attendee_optional">Неабавязкова</string>
<string name="event_attendee_resource">Рэсурс</string>
<string name="event_detail_self_response">Ваш адказ: %1$s</string>
<string name="reminder_at_time">На момант падзеі</string>
<string name="reminder_default">Напамін па змаўчаньні</string>
<plurals name="reminder_minutes">
<item quantity="one">За %d хвіліну</item>
<item quantity="few">За %d хв.</item>
<item quantity="many">За %d хв.</item>
<item quantity="other">За %d хв.</item>
</plurals>
<plurals name="reminder_hours">
<item quantity="one">За %d гадзіну</item>
<item quantity="few">За %d гадз.</item>
<item quantity="many">За %d гадз.</item>
<item quantity="other">За %d гадз.</item>
</plurals>
<plurals name="reminder_days">
<item quantity="one">За %d суткі</item>
<item quantity="few">За %d сут.</item>
<item quantity="many">За %d сут.</item>
<item quantity="other">За %d сут.</item>
</plurals>
<plurals name="reminder_weeks">
<item quantity="one">За %d тыдзень</item>
<item quantity="few">За %d тыдз.</item>
<item quantity="many">За %d тыдз.</item>
<item quantity="other">За %d тыдз.</item>
</plurals>
<plurals name="duration_minutes">
<item quantity="one">%d хвіліна</item>
<item quantity="few">%d хв.</item>
<item quantity="many">%d хв.</item>
<item quantity="other">%d хв.</item>
</plurals>
<plurals name="duration_hours">
<item quantity="one">%d гадзіна</item>
<item quantity="few">%d гадз.</item>
<item quantity="many">%d гадз.</item>
<item quantity="other">%d гадз.</item>
</plurals>
<plurals name="duration_days">
<item quantity="one">%d суткі</item>
<item quantity="few">%d сут.</item>
<item quantity="many">%d сут.</item>
<item quantity="other">%d сут.</item>
</plurals>
<string name="duration_hours_minutes">%1$s гадз. %2$s хв.</string>
<string name="duration_custom_max">Макс. %1$s</string>
<plurals name="duration_weeks">
<item quantity="one">%d тыдзень</item>
<item quantity="few">%d тыдз.</item>
<item quantity="many">%d тыдз.</item>
<item quantity="other">%d тыдз.</item>
</plurals>
<string name="event_untitled">(без загалоўка)</string>
<string name="onboarding_step_counter">Крок %1$d з %2$d</string>
<string name="onboarding_backup_title">Вашы падзеі знаходзяцца толькі тут</string>
<string name="onboarding_backup_body">На гэтым тэлефоне не адбываецца сынхранізацыя зь якім-небудзь уліковым запісам, і страта азначае страту вашага календара. Calendula можа зрабіць рэзервую копію для вас.</string>
<string name="onboarding_backup_benefit_folder_title">Каталёг на ваш выбар</string>
<string name="onboarding_backup_benefit_folder_body">Рэзэрвовыя копіі — гэта звычайныя файлы .ics. Захоўвайце іх у месцы, дзе яны сынхранізуюцца, або на SD-карце.</string>
<string name="onboarding_backup_benefit_daily_title">Раз за суткі, аўтаматычна</string>
<string name="onboarding_backup_benefit_daily_body">Calendula робіць экспарт вашых лякальных календароў у фонавым рэжыме. Зьмяніць пэрыядычнасьць можна ў наладах.</string>
<string name="onboarding_backup_enable_button">Выбраць каталёг і зрабіць рэзэрвовую копію</string>
<string name="onboarding_backup_skip_button">Ня зараз</string>
<string name="onboarding_view_title">Што павінна адкрыцца першым?</string>
<string name="onboarding_month_style_title">Як мусіць выглядаць месяц?</string>
<string name="onboarding_view_continue_button">Далей</string>
<string name="onboarding_back">Назад</string>
<string name="onboarding_visibility_button">Зразумела</string>
<string name="onboarding_done_title">Усё зроблена</string>
<string name="onboarding_done_body">Вашы календары гатовыя. Любы выбар, зроблены зараз, можна пазьней зьмяніць у наладах.</string>
<string name="onboarding_done_button">Адкрыць мой каляндар</string>
<string name="reminder_channel_name">Напаміны пра падзеі</string>
<string name="reminder_channel_description">Абвесткі ў час напамінаў пра вашы падзеі</string>
<string name="reminder_onboarding_title">Не прапускаць ніводную падзею</string>
<string name="reminder_onboarding_body">Сыстэма Android сама не паказвае напаміны — гэта мусіць рабіць дадатак календара. Хай гэта робіць Calendula.</string>
<string name="reminder_benefit_delivery_title">Напаміны, дастаўленыя</string>
<string name="reminder_benefit_delivery_body">Кожны напамін пра вашы падзеі прыходзіць у выглядзе своечасовай абвесткі.</string>
<string name="reminder_benefit_duplicates_title">Карыстаецеся яшчэ адным дадаткам календара?</string>
<string name="reminder_benefit_duplicates_body">Калі іншы дадатак таксама выдае напаміны, вы будзеце бачыць іх двойчы — адключэце іх там або тут.</string>
<string name="reminder_benefit_reversible_title">Гэта можна зьмяніць у які заўгодна час</string>
<string name="reminder_benefit_reversible_body">Перамыкач знаходзіцца ў наладах, у разьдзеле «Абвесткі».</string>
<string name="reminder_onboarding_enable_button">Уключыць напаміны</string>
<string name="reminder_onboarding_skip_button">Ня зараз</string>
<string name="reminder_action_snooze">Адкласьці</string>
<string name="reminder_action_dismiss">Адхіліць</string>
<string name="reminder_day_tomorrow">Заўтра</string>
<string name="reminder_day_yesterday">Учора</string>
<string name="view_month">Месяц</string>
<string name="view_week">Тыдзень</string>
<string name="view_day">Дзень</string>
<string name="view_agenda">Расклад</string>
<string name="view_section">Выгляд</string>
<string name="drawer_jump_to_date">Пераход да даты</string>
<string name="agenda_today_action">Сёньня</string>
<string name="agenda_header_today">Сёньня</string>
<string name="agenda_header_tomorrow">Заўтра</string>
<string name="agenda_empty_title">Усё завершана</string>
<string name="agenda_no_more_today">Сёньня больш няма падзеяў</string>
<string name="agenda_span_starts">Пачатак: %1$s</string>
<string name="agenda_span_ends">Заканчэньне: %1$s</string>
<string name="today_jump_action">Перайсці на сёньня</string>
<string name="search_action">Пошук</string>
<string name="search_hint">Пошук падзеяў</string>
<string name="search_back">Назад</string>
<string name="search_clear">Ачысьціць</string>
<string name="search_idle_hint">Пошук падзеяў па загалоўках, месцазнаходжаньні або зацемках.</string>
<string name="search_empty">Няма падзей, якія адпавядаюць «%1$s».</string>
<plurals name="search_selected_count">
<item quantity="one">Вылучана: %d</item>
<item quantity="few">Вылучана: %d</item>
<item quantity="many">Вылучана: %d</item>
<item quantity="other">Вылучана: %d</item>
</plurals>
<string name="search_in_descriptions">Знойдзена ў апісаньнях</string>
<string name="search_selection_close">Зьняць вылучэньне</string>
<string name="search_select_all">Вылучыць усё</string>
<string name="search_delete_selected">Выдаліць вылучанае</string>
<plurals name="search_delete_title">
<item quantity="one">Выдаліць падзеі (%d)?</item>
<item quantity="few">Выдаліць падзеі (%d)?</item>
<item quantity="many">Выдаліць падзеі (%d)?</item>
<item quantity="other">Выдаліць падзеі (%d)?</item>
</plurals>
<plurals name="search_delete_done">
<item quantity="one">Выдаленая %d падзея</item>
<item quantity="few">Выдалена падзеяў: %d</item>
<item quantity="many">Выдалена падзеяў: %d</item>
<item quantity="other">Выдалена падзеяў: %d</item>
</plurals>
<string name="search_delete_partial">Выдалена %1$d, не атрымалася выдаліць %2$d</string>
<string name="search_delete_denied_partial">Выдалена %1$d, затым быў скасаваны дазвол на запіс</string>
<string name="widget_agenda_title">Наступнае</string>
<string name="widget_agenda_label">Расклад Calendula</string>
<string name="widget_month_label">Месяц Calendula</string>
<string name="widget_refresh">Абнавіць</string>
<string name="widget_new_event">Новая падзея</string>
<string name="widget_needs_permission">Адкрыйце Calendula, каб дазволіць доступ да календара</string>
<string name="widget_prev_month">Папярэдні месяц</string>
<string name="widget_next_month">Наступны месяц</string>
<string name="widget_today">Сёньня</string>
<string name="filter_title">Календары</string>
<string name="settings_title">Налады</string>
<string name="settings_back">Назад</string>
<string name="back">Назад</string>
<string name="settings_section_appearance">Афармленьне</string>
<string name="settings_theme">Тэма</string>
<string name="settings_theme_system">Сыстэмная</string>
<string name="settings_theme_light">Сьветлая</string>
<string name="settings_theme_dark">Цёмная</string>
<string name="settings_theme_hint">Сьветлы або цёмны выгляд дадатку. Выбар будзе ўжыты адразу ж.</string>
<string name="settings_theme_system_summary">Зараз: %1$s</string>
<string name="settings_default_view">Выгляд па змаўчаньні</string>
<string name="settings_dynamic_color">Дынамічны колер</string>
<string name="settings_dynamic_color_unavailable">Патрабуецца сыстэма Android вэрсіі 12 або навейшай</string>
<string name="settings_soften_colors">Гарманізацыя колераў календара</string>
<string name="settings_soften_colors_summary">Вытрымліваць адценьне і яркасьць кожнага календара, каб кожная падзея заставалася чытэльнай, а колеры спалучаліся. Адключыць, каб паказваць зыходныя колеры з крыніцы календара.</string>
<string name="settings_font_headings">Шрыфт загалоўкаў</string>
<string name="settings_font_body">Шрыфт тэксту</string>
<string name="settings_font_system">Сыстэмны</string>
<string name="font_atkinson_hyperlegible">Atkinson Hyperlegible</string>
<string name="font_lora">Lora</string>
<string name="font_jetbrains_mono">JetBrains Mono</string>
<string name="settings_font_choose_file">Выбраць файл…</string>
<string name="settings_font_custom_selected">Карыстальніцкі</string>
<string name="settings_font_import_failed">Не атрымалася прачытаць файлы шрыфту</string>
<string name="settings_font_specimen_heading">Чацьвер, 14 траўня</string>
<string name="settings_font_specimen_body">Камандны разгляд а 10:00, затым абед з Робінам у кавярні на Марктпляц.</string>
<string name="settings_week_start">Тыдзень пачынаецца з</string>
<string name="settings_week_start_auto">Аўтаматычна</string>
<string name="settings_week_start_auto_summary">Зараз: %1$s</string>
<string name="settings_week_numbers">Нумары тыдняў</string>
<string name="settings_week_numbers_summary">Паказваць нумары тыдняў календара ў рэжыме прагляду месяца</string>
<string name="settings_today_toolbar">Кнопка «Сёньня» на панэлі</string>
<string name="settings_today_toolbar_summary">Паказваць кнопку пераходу да сёньняшняга дня на панэлі прыладаў замест плаваючай кнопкі</string>
<string name="settings_app_name">Назва дадатку</string>
<string name="settings_app_name_summary">Паказаць Calendula як «Каляндар» на панэлі запуску. На панэлі запуску зьменіцца толькі назва. Пасьля пераключэньня можа зьмяніцца месцазнаходжаньне абразка.</string>
<string name="settings_time_format">Фармат часу</string>
<string name="settings_time_format_auto">Аўта</string>
<string name="settings_time_format_12h">12-гадз. (2:00 пасьля абеду)</string>
<string name="settings_time_format_24h">24-гадз. (14:00)</string>
<string name="settings_time_format_auto_summary">Сыстэмная налада: %1$s</string>
<string name="settings_hour_lines">Лініі гадзінаў</string>
<string name="settings_hour_lines_summary">Паказваць раздзяляльную лінію для кожнай гадзіны ў рэжыме прагляду тыдня і дня</string>
<string name="settings_timeline_scale">Вышыня гадзіны</string>
<string name="settings_timeline_scale_hint">Колькі прасторы па вэртыкалі даецца на гадзіну ў рэжыме прагляду тыдня і дня. Гэтая налада агульная для абодвух рэжымаў прагляду. Таксама можна двума пальцамі перамяшчаць лінію, каб задаць нейкую іншую вышыню для гадзінаў.</string>
<string name="timeline_scale_fit_day">Цэлыя суткі</string>
<string name="timeline_scale_fit_day_summary">На экране ўсе 24 гадзіны, прагортваць ня трэба</string>
<string name="timeline_scale_compact">Кампактна</string>
<string name="timeline_scale_compact_summary">На экране больш гадзінаў, блёкі меншыя</string>
<string name="timeline_scale_regular">Звычайна</string>
<string name="timeline_scale_regular_summary">Стандартны інтэрвал</string>
<string name="timeline_scale_comfortable">Камфортна</string>
<string name="timeline_scale_comfortable_summary">Большыя блёкі, больш прагорткі</string>
<string name="timeline_scale_custom">Карыстальніцкі варыянт</string>
<string name="timeline_scale_custom_summary">Вышыня ў выніку перамяшчэньня лініі пальцамі</string>
<string name="settings_dim_completed">Зацямняць завершаныя падзеі</string>
<string name="settings_dim_completed_summary">Зацямняць завершаныя падзеі ў рэжыме прагляду месяца і тыдня</string>
<string name="settings_drag_to_reschedule">Перацягваць, каб пераплянаваць</string>
<string name="settings_drag_to_reschedule_summary">Перанесьці падзею, перацягнуўшы яе на іншы дзень або час</string>
<string name="settings_past_events">Мінулыя падзеі</string>
<string name="settings_past_events_show">Паказваць</string>
<string name="settings_past_events_dim">Зацямняць</string>
<string name="settings_past_events_hide">Хаваць</string>
<string name="settings_past_events_sample_morning">Камандны разгляд</string>
<string name="settings_past_events_sample_midday">Абед з Робінам</string>
<string name="settings_past_events_sample_evening">Рэпетыцыя ў хоры</string>
<string name="settings_agenda_header">Расклад</string>
<string name="settings_agenda_range">Дыяпазон раскладу</string>
<string name="settings_agenda_range_hint">Наколькі далёка наперад паказваюцца падзеі на экране раскладу.</string>
<string name="settings_agenda_widget_range">Дыяпазон віджэта раскладу</string>
<string name="settings_agenda_widget_range_hint">Наколькі далёка наперад паказваюцца падзеі раскладу на галоўным экране віджэта.</string>
<string name="settings_widget_size">Памер віджэта раскладу</string>
<string name="settings_widget_size_hint">Наколькі вялікім выглядае галоўны экран, на які выводзіцца тэкст раскладу. Віджэт у рэжыме прагляду месяца ня мае падобнага парамэтра, ягоная сетка займае ўсю выдзеленую прастору.</string>
<string name="settings_widget_size_small">Дробны</string>
<string name="settings_widget_size_medium">Сярэдні</string>
<string name="settings_widget_size_large">Буйны</string>
<string name="settings_widget_size_extra_large">Вельмі буйны</string>
<string name="settings_widget_size_summary">Тэкст падзеі %1$d%%</string>
<string name="settings_agenda_show_today">Заўсёды паказваць сёньняшні дзень</string>
<string name="settings_agenda_show_today_hint">Сёньняшні дзень застаецца ў верхняй частцы раскладу і віджэта, нават калі падзеяў больш няма.</string>
<string name="settings_agenda_range_bar">Панэль дыяпазона</string>
<string name="settings_agenda_range_bar_hint">Паказваць уверсе панэль раскладу зь пералікам паказаных дат і кнопку для пераключэньня дыяпазону для сэсіі</string>
<string name="agenda_range_day">Сёньня</string>
<string name="agenda_range_this_week">Гэты тыдзень</string>
<string name="agenda_range_this_month">Гэты месяц</string>
<string name="agenda_range_week">Наступныя 7 сутак</string>
<string name="agenda_range_month">Наступныя 30 сутак</string>
<string name="agenda_range_custom">Свой варыянт…</string>
<string name="agenda_range_custom_hint">Суткі</string>
<string name="agenda_range_override_hint">Толькі цяпер. Пры паўторным адкрыцьці Calendula дыяпазон скінецца да захаванага значэньня.</string>
<string name="agenda_range_showing_label">Паказаныя ўсе будучыя падзеі для</string>
<plurals name="agenda_range_days">
<item quantity="one">%d суткі</item>
<item quantity="few">%d сут.</item>
<item quantity="many">%d сут.</item>
<item quantity="other">%d сут.</item>
</plurals>
<string name="settings_section_views">Рэжымы прагляду</string>
<string name="settings_special_dates_type_birthday">Дні нараджэньня</string>
<string name="settings_special_dates_type_anniversary">Юбілейныя даты</string>
<string name="settings_special_dates_type_custom">Іншыя даты</string>
<string name="settings_special_dates_template">Фармат загалоўка</string>
<string name="settings_special_dates_template_hint">Ужываць {name} для імя кантакту і {year} для года (год нараджэньня або год пачатку юбілейнай падзеі; схаваны, калі невядомы).</string>
<string name="settings_special_dates_reminders">Напаміны</string>
<string name="settings_special_dates_show_year">Паказаць год</string>
<string name="settings_special_dates_show_year_hint">Пазначаць {year} (год) у загалоўках, калі вядомы</string>
<string name="settings_special_dates_sync_now">Сынхранізаваць зараз</string>
<string name="settings_special_dates_never_synced">Пакуль не сынхранізавана</string>
<string name="settings_special_dates_last_synced">Апошняя сынхранізацыя %1$s</string>
<string name="settings_special_dates_calendar_hint">Задаць у наладах колер і бачнасьць кожнага календара.</string>
<string name="settings_calendar_reminders_managed_hint">Задаць асаблівыя даты кантактаў</string>
<string name="settings_special_dates_paused_title">Прыпынена</string>
<string name="settings_special_dates_paused_hint">Calendula больш ня можа чытаць вашы кантакты, таму гэтыя календары не абнаўляюцца.</string>
<string name="settings_special_dates_grant">Дазволіць доступ</string>
<string name="settings_special_dates_disable_title">Адключыць даты кантактаў?</string>
<string name="settings_special_dates_disable_all_message">Пры гэты выдаляцца календары з датамі кантактаў і адпаведныя падзеі. Даданыя да іх напаміны або заўвагі зьнікнуць.</string>
<string name="settings_special_dates_disable_type_message">Пры гэтым выдаліцца каляндар «%1$s» зь ягонымі падзеямі. Даданыя да іх напаміны або зацемкі зьнікнуць.</string>
<string name="settings_special_dates_disable_confirm">Адключыць</string>
<string name="dialog_save">Захаваць</string>
<string name="settings_section_about">Аб дадатку</string>
<string name="settings_license">Ліцэнзія</string>
<string name="settings_license_value">MIT</string>
<string name="settings_about_author">аўтар: Жан-Люк Макіёла</string>
<string name="settings_about_source">Зыходны код</string>
<string name="settings_about_privacy">Палітыка канфідэнцыйнасьці</string>
<string name="settings_about_support">Падтрымка распрацоўкі</string>
<string name="settings_about_version">Вэрсія %1$s</string>
<string name="settings_about_logo_desc">Абразок дадатку Calendula</string>
<string name="settings_report_problem">Паведаміць пра праблему</string>
<string name="settings_report_problem_hint">Адправіць справаздачу аб краху або адкрыць сыстэму адсочваньня праблемаў</string>
<string name="calendars_title">Календары</string>
<string name="calendars_local_header">Вашыя календары</string>
<string name="calendars_local_empty">Пакуль няма лякальных календароў. Стварыць, каб захоўваць падзеі толькі на гэтай прыладзе.</string>
<string name="calendars_add">Дадаць каляндар</string>
<string name="calendars_visibility_hint">Адключыць каляндар, каб схаваць яго на гэтай прыладзе — падзеі і напаміны зь яго зьнікнуць з дадатку. Гэты перамыкач выкарыстоўваюць іншыя дадаткі календара, таму яны таксама яго схаваюць. Нічога не выдаляецца, гэта не ўплывае на іншыя прылады, і вы можаце ўключыць яго зноў тут у які заўгодна час.</string>
<string name="calendars_visibility_a11y">Паказаць «%1$s»</string>
<string name="calendars_visibility_notice_title">Некаторыя календары адключаныя</string>
<string name="calendars_visibility_notice_message">Calendula паказвае календары, уключаныя на гэтай прыладзе, а некаторыя з вашых адключаны. Каб убачыць падзеі ў іх, уключэце іх у разьдзеле «Налады» → «Календары».</string>
<string name="calendar_picker_missing_title">Не хапае календара?</string>
<string name="calendar_picker_missing_summary">Магчыма ён адключаны, у рэжыме толькі чытаньня, або запоўнены з вашых кантактаў — кіруйце календарамі тут.</string>
<string name="calendars_state_read_only">Толькі чытаньне</string>
</resources>

View File

@@ -43,25 +43,25 @@
<string name="day_today_action">Dnes</string>
<string name="event_detail_back">Zpět</string>
<string name="event_detail_edit">Upravit</string>
<string name="event_detail_delete">Vymazat</string>
<string name="event_detail_delete">Odstranit</string>
<string name="event_detail_share">Sdílet</string>
<string name="event_detail_duplicate">Kopírovat</string>
<string name="event_share_chooser_title">Sdílet událost</string>
<string name="event_share_failed">Tuto událost nelze sdílet.</string>
<string name="event_delete_title">Odstranit událost?</string>
<string name="event_delete_body">Událost je odstraněna z kalendáře i ze všech synchronizovaných zařízení.</string>
<string name="event_delete_recurring_title">Smazat opakující se událost</string>
<string name="event_delete_recurring_title">Odstranit opakující se událost</string>
<string name="event_delete_option_occurrence">Pouze tuto událost</string>
<string name="event_delete_option_following">Tuto a všechny následující události</string>
<string name="event_delete_option_series">Všechny události v sérii</string>
<string name="event_edit_recurring_title">Upravit opakující se událost</string>
<string name="event_delete_failed">Tuto událost nelze odstranit</string>
<string name="event_delete_write_denied">Calendula potřebuje oprávnění k zápisu, aby mohla mazat události</string>
<string name="event_delete_write_denied">Calendula potřebuje oprávnění k zápisu, aby mohla odstraňovat události</string>
<string name="event_move_action">Přesunout…</string>
<string name="event_move_recurring_title">Přesunout opakující se událost</string>
<string name="event_move_occurrence_only">Přesunutí celé série by rozhodilo pořadí dnů, na které série připadá, přesunout lze tedy pouze tuto událost.</string>
<string name="event_move_done">Přesunuto do %1$s</string>
<string name="event_move_undo">Zpět</string>
<string name="event_move_undo">Vrátit</string>
<string name="event_move_undone">Vráceno zpět</string>
<string name="event_move_failed">Událost nelze přesunout</string>
<string name="event_move_write_denied">Calendula k přesouvání události vyžaduje oprávnění k zápisu</string>
@@ -111,7 +111,7 @@
<string name="event_edit_color">Barva</string>
<string name="event_edit_color_default">Barva kalendáře</string>
<string name="event_edit_color_custom">Vlastní barva</string>
<string name="event_edit_color_reset">Obnovit</string>
<string name="event_edit_color_reset">Znovu nastavit</string>
<string name="event_edit_color_unsupported">Pro tento kalendář není k dispozici</string>
<string name="event_edit_color_unsupported_hint">Tento kalendář nemá žádnou sadu barev. Vlastní barvy kalendářů můžete povolit v nastavení.</string>
<string name="event_edit_color_sync_warning">Tato barva může být během příští synchronizace kalendáře ztracena nebo přepsána.</string>
@@ -121,8 +121,8 @@
<string name="event_edit_conflict_overwrite_hint">Pouze u upravených polí dojde k přepsání vnějšího zdroje</string>
<string name="event_edit_conflict_discard">Zrušit změny</string>
<string name="event_edit_conflict_discard_hint">Událost zůstává beze změny</string>
<string name="event_edit_gone_title">Událost byla smazána</string>
<string name="event_edit_gone_body">Během úpravy došlo ke smazání události, například pomocí jiného zařízení. Vaše změny již nelze uložit.</string>
<string name="event_edit_gone_title">Událost byla odstraněna</string>
<string name="event_edit_gone_body">Během úpravy došlo k odstranění události, například pomocí jiného zařízení. Vaše změny již nelze uložit.</string>
<string name="import_reminder_prompt_title">Chcete použít výchozí upomínku?</string>
<string name="import_reminder_prompt_body_none">Tato událost byla importována bez nastavené upomínky.</string>
<plurals name="import_reminder_prompt_body_existing">
@@ -250,4 +250,86 @@
<string name="onboarding_backup_benefit_folder_title">Složka, kterou si vyberete</string>
<string name="onboarding_backup_benefit_folder_body">Zálohy jsou obyčejné soubory v .ics formátu — uložte je někam, kde se synchronizují, nebo na SD kartu.</string>
<string name="onboarding_backup_benefit_daily_title">Jednou denně, automaticky</string>
<string name="onboarding_backup_benefit_daily_body">Calendula exportuje vaše místní kalendáře na pozadí. Frekvenci lze změnit v nastavení.</string>
<string name="onboarding_backup_enable_button">Vyberte složku a proveďte zálohu</string>
<string name="onboarding_backup_skip_button">Teď ne</string>
<string name="onboarding_view_title">Co by se mělo otevřít nejdříve?</string>
<string name="onboarding_month_style_title">Jak by mělo vypadat měsíční rozvržení?</string>
<string name="onboarding_view_continue_button">Pokračovat</string>
<string name="onboarding_back">Zpět</string>
<string name="onboarding_visibility_button">Jasně</string>
<string name="onboarding_done_title">Vše je připraveno</string>
<string name="onboarding_done_body">Vaše kalendáře jsou připraveny. Veškeré volby lze později změnit v nastavení.</string>
<string name="onboarding_done_button">Otevřít můj kalendář</string>
<string name="reminder_channel_name">Upomínky událostí</string>
<string name="reminder_channel_description">Oznámení v časech upomínek vašich událostí</string>
<string name="reminder_onboarding_title">Ať vám neunikne žádná událost</string>
<string name="reminder_onboarding_body">Android sám o sobě nezobrazuje upomínky událostí — to musí zajistit aplikace kalendáře. Nechte tuto práci na Calendule.</string>
<string name="reminder_benefit_delivery_title">Upomínky, doručené</string>
<string name="reminder_benefit_delivery_body">Upomínky k vašim událostem vám přijdou v danou dobu jako oznámení.</string>
<string name="reminder_benefit_duplicates_title">Používáte ještě nějakou jinou aplikaci s kalendářem?</string>
<string name="reminder_benefit_duplicates_body">Pokud i jiná aplikace odesílá upomínky, uvidíte je dvakrát — v jedné z aplikací je musíte vypnout.</string>
<string name="reminder_benefit_reversible_title">Lze kdykoliv změnit</string>
<string name="reminder_benefit_reversible_body">Tento přepínač naleznete v Nastavení, v části Oznámení.</string>
<string name="reminder_onboarding_enable_button">Zapnout upomínky</string>
<string name="reminder_onboarding_skip_button">Později</string>
<string name="reminder_action_snooze">Odložit</string>
<string name="reminder_action_dismiss">Zrušit</string>
<string name="reminder_day_tomorrow">Zítra</string>
<string name="reminder_day_yesterday">Včera</string>
<string name="view_month">Měsíc</string>
<string name="view_week">Týden</string>
<string name="view_day">Den</string>
<string name="view_agenda">Program</string>
<string name="view_section">Zobrazení</string>
<string name="drawer_jump_to_date">Přejít na datum</string>
<string name="agenda_today_action">Dnes</string>
<string name="agenda_header_today">Dnes</string>
<string name="agenda_header_tomorrow">Zítra</string>
<string name="agenda_empty_title">Teď už jsi v obraze</string>
<string name="agenda_no_more_today">Dnes bez dalších událostí</string>
<string name="agenda_span_starts">Začátek %1$s</string>
<string name="agenda_span_ends">Konec %1$s</string>
<string name="today_jump_action">Přejít na dnešek</string>
<string name="search_action">Hledat</string>
<string name="search_hint">Vyhledat události</string>
<string name="search_back">Zpět</string>
<string name="search_clear">Vymazat</string>
<string name="search_idle_hint">Prohledávejte své události podle názvu, místa konání nebo poznámek.</string>
<string name="search_empty">Žádná událost neodpovídá “%1$s”.</string>
<plurals name="search_selected_count">
<item quantity="one">%d označený</item>
<item quantity="few">%d označené</item>
<item quantity="many">%d označených</item>
<item quantity="other">%d označených</item>
</plurals>
<string name="search_in_descriptions">Nalezeno v popisech</string>
<string name="search_selection_close">Zrušit výběr</string>
<string name="search_select_all">Vybrat vše</string>
<string name="search_delete_selected">Odstranit vybrané</string>
<plurals name="search_delete_title">
<item quantity="one">Odstranit %d událost?</item>
<item quantity="few">Odstranit %d události?</item>
<item quantity="many">Odstranit %d událostí?</item>
<item quantity="other">Odstranit %d událostí?</item>
</plurals>
<plurals name="search_delete_done">
<item quantity="one">%d událost odstraněna</item>
<item quantity="few">%d události odstraněny</item>
<item quantity="many">%d událostí odstraněno</item>
<item quantity="other">%d událostí odstraněno</item>
</plurals>
<string name="search_delete_partial">%1$d odstraněno, u %2$d se nepodařilo</string>
<string name="search_delete_denied_partial">%1$d odstraněno, poté byl odepřen přístup pro zápis</string>
<string name="settings_special_dates_disable_all_message">Tímto se smažou kalendáře spojené s určitým kontaktem a všechny události v nich obsažené. Veškerá upomínky a poznámky, které jste do nich přidali, budou ztraceny.</string>
<string name="widget_agenda_title">Nadcházející</string>
<string name="widget_agenda_label">Události Calendula</string>
<string name="widget_month_label">Měsíc Calendula</string>
<string name="widget_refresh">Obnovit</string>
<string name="widget_new_event">Nová událost</string>
<string name="widget_needs_permission">Otevřete Calendulu a povolte přístup ke kalendáři</string>
<string name="widget_prev_month">Předchozí měsíc</string>
<string name="widget_next_month">Následující měsíc</string>
<string name="widget_today">Dnes</string>
<string name="filter_title">Kalendáře</string>
</resources>

View File

@@ -16,14 +16,14 @@
<string name="state_failure_no_calendars_action">Otwórz systemowe ustawienia kalendarza</string>
<string name="state_failure_provider">Nie udało się kalendarza.</string>
<string name="permission_rationale_title">Zobacz wszystkie swoje wydarzenia w pięknej oprawie</string>
<string name="permission_rationale_body">Calendula potrzebuje dostępu do Twojego kalendarza, aby wyświetlać wydarzenia i nimi zarządzać. To jedyne, o co prosi na wstępie — i żadne dane nigdy nie opuszczają Twojego urządzenia.</string>
<string name="permission_rationale_body">Calendula potrzebuje dostępu do Twojego kalendarza, aby wyświetlać wydarzenia i nimi zarządzać.</string>
<string name="permission_request_button">Przyznaj dostęp do kalendarza</string>
<string name="permission_denied_title">Brak dostępu do kalendarza</string>
<string name="permission_denied_body">Calendula nie może wyświetlać wydarzeń bez dostępu do kalendarza. Możesz go ponownie przyznać w ustawieniach systemowych.</string>
<string name="permission_open_settings_button">Otwórz ustawienia systemowe</string>
<string name="permission_retry_button">Spróbuj ponownie</string>
<string name="permission_benefit_private_title">Pozostaje na Twoim urządzeniu</string>
<string name="permission_benefit_private_body">Twoje kalendarze są odczytywane lokalnie i nigdy nie opuszcza telefonu.</string>
<string name="permission_benefit_private_title">Prywatność z założenia</string>
<string name="permission_benefit_private_body">Brak uprawnień do internetu, brak telemetrii — nic nigdy nie opuszcza Twojego telefonu.</string>
<string name="permission_benefit_sync_title">Wszystkie Twoje kalendarze w jednym miejscu</string>
<string name="permission_benefit_sync_body">Google, CalDAV, lokalne — wszystko, co jest zsynchronizowane z urządzeniem, po prostu się pojawia.</string>
<string name="permission_benefit_privacy_title">Nigdy żadnego śledzenia</string>
@@ -333,7 +333,7 @@
<string name="settings_default_reminder">Domyślne przypomnienie</string>
<string name="settings_default_reminder_allday">Wydarzenia całodniowe</string>
<string name="settings_allday_reminder_time">Godzina przypomnienia o wydarzeniach całodniowych</string>
<string name="settings_allday_reminder_time_hint">Przypomnienia o wydarzeniach całodniowych zostaną pojawiają się o %1$s</string>
<string name="settings_allday_reminder_time_hint">Przypomnienia o wydarzeniach całodniowych pojawiają się o %1$s</string>
<string name="reminder_none">Brak</string>
<string name="reminder_use_default">Użyj domyślnego przypomnienia</string>
<string name="reminder_custom_amount">jednostek</string>
@@ -353,10 +353,10 @@
<string name="settings_language_auto">Domyślny systemu</string>
<string name="settings_translate">Pomóż w tłumaczeniu</string>
<string name="settings_translate_hint">Dodaj lub ulepsz tłumaczenie w Weblate</string>
<string name="settings_appearance_subtitle">Motyw, domyślny widok, pierwszy dzień tygodnia</string>
<string name="settings_views_subtitle">Układ widoku miesiąca, przycisk szybkiego przełączania, kolejność menu</string>
<string name="settings_event_form_subtitle">Domyślne pola dla nowych wydarzeń</string>
<string name="settings_notifications_subtitle">Przypomnienia o wydarzeniach</string>
<string name="settings_appearance_subtitle">Motyw, kolory, czcionki</string>
<string name="settings_views_subtitle">Domyślny widok, układ, kolejność</string>
<string name="settings_event_form_subtitle">Domyślne pola i zachowanie</string>
<string name="settings_notifications_subtitle">Przypomnienia i dostarczanie</string>
<string name="settings_special_dates_subtitle">Urodziny i rocznice kontaktów</string>
<string name="settings_section_special_dates">Szczególne daty kontaktów</string>
<string name="settings_special_dates_enable">Pokaż daty kontaktów</string>
@@ -509,8 +509,8 @@
<string name="reminder_day_tomorrow">Jutro</string>
<string name="reminder_day_yesterday">Wczoraj</string>
<string name="agenda_no_more_today">Brak zaplanowanych wydarzeń</string>
<string name="settings_soften_colors">Zredukuj intensywność kolorów kalendarza</string>
<string name="settings_soften_colors_summary">Dopasuj intensywność kolorów kalendarza i wydarzeń do motywu. Wyłącz tę opcję, aby wyświetlać oryginalne kolory ze źródła kalendarza.</string>
<string name="settings_soften_colors">Harmonizuj kolory kalendarza</string>
<string name="settings_soften_colors_summary">Zachowaj odcień każdego kalendarza, ale wyrównaj jego jasność, tak aby każde wydarzenie pozostało czytelne, a kolory współgrały ze sobą. Wyłącz tę opcję, aby wyświetlać oryginalne kolory ze źródła kalendarza.</string>
<string name="settings_agenda_show_today">Zawsze pokazuj dzisiejszy dzień</string>
<string name="settings_agenda_show_today_hint">Zachowaj dzisiejszy dzień na górze agendy i widżetu, nawet gdy nie ma już na dziś żadnych zadań.</string>
<string name="special_dates_calendar_birthday">Urodziny</string>
@@ -543,4 +543,128 @@
<string name="month_split_no_events">Brak planów</string>
<string name="month_split_expand">Pokaż cały miesiąc</string>
<string name="month_split_collapse">Pokaż wydarzenia dnia</string>
<string name="event_move_gone">To wydarzenie już nie istnieje</string>
<string name="event_move_action">Przenieś…</string>
<string name="event_move_recurring_title">Przenieś wydarzenie cykliczne</string>
<string name="event_move_occurrence_only">Przeniesienie całej serii zmieniłoby dni, w których wypadają wydarzenia, więc można przenieść tylko to wystąpienie.</string>
<string name="event_move_done">Przeniesiono na %1$s</string>
<string name="event_move_undo">Cofnij</string>
<string name="event_move_undone">Cofnięto przeniesienie</string>
<string name="event_move_failed">Nie udało się przenieść wydarzenia</string>
<string name="event_move_write_denied">Calendula wymaga uprawnień do zapisu, aby móc przenosić wydarzenia</string>
<string name="event_move_blocked_series_end">Nie można przenieść wydarzenia poza datę zakończenia jego serii</string>
<string name="event_edit_recurrence_next">Następne: %1$s</string>
<string name="event_edit_recurrence_next_none">Ta reguła nie ma powtórzeń</string>
<string name="event_access_default_summary">Standardowe ustawienie tego kalendarza</string>
<string name="event_access_public_summary">Każdy, kto ma dostęp, widzi pełne szczegóły</string>
<string name="event_access_private_summary">Inni widzą tylko to, że jesteś zajęty</string>
<string name="event_access_confidential_summary">Oznaczone jako poufne; co to oznacza, zależy od konta kalendarza</string>
<string name="duration_hours_minutes">%1$s %2$s</string>
<string name="duration_custom_max">Maksymalnie %1$s</string>
<string name="onboarding_step_counter">Krok %1$d z %2$d</string>
<string name="onboarding_backup_title">Twoje wydarzenia istnieją tylko tutaj</string>
<string name="onboarding_backup_body">Nic z tego telefonu nie synchronizuje się z kontem, więc jego utrata oznaczałaby utratę kalendarza. Calendula może utworzyć dla Ciebie kopię zapasową.</string>
<string name="onboarding_backup_benefit_folder_title">Wybrany przez Ciebie folder</string>
<string name="onboarding_backup_benefit_folder_body">Kopie zapasowe to zwykłe pliki .ics — umieść je w miejscu, które się synchronizuje, albo na karcie SD.</string>
<string name="onboarding_backup_benefit_daily_title">Raz dziennie, automatycznie</string>
<string name="onboarding_backup_benefit_daily_body">Calendula eksportuje Twoje lokalne kalendarze w tle. Możesz zmienić częstotliwość w Ustawieniach.</string>
<string name="onboarding_backup_enable_button">Wybierz folder i utwórz kopię zapasową</string>
<string name="onboarding_view_title">Co powinno się otworzyć jako pierwsze?</string>
<string name="onboarding_month_style_title">Jak powinien wyglądać miesiąc?</string>
<string name="onboarding_view_continue_button">Kontynuuj</string>
<string name="onboarding_back">Wstecz</string>
<string name="onboarding_visibility_button">Rozumiem</string>
<string name="onboarding_done_title">Wszystko gotowe</string>
<string name="onboarding_done_body">Twoje kalendarze są gotowe. Wszystko co właśnie wybrałeś możesz później zmienić w Ustawieniach.</string>
<string name="onboarding_done_button">Otwórz mój kalendarz</string>
<plurals name="search_selected_count">
<item quantity="one">%d wybrane</item>
<item quantity="few">%d wybrane</item>
<item quantity="many">%d wybranych</item>
<item quantity="other">%d wybranych</item>
</plurals>
<string name="search_in_descriptions">Znaleziono w opisach</string>
<string name="search_selection_close">Anuluj wybór</string>
<string name="search_select_all">Wybierz wszystkie</string>
<string name="search_delete_selected">Usuń wybrane</string>
<plurals name="search_delete_title">
<item quantity="one">Usunąć %d wydarzenie?</item>
<item quantity="few">Usunąć %d wydarzenia?</item>
<item quantity="many">Usunąć %d wydarzeń?</item>
<item quantity="other">Usunąć %d wydarzeń?</item>
</plurals>
<plurals name="search_delete_done">
<item quantity="one">Usunięto %d wydarzenie</item>
<item quantity="few">Usunięto %d wydarzenia</item>
<item quantity="many">Usunięto %d wydarzeń</item>
<item quantity="other">Usunięto %d wydarzeń</item>
</plurals>
<string name="search_delete_partial">%1$d usunięto, %2$d nie udało się</string>
<string name="search_delete_denied_partial">%1$d usunięto, następnie utracono uprawnienia do zapisu</string>
<string name="settings_theme_hint">Czy aplikacja ma być jasna, czy ciemna. Wybór zostanie zastosowany natychmiast.</string>
<string name="settings_theme_system_summary">Obecnie %1$s</string>
<string name="settings_font_specimen_heading">czwartek, 14 maja</string>
<string name="settings_font_specimen_body">Przegląd zespołu o 10:00, a potem lunch z Robinem w kawiarni na rynku.</string>
<string name="settings_week_start_auto_summary">Obecnie %1$s</string>
<string name="settings_time_format_auto_summary">Zgodnie z systemem: %1$s</string>
<string name="settings_timeline_scale">Wysokość godzin</string>
<string name="settings_timeline_scale_hint">Ile miejsca w pionie zajmuje jedna godzina w widoku tygodnia i dnia. Oba widoki korzystają z tego ustawienia. Możesz również rozciągnąć lub ścisnąć oś czasu dwoma palcami, aby ustawić dowolną wysokość pomiędzy.</string>
<string name="timeline_scale_fit_day">Cały dzień na ekranie</string>
<string name="timeline_scale_fit_day_summary">Cała doba na jednym ekranie, bez przewijania</string>
<string name="timeline_scale_compact">Kompaktowa</string>
<string name="timeline_scale_compact_summary">Więcej godzin na ekranie, mniejsze bloki</string>
<string name="timeline_scale_regular">Standardowa</string>
<string name="timeline_scale_regular_summary">Standardowy rozmiar</string>
<string name="timeline_scale_comfortable">Wygodna</string>
<string name="timeline_scale_comfortable_summary">Większe bloki, więcej przewijania</string>
<string name="timeline_scale_custom">Własna</string>
<string name="timeline_scale_custom_summary">Wysokość, którą wybrałeś gestem „uszczypnięcia” osi czasu</string>
<string name="settings_drag_to_reschedule">Przeciągnij, aby zmienić termin</string>
<string name="settings_drag_to_reschedule_summary">Przenieś wydarzenie, przeciągając je na inny dzień lub godzinę</string>
<string name="settings_past_events_sample_morning">Przegląd zespołu</string>
<string name="settings_past_events_sample_midday">Lunch z Robin</string>
<string name="settings_past_events_sample_evening">Próba chóru</string>
<string name="settings_widget_size">Rozmiar widżetu agendy</string>
<string name="settings_widget_size_hint">Rozmiar tekstu wyświetlanego przez widżet agendy na ekranie domowym. Widżet miesiąca nie posiada tego ustawienia — jego siatka zawsze dopasowuje się do przydzielonego miejsca.</string>
<string name="settings_widget_size_small">Mały</string>
<string name="settings_widget_size_medium">Średni</string>
<string name="settings_widget_size_large">Duży</string>
<string name="settings_widget_size_extra_large">Bardzo duży</string>
<string name="settings_widget_size_summary">Tekst wydarzenia %1$d%%</string>
<string name="settings_event_duration">Domyślny czas trwania</string>
<string name="settings_event_duration_hint">Czas trwania nowego wydarzenia do momentu zmiany godziny jego zakończenia. Nie dotyczy to wydarzeń całodniowych.</string>
<string name="settings_calendar_durations_title">Czas trwania dla poszczególnych kalendarzy</string>
<string name="settings_calendar_durations_hint">Przypisz kalendarzowi własną domyślną długość — np. 8 godzin dla zmian w pracy.</string>
<string name="settings_calendar_duration_inherits">Domyślny (%1$s)</string>
<string name="settings_calendar_duration_use_default">Używaj domyślnego czasu trwania (%1$s)</string>
<string name="settings_allday_reminder_fires_at">Powiadamia o %1$s</string>
<string name="settings_group_look">Wygląd i zachowanie</string>
<string name="settings_group_data">Dane</string>
<string name="settings_group_app">Aplikacja</string>
<string name="settings_group_about">O aplikacji</string>
<string name="settings_widgets_subtitle">Widżet agendy, kafelek Szybkich ustawień</string>
<string name="settings_backup_subtitle">Eksport, import, automatyczna kopia zapasowa</string>
<string name="settings_section_widgets">Widżety i kafelki</string>
<string name="settings_widgets_hint">Ustawienia widżetów ekranu głównego i kafelka Szybkich ustawień. Aby dodać widżet, naciśnij i przytrzymaj na ekranie domowym.</string>
<string name="settings_section_backup">Kopia zapasowa i przywracanie</string>
<string name="settings_views_all_header">Wszystkie widoki</string>
<string name="settings_week_day_header">Tydzień i dzień</string>
<string name="settings_default_view_hint">Widok, który pojawia się po uruchomieniu aplikacji Calendula.</string>
<string name="settings_week_start_hint">Dzień, od którego zaczyna się każdy tydzień we wszystkich widokach i widżetach.</string>
<string name="settings_time_format_hint">Format godziny w aplikacji. Opcja automatyczna dostosowuje się do ustawień systemowych.</string>
<string name="settings_past_events_hint">Co agenda robi z wydarzeniami, które już się zakończyły.</string>
<string name="settings_dynamic_color_summary">Dopasuj kolory aplikacji do swojej tapety.</string>
<string name="settings_about_privacy">Polityka prywatności</string>
<string name="calendars_visibility_hint">Wyłącz kalendarz, aby ukryć go na tym urządzeniu — jego wydarzenia znikną z aplikacji i przestaniesz otrzymywać powiadomienia. To ten sam przełącznik, którego używają inne aplikacje kalendarza, więc one również go ukryją. Nic nie zostanie usunięte, nie wpłynie to na inne urządzenia, a kalendarz możesz tu włączyć ponownie w dowolnym momencie.</string>
<string name="calendars_visibility_a11y">Pokaż \"%1$s\"</string>
<string name="calendars_visibility_notice_title">Niektóre kalendarze są wyłączone</string>
<string name="calendars_visibility_notice_message">Calendula wyświetla kalendarze włączone na tym urządzeniu, a niektóre z Twoich są wyłączone. Aby zobaczyć ich wydarzenia, włącz je w sekcji Ustawienia → Kalendarze.</string>
<string name="calendar_picker_missing_title">Brakuje jakiegoś kalendarza?</string>
<string name="calendar_picker_missing_summary">Może być wyłączony, tylko do odczytu lub wypełniony na podstawie Twoich kontaktów — zarządzaj swoimi kalendarzami tutaj.</string>
<string name="calendars_state_read_only">Tylko do odczytu</string>
<string name="calendars_state_not_synced">Niezsynchronizowany z tym urządzeniem</string>
<string name="calendars_state_managed">Wypełniony na podstawie Twoich kontaktów</string>
<string name="calendars_managed_delete_locked">Ten kalendarz jest uzupełniany na podstawie Twoich kontaktów, więc Calendula utworzy go ponownie przy następnej synchronizacji. Aby go usunąć, wyłącz daty szczególne w menu Ustawienia → Szczególne daty kontaktów.</string>
<string name="calendars_account_from_source">%1$s (%2$s)</string>
<string name="onboarding_backup_skip_button">Nie teraz</string>
</resources>

View File

@@ -133,4 +133,47 @@
<string name="import_reminder_prompt_apply">Применить стандартное</string>
<string name="import_reminder_prompt_keep">Оставить как есть</string>
<string name="event_edit_recurrence_none">Не повторяется</string>
<string name="event_edit_recurrence_custom">Свой</string>
<string name="event_edit_recurrence_every">Каждый</string>
<string name="recurrence_unit_days">дни</string>
<string name="recurrence_unit_weeks">недели</string>
<string name="recurrence_unit_months">месяцы</string>
<string name="recurrence_unit_years">года</string>
<string name="event_edit_recurrence_incomplete">Введите число от 1 до 999</string>
<string name="event_edit_recurrence_next_none">Это правило никогда не повторяется</string>
<string name="event_edit_recurrence_ends">Заканчивается</string>
<string name="event_edit_recurrence_end_never">Никогда</string>
<string name="event_edit_recurrence_end_until">До</string>
<string name="event_edit_recurrence_end_count">После определённого количества</string>
<string name="event_availability_busy">Занят</string>
<string name="event_access_default">Стандартный</string>
<string name="event_access_public">Публичный</string>
<string name="event_detail_all_day">Весь день</string>
<string name="event_detail_calendar">Календарь</string>
<string name="event_detail_calendar_unknown">Неизвестный календарь</string>
<string name="event_detail_location">Местоположение</string>
<string name="event_detail_description">Описание</string>
<string name="event_detail_recurring">Повторяющееся событие</string>
<string name="recurrence_daily">Каждый день</string>
<string name="recurrence_weekly">Каждую неделю</string>
<string name="recurrence_monthly">Каждый месяц</string>
<string name="recurrence_yearly">Каждый год</string>
<string name="recurrence_every_n_days">Каждые %1$d дней</string>
<string name="recurrence_every_n_weeks">Каждые %1$d недель</string>
<string name="recurrence_every_n_months">Каждые %1$d месяцев</string>
<string name="recurrence_every_n_years">Каждые %1$d лет</string>
<string name="event_detail_not_found">Это событие больше не существует.</string>
<string name="event_attendee_accepted">Принято</string>
<string name="event_attendee_declined">Отклонено</string>
<string name="event_attendee_needs_action">Без ответа</string>
<string name="event_detail_reminders">Напоминания</string>
<string name="event_detail_timezone">Временная зона</string>
<string name="event_status_cancelled">Отменён</string>
<string name="event_availability_free">Бесплатно</string>
<string name="event_access_private">Приватно</string>
<string name="event_access_confidential">Конфиденциально</string>
<string name="event_access_public_summary">Любой с доступом может видеть все детали</string>
<string name="event_access_private_summary">Другие видят только, что вы заняты</string>
<string name="event_detail_self_response">Ваш ответ: %1$s</string>
<string name="reminder_at_time">Во время начала события</string>
</resources>

View File

@@ -0,0 +1,190 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="backup_interval_units">
<item>Minutes</item>
<item>Hours</item>
<item>Days</item>
<item>Weeks</item>
</string-array>
<string name="app_name">Calendula</string>
<string name="app_tagline">Moderný kalendár.</string>
<string name="state_loading">Načítava sa…</string>
<string name="state_retry">Opakovať</string>
<string name="state_failure_unknown">Niečo sa pokazilo.</string>
<string name="state_failure_permission">Je potrebný prístup ku kalendáru.</string>
<string name="state_failure_permission_action">Udeliť prístup</string>
<string name="state_failure_no_calendars">Nie sú nakonfigurované žiadne kalendáre.</string>
<string name="state_failure_no_calendars_action">Otvoriť systémové nastavenie kalendára</string>
<string name="state_failure_provider">Nepodarilo sa načítať kalendár.</string>
<string name="permission_rationale_title">Prehľadávajte všetky svoje udalosti v krásnom prevedení</string>
<string name="permission_rationale_body">Calendula potrebuje prístup k vášmu kalendáru, aby mohla zobraziť a spravovať vaše udalosti.</string>
<string name="permission_request_button">Udeliť prístup k kalendáru</string>
<string name="permission_denied_title">Prístup ku kalendáru bol zamietnutý</string>
<string name="permission_denied_body">Calendula nemôže zobraziť udalosti bez prístupu ku kalendáru. Môžete ho znova udeliť v nastavení systému.</string>
<string name="permission_open_settings_button">Otvoriť systémové nastavenia</string>
<string name="permission_retry_button">Skúsiť znova</string>
<string name="permission_benefit_private_title">Súkromné už od začiatku</string>
<string name="permission_benefit_private_body">Žiadny prístup k internetu, žiadna telemetria - nikdy nič z vášho telefónu neunikne.</string>
<string name="permission_benefit_sync_title">Všetky vaše kalendáre pohromade</string>
<string name="permission_benefit_sync_body">Google, CalDAV, lokálne kalendáre - čokoľvek synchronizované zo zariadením sa proste objaví.</string>
<string name="permission_benefit_privacy_title">Nikdy žiadne sledovanie</string>
<string name="permission_benefit_privacy_body">Žiadna telemetria, žiadne analytické nástroje, bez reklám.</string>
<string name="permission_privacy_footnote">Ostáva na vašom zariadení · bez prístupu k internetu</string>
<string name="month_prev">Predchádzajúci mesiac</string>
<string name="month_next">Nasledujúci mesiac</string>
<string name="month_today_action">Dnes</string>
<string name="month_more_actions">Ďalšie možnosti</string>
<string name="month_open_menu">Otvoriť menu</string>
<string name="month_action_settings">Nastavenia</string>
<string name="month_a11y_today_prefix">Dnes</string>
<string name="week_today_action">Tento víkend</string>
<string name="week_number_label">týžd.</string>
<string name="day_today_action">Dnes</string>
<string name="event_detail_back">Späť</string>
<string name="event_detail_edit">Upraviť</string>
<string name="event_detail_delete">Vymazať</string>
<string name="event_detail_share">Zdielať</string>
<string name="event_detail_duplicate">Duplikovať</string>
<string name="event_share_chooser_title">Zdielať udalosť</string>
<string name="event_share_failed">Túto udalosť nieje možné zdieľať.</string>
<string name="event_delete_title">Odstrániť udalosť?</string>
<string name="event_delete_body">Udalosť je odstránená z vášho kalendára aj zo všetkých synchronizovaných zariadení.</string>
<string name="event_delete_recurring_title">Odstrániť opakujúcu sa udalosť</string>
<string name="event_delete_option_occurrence">Iba túto udalosť</string>
<string name="event_delete_option_following">Túto aj všetky nasledujúce udalosti</string>
<string name="event_delete_option_series">Všetky udalosti v sérii</string>
<string name="event_edit_recurring_title">Upraviť opakujúcu sa udalosť</string>
<string name="event_delete_failed">Túto udalosť nebolo možné odstrániť</string>
<string name="event_delete_write_denied">Calendula potrebuje povolenie k zápisu, aby mohla odstrániť udalosti</string>
<string name="event_move_action">Presunúť…</string>
<string name="event_move_recurring_title">Presunúť opakujúcu sa udalosť</string>
<string name="event_move_occurrence_only">Presunútie celej série by sa zmenilo poradie dňou, na ktorú séria pripadá, takže presunúť je možné iba túto udalosť.</string>
<string name="event_move_done">Presunuté na %1$s</string>
<string name="event_move_undo">Vrátiť späť</string>
<string name="event_move_undone">Navrátené naspäť</string>
<string name="event_move_failed">Nemožno presunúť udalosť</string>
<string name="event_move_write_denied">Calendula potrebuje povolenie k zápisu, aby mohla presúvať udalosti</string>
<string name="event_move_gone">Táto udalosť už neexistuje</string>
<string name="event_move_blocked_series_end">Nie je možné presunúť udalosť za koniec danej série</string>
<string name="dialog_cancel">Zrušiť</string>
<string name="dialog_ok">OK</string>
<string name="event_edit_new_title">Nová udalosť</string>
<string name="event_edit_close">Zavrieť</string>
<string name="event_edit_save">Uložiť</string>
<string name="event_edit_title_hint">Pridať názov</string>
<string name="event_edit_managed_hint">Spravové kalendárom “%1$s” — názov, dátum a opakovanie je synchronizované z vašich kontaktov. Pripomienky, poloha a poznámky môžte upraviť.</string>
<string name="event_edit_starts">Začiatok</string>
<string name="event_edit_ends">Koniec</string>
<string name="event_edit_error_end_before_start">Končí pred začiatkom</string>
<string name="event_edit_error_no_calendar">Není dostupný kalendár, ktorý je možno upravovať</string>
<string name="event_edit_save_failed">Nemožno udalosť uložiť</string>
<string name="event_edit_write_denied">Calendula potrebuje povolenie k zápisu, aby mohla vytvárať udalosti</string>
<string name="event_edit_more_fields">Viac poli</string>
<string name="event_edit_add">Pridať</string>
<string name="event_edit_add_reminder">Pridať pripomienku</string>
<string name="event_edit_remove_reminder">Odstrániť pripomienku</string>
<string name="event_edit_attendees">Hostia</string>
<string name="event_edit_add_guest">Pridať hosťa</string>
<string name="event_edit_add_guest_hint">Pridať hosťa e-mailom…</string>
<string name="event_edit_add_guest_from_contacts">Pridať z kontaktov</string>
<string name="event_edit_location_from_contacts">Vybrať adresu z kontaktov</string>
<string name="event_edit_remove_guest">Odstrániť hosťa</string>
<string name="event_edit_attendee_required">Nutné</string>
<string name="event_edit_attendee_optional">Voliteľné</string>
<string name="event_edit_attendees_note_synced">Calendula neposiela pozvánky. Váš kalendárny účet ich môže poslať keď sa synchronizuje.</string>
<string name="event_edit_attendees_note_local">Uložené na tomto zariadení. Nikomu nebude poslaná notifikácia.</string>
<string name="event_edit_reminder_custom">Vlastné</string>
<string name="reminder_unit_minutes">minúty</string>
<string name="reminder_unit_hours">hodiny</string>
<string name="reminder_unit_days">dni</string>
<string name="reminder_unit_weeks">týždne</string>
<string name="event_edit_availability">Dostupnosť</string>
<string name="event_edit_visibility">Viditeľnosť</string>
<string name="event_edit_timezone_device">Časové pásmo zariadenia</string>
<string name="event_edit_timezone_device_summary">Sleduje vás, nech ste kdekoľvek</string>
<string name="event_edit_timezone_search">Vyhľadať časové pásmo</string>
<string name="event_edit_timezone_recent">Nedávne</string>
<string name="event_edit_timezone_all">Všetky časové pásma</string>
<string name="event_edit_timezone_none">Žiadne časové pásmo nezodpovedá “%1$s”</string>
<string name="event_edit_timezone_local_time">%1$s vášho času</string>
<string name="event_edit_color">Farba</string>
<string name="event_edit_color_default">Farba kalendáru</string>
<string name="event_edit_color_custom">Vlastná farba</string>
<string name="event_edit_color_reset">Obnoviť</string>
<string name="event_edit_color_unsupported">Není k dispozícii pre tento kalendár</string>
<string name="event_edit_color_unsupported_hint">Tento kalendár nemá vlastnú sadu farieb. Pre takýto kalendár môžte povoliť vlastné farby v nastaveniach.</string>
<string name="event_edit_color_sync_warning">Tento kalendár môže vymazať alebo prepísať farbu pri ďalšej synchronizácii.</string>
<string name="event_edit_conflict_title">Udalosť bola zmenená niekde inde</string>
<string name="event_edit_conflict_body">Počas úprav sa táto udalosť zmenila — synchronizáciou alebo inou aplikáciou. Čo sa má stať s vašimi zmenami?</string>
<string name="event_edit_conflict_overwrite">Uložiť zmeny</string>
<string name="event_edit_conflict_overwrite_hint">Iba u upravených polí sa prepíše zmena z iného zdroja</string>
<string name="event_edit_conflict_discard">Zrušiť zmeny</string>
<string name="event_edit_conflict_discard_hint">Udalosť ostáva bez zmeny</string>
<string name="event_edit_gone_title">Udalosť odstránená</string>
<string name="event_edit_gone_body">Počas úprav bola táto udalosť odstránená, napríklad na inom zariadení. Vaše zmeny už nie je možné uložiť.</string>
<string name="import_reminder_prompt_title">Chcete použiť predvolenú pripomienku?</string>
<string name="import_reminder_prompt_body_none">Táto udalosť bola importovaná bez pripomienky.</string>
<plurals name="import_reminder_prompt_body_existing">
<item quantity="one">Táto udalosť bola importovaná s %1$d pripomienkou.</item>
<item quantity="few">Táto udalosť bola importovaná s %1$d pripomienkami.</item>
<item quantity="many">Táto udalosť bola importovaná s %1$d pripomienkami.</item>
<item quantity="other">Táto udalosť bola importovaná s %1$d pripomienkami.</item>
</plurals>
<string name="import_reminder_prompt_apply">Nastaviť predvolené</string>
<string name="import_reminder_prompt_keep">Nechať bez zmeny</string>
<string name="event_edit_recurrence_none">Neopakuje sa</string>
<string name="event_edit_recurrence_custom">Vlastné</string>
<string name="event_edit_recurrence_every">Každý</string>
<string name="recurrence_unit_days">dni</string>
<string name="recurrence_unit_weeks">týždne</string>
<string name="recurrence_unit_months">mesiace</string>
<string name="recurrence_unit_years">roky</string>
<string name="event_edit_recurrence_incomplete">Zadajte číslo od 1 do 999</string>
<string name="event_edit_recurrence_next">Nasledujúce: %1$s</string>
<string name="event_edit_recurrence_next_none">Toto pravidlo sa nikdy neopakuje</string>
<string name="event_edit_recurrence_ends">Koniec</string>
<string name="event_edit_recurrence_end_never">Nikdy</string>
<string name="event_edit_recurrence_end_until">K určitému dátumu</string>
<string name="event_edit_recurrence_end_count">Po určitom počtu opakovaní</string>
<string name="event_edit_recurrence_times">opakovaní</string>
<string name="event_edit_error_recurrence_ends_before_start">Opakovanie končí pred začiatkom udalosti</string>
<string name="event_availability_busy">Zaneprázdnený</string>
<string name="event_access_default">Predvolený</string>
<string name="event_access_public">Verejný</string>
<string name="event_detail_all_day">Celý deň</string>
<string name="event_detail_calendar">Kalendár</string>
<string name="event_detail_calendar_unknown">Neznámy kalendár</string>
<string name="event_detail_location">Poloha</string>
<string name="event_detail_description">Popis</string>
<string name="event_detail_attendees">Účastníci</string>
<string name="event_detail_recurrence">Opakovanie</string>
<string name="event_detail_recurring">Opakovaná udalosť</string>
<string name="recurrence_daily">Každý deň</string>
<string name="recurrence_weekly">Každý týždeň</string>
<string name="recurrence_monthly">Každý mesiac</string>
<string name="recurrence_yearly">Každý rok</string>
<string name="recurrence_every_n_days">Každý %1$d. deň</string>
<string name="recurrence_every_n_weeks">Každý %1$d. týždeň</string>
<string name="recurrence_every_n_months">Každý %1$d. mesiac</string>
<string name="recurrence_every_n_years">Každý %1$d. rok</string>
<string name="recurrence_on_days">%1$s v %2$s</string>
<string name="recurrence_with_until">%1$s do%2$s</string>
<string name="recurrence_with_count">%1$s, %2$d opakovaní</string>
<string name="event_detail_not_found">Táto udalosť už neexistuje.</string>
<string name="event_attendee_accepted">Akceptované</string>
<string name="event_attendee_declined">Zamietnuté</string>
<string name="event_attendee_tentative">Predbežne</string>
<string name="event_attendee_needs_action">Bez odozvy</string>
<string name="event_attendee_unknown"></string>
<string name="event_detail_reminders">Pripomienky</string>
<string name="event_detail_timezone">Časové pásmo</string>
<string name="event_status_tentative">Predbežne</string>
<string name="event_status_cancelled">Zrušené</string>
<string name="event_availability_free">Voľno</string>
<string name="event_access_private">Súkromné</string>
<string name="event_access_confidential">Tajné</string>
<string name="event_access_default_summary">Bežná činnosť kalendáru</string>
<string name="event_access_public_summary">Kdekoľvek s prístupom vidí všetky detaily</string>
<string name="event_access_private_summary">Ostatný vidia iba že ste zaneprázdnený</string>
<string name="event_access_confidential_summary">Označené ako utajené; záleží na kalendárnom účtu čo toto znamená</string>
</resources>

View File

@@ -6,34 +6,33 @@
<item>Days</item>
<item>Weeks</item>
</string-array>
<string name="app_name">Calendula</string>
<string name="app_tagline">一个现代化的日历应用</string>
<string name="app_tagline">现代化的日历应用</string>
<string name="state_loading">加载中…</string>
<string name="state_retry">推迟</string>
<string name="state_failure_unknown">错误!</string>
<string name="state_failure_permission">需要日历权限</string>
<string name="state_retry">重试</string>
<string name="state_failure_unknown">出错了。</string>
<string name="state_failure_permission">需要日历访问权限</string>
<string name="state_failure_permission_action">授予访问权限</string>
<string name="state_failure_no_calendars">无已设置的日历</string>
<string name="state_failure_no_calendars">未配置任何日历</string>
<string name="state_failure_no_calendars_action">打开系统日历设置</string>
<string name="state_failure_provider">无法读取日历</string>
<string name="permission_rationale_title">优雅地查看你的所有活动</string>
<string name="permission_rationale_body">Calendula需要获取权限来访问您的日历展示和管理您的活动。所有权限均会在使用前申请——不必担心隐私泄露</string>
<string name="permission_request_button">授予日历权限</string>
<string name="permission_denied_title">日历权限不可用</string>
<string name="permission_denied_body">Calendula 无法显示没有日历访问权限的事件。可以在系统设置里再次授予它</string>
<string name="state_failure_provider">无法读取日历</string>
<string name="permission_rationale_title">优雅地查看您所有的事件</string>
<string name="permission_rationale_body">Calendula 需要访问您的日历,以展示和管理您的事件</string>
<string name="permission_request_button">授予日历访问权限</string>
<string name="permission_denied_title">日历访问被拒绝</string>
<string name="permission_denied_body">Calendula 无法没有日历访问权限的情况下显示事件。可以在系统设置中重新授予权限</string>
<string name="permission_open_settings_button">打开系统设置</string>
<string name="permission_retry_button">重试</string>
<string name="permission_benefit_private_title">保留在设备</string>
<string name="permission_benefit_private_body">您的日历数据将会在本地读取,而不会被上传</string>
<string name="permission_benefit_sync_title">所有日历</string>
<string name="permission_benefit_sync_body">Google、CalDAV、本地设备——任何同步到设备的东西都会直接显示出来</string>
<string name="permission_benefit_privacy_title">无追踪</string>
<string name="permission_benefit_privacy_body">零遥测零分析,没有广告。</string>
<string name="permission_privacy_footnote">数据保留在本地设备 ·无网络权限</string>
<string name="month_prev"></string>
<string name="month_next"></string>
<string name="permission_benefit_private_title">从设计上保护隐私</string>
<string name="permission_benefit_private_body">没有网络权限,没有遥测——任何数据都不会离开您的手机</string>
<string name="permission_benefit_sync_title">所有日历汇聚一处</string>
<string name="permission_benefit_sync_body">Google、CalDAV、本地日历——只要同步到设备就会自动显示</string>
<string name="permission_benefit_privacy_title">无追踪</string>
<string name="permission_benefit_privacy_body">零遥测零分析、无广告。</string>
<string name="permission_privacy_footnote">数据保留在您的设备 · 无网络权限</string>
<string name="month_prev">上月</string>
<string name="month_next">下月</string>
<string name="month_today_action">今天</string>
<string name="month_more_actions">更多选项</string>
<string name="month_more_actions">更多操作</string>
<string name="month_open_menu">打开菜单</string>
<string name="month_action_settings">设置</string>
<string name="month_a11y_today_prefix">今天</string>
@@ -43,80 +42,572 @@
<string name="event_detail_edit">编辑</string>
<string name="event_detail_delete">删除</string>
<string name="event_detail_share">分享</string>
<string name="event_share_chooser_title">分享活动</string>
<string name="event_share_failed">无法分享该活动</string>
<string name="event_delete_title">删除活动</string>
<string name="event_delete_body">活动将从的日历以及所有同步设备中移除。</string>
<string name="event_delete_recurring_title">删除重复活动</string>
<string name="event_delete_option_occurrence">该活动</string>
<string name="event_delete_option_following">当前及接下来的所有活动</string>
<string name="event_delete_option_series">系列的所有活动</string>
<string name="event_edit_recurring_title">编辑重复活动</string>
<string name="event_delete_failed">无法删除该活动</string>
<string name="event_delete_write_denied">Calendula需要权限读取或删除活动</string>
<string name="event_share_chooser_title">分享事件</string>
<string name="event_share_failed">无法分享此事件</string>
<string name="event_delete_title">删除事件</string>
<string name="event_delete_body">事件将从的日历以及所有同步设备中移除。</string>
<string name="event_delete_recurring_title">删除重复事件</string>
<string name="event_delete_option_occurrence">此事件</string>
<string name="event_delete_option_following">此事件及其后的所有事件</string>
<string name="event_delete_option_series">整个系列的所有事件</string>
<string name="event_edit_recurring_title">编辑重复事件</string>
<string name="event_delete_failed">无法删除事件</string>
<string name="event_delete_write_denied">Calendula 需要写入权限才能删除事件</string>
<string name="dialog_cancel">取消</string>
<string name="dialog_ok"></string>
<string name="event_edit_new_title">活动</string>
<string name="dialog_ok"></string>
<string name="event_edit_new_title">事件</string>
<string name="event_edit_close">关闭</string>
<string name="event_edit_save">保存</string>
<string name="event_edit_title_hint">加标题</string>
<string name="event_edit_managed_hint">由“%1$s”管理——标题、日期和重复内容会与你的联系人保持同步。提醒、位置和笔记由你自行编辑。</string>
<string name="event_edit_title_hint">加标题</string>
<string name="event_edit_managed_hint">由“%1$s”管理——标题、日期和重复会从您的联系人同步。提醒、位置和备注由您编辑。</string>
<string name="event_edit_starts">开始</string>
<string name="event_edit_ends">结束</string>
<string name="event_edit_error_end_before_start">报错:结束时间早于始时间</string>
<string name="event_edit_error_no_calendar">可写入的日历</string>
<string name="event_edit_save_failed">无法保存该活动</string>
<string name="event_edit_write_denied">Calendula需要写入权限来创建活动</string>
<string name="event_edit_more_fields">其他领域</string>
<string name="event_edit_add">新增</string>
<string name="event_edit_add_reminder">新建提醒</string>
<string name="event_edit_error_end_before_start">结束时间早于始时间</string>
<string name="event_edit_error_no_calendar">没有可写入的日历</string>
<string name="event_edit_save_failed">无法保存事件</string>
<string name="event_edit_write_denied">Calendula 需要写入权限才能创建事件</string>
<string name="event_edit_more_fields">更多字段</string>
<string name="event_edit_add">添加</string>
<string name="event_edit_add_reminder">添加提醒</string>
<string name="event_edit_remove_reminder">移除提醒</string>
<string name="event_edit_attendees">访问</string>
<string name="event_edit_add_guest">新增访问</string>
<string name="event_edit_add_guest_hint">通过 Email 新增一个访问者…</string>
<string name="event_edit_add_guest_from_contacts">从联系人添加访问者</string>
<string name="event_edit_location_from_contacts">从联系人中添加地址</string>
<string name="event_edit_remove_guest">移除访问</string>
<string name="event_edit_attendee_required"></string>
<string name="event_edit_attendee_optional">可选</string>
<string name="event_edit_attendees_note_synced">Calendula 不发送邀请函。你的日历户同步时可能会给访客发邮件</string>
<string name="event_edit_attendees_note_local">保存在本设备,其他访客不会被提醒</string>
<string name="event_edit_attendees">参与</string>
<string name="event_edit_add_guest">添加参与</string>
<string name="event_edit_add_guest_hint">通过电子邮件添加参与者…</string>
<string name="event_edit_add_guest_from_contacts">从联系人添加</string>
<string name="event_edit_location_from_contacts">从联系人选取地址</string>
<string name="event_edit_remove_guest">移除参与</string>
<string name="event_edit_attendee_required"></string>
<string name="event_edit_attendee_optional">可选</string>
<string name="event_edit_attendees_note_synced">Calendula 不发送邀请。您的日历户同步时可能会通过邮件通知参与者</string>
<string name="event_edit_attendees_note_local">存储于本设备,不会通知任何人</string>
<string name="event_edit_reminder_custom">自定义</string>
<string name="reminder_unit_minutes">分钟</string>
<string name="reminder_unit_hours">小时</string>
<string name="reminder_unit_days"></string>
<string name="reminder_unit_weeks"></string>
<string name="event_edit_availability">空闲</string>
<string name="event_edit_visibility">隐私设置</string>
<string name="event_edit_color"></string>
<string name="event_edit_availability">忙闲状态</string>
<string name="event_edit_visibility">可见性</string>
<string name="event_edit_color"></string>
<string name="event_edit_color_default">日历颜色</string>
<string name="event_edit_color_custom">自定义颜色</string>
<string name="event_edit_color_reset">重置</string>
<string name="event_edit_color_unsupported">日历不可用</string>
<string name="event_edit_color_unsupported_hint">此日历未设置任何颜色集。您可以在“设置”中为此类日历启用自定义颜色。</string>
<string name="event_edit_color_sync_warning">日历在下一次同步时可能会删除或覆盖该颜色。</string>
<string name="event_edit_conflict_title">其他设备的活动已更改</string>
<string name="event_edit_conflict_body">编辑时,事件已同步或其他应用修改。您的修改要怎么处理?</string>
<string name="event_edit_color_unsupported">日历不支持</string>
<string name="event_edit_color_unsupported_hint">此日历未提供颜色集。您可以在“设置”中为此类日历允许自定义颜色。</string>
<string name="event_edit_color_sync_warning">日历次同步时可能会丢弃或覆盖该颜色。</string>
<string name="event_edit_conflict_title">事件已在别处更改</string>
<string name="event_edit_conflict_body">您编辑时,事件已通过同步或其他应用修改。您的更改应如何处理?</string>
<string name="event_edit_conflict_overwrite">保存我的更改</string>
<string name="event_edit_conflict_overwrite_hint">仅您编辑的字段会覆盖外部更改</string>
<string name="event_edit_conflict_overwrite_hint">覆盖您编辑的字段</string>
<string name="event_edit_conflict_discard">丢弃我的更改</string>
<string name="event_edit_conflict_discard_hint">该活动保持现状</string>
<string name="event_edit_gone_title">活动被删除</string>
<string name="event_edit_gone_body">这个事件在您编辑期间已被删除了(比如在另一设备上)。您的修改现在无法保存。</string>
<string name="event_edit_recurrence_none">确认无需重复</string>
<string name="event_edit_conflict_discard_hint">事件保持当前状态</string>
<string name="event_edit_gone_title">事件已被删除</string>
<string name="event_edit_gone_body">事件在您编辑期间已被删除(例如在另一设备上)。您的更改无法保存。</string>
<string name="event_edit_recurrence_none">重复</string>
<string name="event_edit_recurrence_custom">自定义</string>
<string name="event_edit_recurrence_every"></string>
<string name="recurrence_unit_days"></string>
<string name="recurrence_unit_weeks"></string>
<string name="recurrence_unit_months"></string>
<string name="recurrence_unit_years"></string>
<string name="event_edit_recurrence_ends">结束时间</string>
<string name="event_edit_recurrence_end_never"></string>
<string name="event_edit_recurrence_ends">结束</string>
<string name="event_edit_recurrence_end_never"></string>
<string name="event_edit_recurrence_end_until">于指定日期</string>
<string name="event_edit_recurrence_end_count">重复几次</string>
<string name="event_edit_recurrence_end_count">在指定次数</string>
<string name="event_edit_recurrence_times"></string>
<string name="event_edit_error_recurrence_ends_before_start">报错:结束日期早于开始日期</string>
<string name="event_availability_busy">占用中</string>
<string name="event_edit_error_recurrence_ends_before_start">重复结束日期早于事件开始时间</string>
<string name="event_availability_busy">忙碌</string>
<string name="event_access_default">默认</string>
<string name="event_access_public">公开</string>
<string name="event_detail_duplicate">复制</string>
<string name="event_move_action">移动…</string>
<string name="event_move_recurring_title">删除重复活动</string>
<string name="event_move_occurrence_only">移动整个系列会改变其发生日期,因此只能移动此事件。</string>
<string name="event_move_done">已移动到 %1$s</string>
<string name="event_move_undo">撤销</string>
<string name="event_move_undone">已撤销移动</string>
<string name="event_move_failed">无法保存该活动</string>
<string name="event_move_write_denied">Calendula需要权限读取或删除活动</string>
<string name="event_move_gone">该事件已不存在</string>
<string name="event_move_blocked_series_end">无法将事件移至其系列结束日期之后</string>
<string name="event_edit_timezone_device">设备时区</string>
<string name="event_edit_timezone_device_summary">跟随您所在位置</string>
<string name="event_edit_timezone_search">搜索时区</string>
<string name="event_edit_timezone_recent">最近使用</string>
<string name="event_edit_timezone_all">所有时区</string>
<string name="event_edit_timezone_none">没有与“%1$s”匹配的时区</string>
<string name="event_edit_timezone_local_time">%1$s 您的本地时间</string>
<string name="import_reminder_prompt_title">应用默认提醒?</string>
<string name="import_reminder_prompt_body_none">此事件导入时没有提醒。</string>
<plurals name="import_reminder_prompt_body_existing">
<item quantity="other">此事件导入时包含 %1$d 个提醒。</item>
</plurals>
<string name="app_name">Calendula</string>
<string name="week_number_label"></string>
<string name="import_reminder_prompt_apply">应用默认</string>
<string name="import_reminder_prompt_keep">保留原样</string>
<string name="event_edit_recurrence_incomplete">请输入 1 到 999 之间的数字</string>
<string name="event_edit_recurrence_next">下一次:%1$s</string>
<string name="event_edit_recurrence_next_none">此规则永不重复</string>
<string name="event_detail_all_day">全天</string>
<string name="event_detail_calendar">Calendula</string>
<string name="event_detail_calendar_unknown">未知日历</string>
<string name="event_detail_location">地点</string>
<string name="event_detail_description">描述</string>
<string name="event_detail_attendees">参与者</string>
<string name="event_detail_recurrence">重复</string>
<string name="event_detail_recurring">重复事件</string>
<string name="recurrence_daily">每天</string>
<string name="recurrence_weekly">每周</string>
<string name="recurrence_monthly">每月</string>
<string name="recurrence_yearly">每年</string>
<string name="recurrence_every_n_days">每 %1$d 天</string>
<string name="recurrence_every_n_weeks">每 %1$d 周</string>
<string name="recurrence_every_n_months">每 %1$d 月</string>
<string name="recurrence_every_n_years">每 %1$d 年</string>
<string name="recurrence_on_days">%1$s%2$s</string>
<string name="recurrence_with_until">%1$s直到 %2$s</string>
<string name="recurrence_with_count">%1$s共 %2$d 次</string>
<string name="event_detail_not_found">此事件已不存在。</string>
<string name="event_attendee_accepted">已接受</string>
<string name="event_attendee_declined">已拒绝</string>
<string name="event_attendee_tentative">待定</string>
<string name="event_attendee_needs_action">未回复</string>
<string name="event_attendee_unknown"></string>
<string name="event_detail_reminders">提醒</string>
<string name="event_detail_timezone">时区</string>
<string name="event_status_tentative">待定</string>
<string name="event_status_cancelled">取消</string>
<string name="event_availability_free">空闲</string>
<string name="event_access_private">私密</string>
<string name="event_access_confidential">机密</string>
<string name="event_access_default_summary">按日历默认设置</string>
<string name="event_access_public_summary">有权限者可见全部详情</string>
<string name="event_access_private_summary">他人仅看到您忙碌</string>
<string name="event_access_confidential_summary">标记为机密,具体含义由日历帐户决定</string>
<string name="event_attendee_organizer">组织者</string>
<string name="event_attendee_optional">可选项</string>
<string name="event_attendee_resource">资源</string>
<string name="event_detail_self_response">您的回复:%1$s</string>
<string name="reminder_at_time">事件开始时</string>
<string name="reminder_default">默认提醒</string>
<plurals name="reminder_minutes">
<item quantity="other">提前 %d 分钟</item>
</plurals>
<plurals name="reminder_hours">
<item quantity="other">提前 %d 小时</item>
</plurals>
<plurals name="reminder_days">
<item quantity="other">提前 %d 天</item>
</plurals>
<plurals name="reminder_weeks">
<item quantity="other">提前 %d 周</item>
</plurals>
<plurals name="duration_minutes">
<item quantity="other">%d分钟</item>
</plurals>
<plurals name="duration_hours">
<item quantity="other">%d 小时</item>
</plurals>
<plurals name="duration_days">
<item quantity="other">%d 天</item>
</plurals>
<string name="duration_hours_minutes">%1$s %2$s</string>
<string name="duration_custom_max">最多 %1$s</string>
<plurals name="duration_weeks">
<item quantity="other">%d 周</item>
</plurals>
<string name="event_untitled">(无标题)</string>
<string name="onboarding_step_counter">第 %1$d 步,共 %2$d 步</string>
<string name="onboarding_backup_title">您的事件仅保存在这里</string>
<string name="onboarding_backup_body">本手机上的事件不会同步到任何帐户丢失手机将丢失日历。Calendula 可以为您创建备份。</string>
<string name="onboarding_backup_benefit_folder_title">您选择的文件夹</string>
<string name="onboarding_backup_benefit_folder_body">备份为纯 .ics 文件——可存放在同步文件夹或 SD 卡中。</string>
<string name="onboarding_backup_benefit_daily_title">每天自动备份</string>
<string name="onboarding_backup_benefit_daily_body">Calendula 会在后台导出您的本地日历。您可以在“设置”中更改频率。</string>
<string name="onboarding_backup_enable_button">选择文件夹并备份</string>
<string name="onboarding_backup_skip_button">暂不</string>
<string name="onboarding_view_title">默认打开哪个视图?</string>
<string name="onboarding_month_style_title">月视图样式?</string>
<string name="onboarding_view_continue_button">继续</string>
<string name="onboarding_back">返回</string>
<string name="onboarding_visibility_button">知道了</string>
<string name="onboarding_done_title">一切就绪</string>
<string name="onboarding_done_body">您的日历已就绪。所有选择均可在“设置”中更改。</string>
<string name="onboarding_done_button">打开我的日历</string>
<string name="reminder_channel_name">事件提醒</string>
<string name="reminder_channel_description">按事件提醒时间推送的通知</string>
<string name="reminder_onboarding_title">不错过任何事件</string>
<string name="reminder_onboarding_body">Android 本身不会显示事件提醒——需要日历应用来承担。让 Calendula 接管这项工作吧。</string>
<string name="reminder_benefit_delivery_title">准时送达提醒</string>
<string name="reminder_benefit_delivery_body">您事件中的每个提醒都会按时以通知形式送达。</string>
<string name="reminder_benefit_duplicates_title">使用第二个日历应用?</string>
<string name="reminder_benefit_duplicates_body">如果另一个应用也发送提醒,您会看到两次——请在其中一个中关闭。</string>
<string name="reminder_benefit_reversible_title">随时更改</string>
<string name="reminder_benefit_reversible_body">开关位于“设置”中的“通知”下。</string>
<string name="reminder_onboarding_enable_button">开启提醒</string>
<string name="reminder_onboarding_skip_button">暂不</string>
<string name="reminder_action_snooze">稍后提醒</string>
<string name="reminder_action_dismiss">关闭</string>
<string name="reminder_day_tomorrow">明天</string>
<string name="reminder_day_yesterday">昨天</string>
<string name="view_month"></string>
<string name="view_week"></string>
<string name="view_day"></string>
<string name="view_agenda">日程</string>
<string name="view_section">视图</string>
<string name="drawer_jump_to_date">跳转到日期</string>
<string name="agenda_today_action">今天</string>
<string name="agenda_header_today">今天</string>
<string name="agenda_header_tomorrow">明天</string>
<string name="agenda_empty_title">暂无待办</string>
<string name="agenda_no_more_today">今天没有更多事件</string>
<string name="agenda_span_starts">开始 %1$s</string>
<string name="agenda_span_ends">结束 %1$s</string>
<string name="today_jump_action">去今天</string>
<string name="search_action">搜索</string>
<string name="search_hint">搜索事件</string>
<string name="search_back">返回</string>
<string name="search_clear">清除</string>
<string name="search_idle_hint">按标题、地点或备注搜索您的事件。</string>
<string name="search_empty">没有与“%1$s”匹配的事件。</string>
<plurals name="search_selected_count">
<item quantity="other">已选 %d 个</item>
</plurals>
<string name="search_in_descriptions">在描述中找到</string>
<string name="search_selection_close">取消选择</string>
<string name="search_select_all">全选</string>
<string name="search_delete_selected">删除所选</string>
<plurals name="search_delete_title">
<item quantity="other">删除 %d个活动</item>
</plurals>
<plurals name="search_delete_done">
<item quantity="other">删除了%d个活动</item>
</plurals>
<string name="search_delete_partial">已删除 %1$d 个,%2$d 个无法删除</string>
<string name="search_delete_denied_partial">已删除 %1$d 个,之后写入权限被撤</string>
<string name="widget_agenda_title">即将开始</string>
<string name="widget_agenda_label">Calendula 日程</string>
<string name="widget_month_label">Calendula 月视图</string>
<string name="widget_refresh">刷新</string>
<string name="widget_new_event">新活动</string>
<string name="widget_needs_permission">打开 Calendula 授予日历访问权限</string>
<string name="widget_prev_month">上个月</string>
<string name="widget_next_month">下个月</string>
<string name="widget_today">今天</string>
<string name="filter_title">日历</string>
<string name="settings_title">设置</string>
<string name="settings_back">返回</string>
<string name="back">返回</string>
<string name="settings_section_appearance">外观</string>
<string name="settings_theme">主题</string>
<string name="settings_theme_system">跟随系统</string>
<string name="settings_theme_light">浅色</string>
<string name="settings_theme_dark">深色</string>
<string name="settings_theme_hint">应用使用浅色或深色主题。选择后立即生效。</string>
<string name="settings_theme_system_summary">当前为 %1$s</string>
<string name="settings_default_view">默认视图</string>
<string name="settings_dynamic_color">动态颜色</string>
<string name="settings_dynamic_color_unavailable">需要 Android 12 或更高版本</string>
<string name="settings_soften_colors">协调日历颜色</string>
<string name="settings_soften_colors_summary">保留每个日历的色调但均衡亮度,使所有事件清晰可读且色彩协调。关闭则显示日历源的原始颜色。</string>
<string name="settings_font_headings">标题字体</string>
<string name="settings_font_body">正文字体</string>
<string name="settings_font_system">系统默认</string>
<string name="font_atkinson_hyperlegible">Atkinson Hyperlegible</string>
<string name="font_lora">Lora</string>
<string name="font_jetbrains_mono">JetBrains Mono</string>
<string name="settings_font_choose_file">选择文件…</string>
<string name="settings_font_custom_selected">自定义字体</string>
<string name="settings_font_import_failed">无法将文件识别为字体</string>
<string name="settings_font_specimen_heading">2026年8月28日 星期四</string>
<string name="settings_font_specimen_body">团队评审 10:00然后与 Robin 在集市广场咖啡馆共进午餐。</string>
<string name="settings_week_start">每周起始日</string>
<string name="settings_week_start_auto">自动</string>
<string name="settings_week_start_auto_summary">当前为 %1$s</string>
<string name="settings_week_numbers">周数</string>
<string name="settings_week_numbers_summary">在月视图中显示日历周数</string>
<string name="settings_today_toolbar">工具栏中的“今天”按钮</string>
<string name="settings_today_toolbar_summary">在工具栏中显示“跳至今天”按钮,而非浮动按钮</string>
<string name="settings_app_name">应用名称</string>
<string name="settings_app_name_summary">在启动器中显示为“日历”。仅启动器名称改变;切换后图标可能移动到新位置。</string>
<string name="settings_time_format">时间格式</string>
<string name="settings_time_format_auto">自动</string>
<string name="settings_time_format_12h">12 小时制(下午 2:00</string>
<string name="settings_time_format_24h">24 小时制14:00</string>
<string name="settings_time_format_auto_summary">跟随系统:%1$s</string>
<string name="settings_hour_lines">整点分隔线</string>
<string name="settings_hour_lines_summary">在周视图和日视图中显示每个整点的分隔线</string>
<string name="settings_timeline_scale">小时高度</string>
<string name="settings_timeline_scale_hint">周视图和日视图中每小时占用的垂直空间。两者共享此设置。您也可以用双指捏合时间线设置任意高度。</string>
<string name="timeline_scale_fit_day">适应全天</string>
<string name="timeline_scale_fit_day_summary">24 小时一屏显示,无需滚动</string>
<string name="timeline_scale_compact">紧凑</string>
<string name="timeline_scale_compact_summary">每屏显示更多小时,区块更小</string>
<string name="timeline_scale_regular">常规</string>
<string name="timeline_scale_regular_summary">标准间距</string>
<string name="timeline_scale_comfortable">舒适</string>
<string name="timeline_scale_comfortable_summary">区块更宽敞,需更多滚动</string>
<string name="timeline_scale_custom">自定义</string>
<string name="timeline_scale_custom_summary">您捏合时间线所设定的高度</string>
<string name="settings_dim_completed">变暗已完成事件</string>
<string name="settings_dim_completed_summary">在月视图和周视图中淡化已结束的事件</string>
<string name="settings_drag_to_reschedule">拖拽重新安排</string>
<string name="settings_drag_to_reschedule_summary">通过拖拽事件到另一天或时间来移动它</string>
<string name="settings_past_events">过去事件</string>
<string name="settings_past_events_show">显示</string>
<string name="settings_past_events_dim">变暗</string>
<string name="settings_past_events_hide">隐藏</string>
<string name="settings_past_events_sample_morning">团队评审</string>
<string name="settings_past_events_sample_midday">与 Robin 午餐</string>
<string name="settings_past_events_sample_evening">合唱团练习</string>
<string name="settings_agenda_header">日程</string>
<string name="settings_agenda_range">日程范围</string>
<string name="settings_agenda_range_hint">“日程”视图列出未来事件的时间跨度。</string>
<string name="settings_agenda_widget_range">日程小部件范围</string>
<string name="settings_agenda_widget_range_hint">主屏幕日程小部件列出未来事件的时间跨度。</string>
<string name="settings_widget_size">日程小部件大小</string>
<string name="settings_widget_size_hint">主屏幕日程小部件绘制文字的大小。月视图小部件无此设置——它的网格始终适应您给定的空间。</string>
<string name="settings_widget_size_small"></string>
<string name="settings_widget_size_medium"></string>
<string name="settings_widget_size_large"></string>
<string name="settings_widget_size_extra_large">特大</string>
<string name="settings_widget_size_summary">事件文字 %1$d%%</string>
<string name="settings_agenda_show_today">始终显示今天</string>
<string name="settings_agenda_show_today_hint">即使今天没有剩余事件,也将今天保持在日程及其小部件顶部。</string>
<string name="settings_agenda_range_bar">范围栏</string>
<string name="settings_agenda_range_bar_hint">在日程顶部显示一个条,标明显示的日期范围,并提供一个按钮用于临时切换范围</string>
<string name="agenda_range_day">今天</string>
<string name="agenda_range_this_week">本周</string>
<string name="agenda_range_this_month">本月</string>
<string name="agenda_range_week">未来 7 天</string>
<string name="agenda_range_month">未来 30 天</string>
<string name="agenda_range_custom">自定义…</string>
<string name="agenda_range_custom_hint">天数</string>
<string name="agenda_range_override_hint">仅本次生效——重新打开 Calendula 时恢复为已保存的范围。</string>
<string name="agenda_range_showing_label">显示所有未来事件</string>
<plurals name="agenda_range_days">
<item quantity="other">%d 天</item>
</plurals>
<string name="settings_section_views">视图</string>
<string name="settings_month_header">月视图</string>
<string name="settings_month_view_style">月视图样式</string>
<string name="month_style_paged">分页</string>
<string name="month_style_paged_summary">一屏显示一个月,左右滑动切换月份。</string>
<string name="month_style_continuous">滚动月份</string>
<string name="month_style_continuous_summary">每个月在其标题下,与下个月之间略有间距。</string>
<string name="month_style_dense">无缝周</string>
<string name="month_style_dense_summary">各周连续排列,月份之间无间隙。</string>
<string name="month_style_split">拆分</string>
<string name="month_style_split_summary">紧凑网格标记有事件的日子,点击的日期在下方列出。</string>
<string name="month_split_no_events">无安排</string>
<string name="month_split_expand">显示整月</string>
<string name="month_split_collapse">显示当天事件</string>
<string name="settings_quick_switch_header">快速切换按钮</string>
<string name="settings_quick_switch_hint">选择右上角按钮循环切换的视图,并拖动排序。关闭的视图仍可从导航菜单访问。</string>
<string name="settings_drawer_order_header">导航菜单</string>
<string name="settings_drawer_order_hint">拖动排序导航菜单中的视图。</string>
<string name="reorder_drag_handle">拖动以排序</string>
<string name="settings_section_event_form">新建事件表单</string>
<string name="settings_form_fields_hint">默认显示的字段——其他字段位于“更多字段”下</string>
<string name="settings_autofocus_title">新建事件时聚焦标题</string>
<string name="settings_autofocus_title_hint">创建新事件时,光标自动置于标题字段并弹出键盘。</string>
<string name="settings_event_duration">默认时长</string>
<string name="settings_event_duration_hint">新事件在您更改结束时间之前的默认时长。全天事件不受影响。</string>
<string name="settings_calendar_durations_title">按日历设置时长</string>
<string name="settings_calendar_durations_hint">为某个日历单独设置默认时长——例如工作班次设为 8 小时。</string>
<string name="settings_calendar_duration_inherits">默认(%1$s</string>
<string name="settings_calendar_duration_use_default">使用默认时长(%1$s</string>
<string name="settings_color_unsupported">允许在不支持的日历上使用颜色</string>
<string name="settings_color_unsupported_hint">某些日历(例如某些 CalDAV未发布颜色集自定义事件颜色可能会在下一次同步时被丢弃或覆盖。这是那些日历的限制并非 Calendula 可修复的问题。</string>
<string name="settings_section_notifications">通知</string>
<string name="settings_reminders">事件提醒</string>
<string name="settings_reminders_hint">看到重复提醒?另一个日历应用也在发送——请关闭其中一个。</string>
<string name="settings_default_reminder">默认提醒</string>
<string name="settings_default_reminder_allday">全天事件</string>
<string name="settings_allday_reminder_time">全天事件提醒时间</string>
<string name="settings_allday_reminder_time_hint">全天事件的提醒在 %1$s 触发</string>
<string name="settings_allday_reminder_fires_at">在 %1$s 通知</string>
<string name="reminder_none"></string>
<string name="reminder_use_default">使用默认提醒</string>
<string name="reminder_custom_amount">数量</string>
<string name="reminder_custom_set">设置</string>
<string name="settings_calendar_reminders_title">按日历设置提醒</string>
<string name="settings_calendar_reminders_hint">为每个日历覆盖默认提醒——分别针对定时事件和全天事件。日历可保持默认、不使用提醒,或设置自己的提醒。</string>
<string name="settings_calendar_reminder_inherits">默认(%1$s</string>
<string name="settings_reliable_delivery">可靠送达</string>
<string name="settings_reliable_delivery_hint">Android 可能为省电延迟提醒。豁免 Calendula 以使其准时送达。</string>
<string name="settings_reliable_delivery_exempt">豁免电池优化——提醒准时送达。</string>
<string name="settings_snooze_duration">贪睡时长</string>
<string name="settings_section_calendars">日历</string>
<string name="settings_manage_calendars">管理日历</string>
<string name="settings_manage_calendars_hint">创建本地日历;管理同步日历</string>
<string name="settings_section_language">语言</string>
<string name="settings_language">应用语言</string>
<string name="settings_language_auto">系统默认</string>
<string name="settings_translate">帮助翻译</string>
<string name="settings_translate_hint">在 Weblate 上添加或改进语言</string>
<string name="settings_group_look">外观与行为</string>
<string name="settings_group_data">数据</string>
<string name="settings_group_app">应用</string>
<string name="settings_group_about">关于</string>
<string name="settings_appearance_subtitle">主题、颜色、字体</string>
<string name="settings_views_subtitle">默认视图、布局、顺序</string>
<string name="settings_event_form_subtitle">默认字段和行为</string>
<string name="settings_notifications_subtitle">提醒与送达</string>
<string name="settings_special_dates_subtitle">联系人生日和纪念日</string>
<string name="settings_widgets_subtitle">日程小部件、快速设置磁贴</string>
<string name="settings_backup_subtitle">导出、导入、自动备份</string>
<string name="settings_section_widgets">小部件与磁贴</string>
<string name="settings_widgets_hint">主屏幕小部件和快速设置磁贴的设置。长按主屏幕即可添加小部件。</string>
<string name="settings_section_backup">备份与恢复</string>
<string name="settings_views_all_header">所有视图</string>
<string name="settings_week_day_header">周与日</string>
<string name="settings_default_view_hint">启动 Calendula 时默认打开的视图。</string>
<string name="settings_week_start_hint">所有视图和小部件中每周开始的日子。</string>
<string name="settings_time_format_hint">整个应用的时间显示格式。自动跟随系统设置。</string>
<string name="settings_past_events_hint">日程对已结束事件的处理方式。</string>
<string name="settings_dynamic_color_summary">从壁纸中提取应用颜色。</string>
<string name="settings_section_special_dates">联系人特殊日期</string>
<string name="settings_special_dates_enable">显示联系人日期</string>
<string name="settings_special_dates_enable_hint">将联系人生日和其他日期镜像到本地日历。仅读取本设备上的联系人——不会上传任何内容,也不会修改您的联系人。</string>
<string name="settings_special_dates_type_birthday">生日</string>
<string name="settings_special_dates_type_anniversary">纪念日</string>
<string name="settings_special_dates_type_custom">其他日期</string>
<string name="settings_special_dates_template">标题格式</string>
<string name="settings_special_dates_template_hint">使用 {name} 表示联系人,{year} 表示年份(出生年份或纪念日开始年份;未知时隐藏)。</string>
<string name="settings_special_dates_reminders">提醒</string>
<string name="settings_special_dates_show_year">显示年份</string>
<string name="settings_special_dates_show_year_hint">在标题中包含 {year}(当已知时)</string>
<string name="settings_special_dates_sync_now">立即同步</string>
<string name="settings_special_dates_never_synced">尚未同步</string>
<string name="settings_special_dates_last_synced">上次同步:%1$s</string>
<string name="settings_special_dates_calendar_hint">在“日历”设置中分别设置每个日历的颜色和可见性。</string>
<string name="settings_calendar_reminders_managed_hint">在“联系人特殊日期”中设置</string>
<string name="settings_special_dates_paused_title">已暂停</string>
<string name="settings_special_dates_paused_hint">Calendula 无法读取您的联系人,因此这些日历未更新。</string>
<string name="settings_special_dates_grant">授予访问权限</string>
<string name="settings_special_dates_disable_title">关闭联系人日期?</string>
<string name="settings_special_dates_disable_all_message">这将删除联系人日期日历及其事件。您添加的任何提醒或备注将丢失。</string>
<string name="settings_special_dates_disable_type_message">这将删除“%1$s”日历及其事件。您添加的任何提醒或备注将丢失。</string>
<string name="settings_special_dates_disable_confirm">关闭</string>
<string name="dialog_save">保存</string>
<string name="settings_section_about">关于</string>
<string name="settings_license">许可协议</string>
<string name="settings_license_value">MIT</string>
<string name="settings_about_author">作者 Jean-Luc Makiola</string>
<string name="settings_about_source">源代码</string>
<string name="settings_about_privacy">隐私政策</string>
<string name="settings_about_support">支持开发</string>
<string name="settings_about_version">版本 %1$s</string>
<string name="settings_about_logo_desc">Calendula 应用图标</string>
<string name="settings_report_problem">报告问题</string>
<string name="settings_report_problem_hint">发送崩溃报告或打开问题追踪器</string>
<string name="calendars_title">日历</string>
<string name="calendars_local_header">您的日历</string>
<string name="calendars_local_empty">尚未创建本地日历。创建一个以仅在本设备保存事件。</string>
<string name="calendars_add">添加日历</string>
<string name="calendars_visibility_hint">关闭日历可隐藏其在设备上的显示——事件会从应用中消失,同时停止提醒。此开关与其他日历应用共用,因此它们也会隐藏。不会删除任何内容,不会影响其他设备,您随时可在此重新开启。</string>
<string name="calendars_visibility_a11y">显示“%1$s”</string>
<string name="calendars_visibility_notice_title">部分日历已关闭</string>
<string name="calendars_visibility_notice_message">Calendula 显示本设备已开启的日历,但您有一些是关闭的。要查看事件,请在“设置”→“日历”中将其开启。</string>
<string name="calendar_picker_missing_title">找不到日历?</string>
<string name="calendar_picker_missing_summary">可能已关闭、只读,或由联系人填充——在此管理您的日历。</string>
<string name="calendars_state_read_only">只读</string>
<string name="calendars_state_not_synced">未同步到本设备</string>
<string name="calendars_state_managed">由联系人填充</string>
<string name="calendars_managed_delete_locked">此日历由联系人填充Calendula 下次同步时会重新创建。要删除它,请在“设置”→“特殊日期”中关闭相关功能。</string>
<string name="calendars_synced_header">同步日历</string>
<string name="calendars_synced_hint">来自设备上的帐户。请在对应的应用中创建和编辑。</string>
<string name="calendars_manage_in_app">在应用中管理</string>
<string name="calendars_account_from_source">%1$s%2$s</string>
<string name="calendars_account_menu_a11y">%1$s 的更多选项</string>
<string name="calendars_enable_all">启用全部</string>
<string name="calendars_disable_all">禁用全部</string>
<string name="calendars_add_account">添加帐户</string>
<string name="calendars_new_title">新建日历</string>
<string name="calendars_edit_title">编辑日历</string>
<string name="calendars_name_label">名称</string>
<string name="calendars_color_label">色彩</string>
<string name="calendars_description_hint">添加描述</string>
<string name="calendars_delete_confirm_title">删除日历?</string>
<string name="calendars_delete_confirm_message">“%1$s”及其所有事件将从本设备永久删除。</string>
<string name="calendars_write_error">无法保存更改。</string>
<string name="calendars_backup_header">返回</string>
<string name="calendars_backup_hint">本地日历不会同步到任何地方,请导出为 .ics 文件以保留副本。</string>
<string name="calendars_backup_action">导出为 .ics 文件</string>
<string name="calendars_export_title">导出日历</string>
<string name="calendars_export_hint">选择要包含在 .ics 文件中的日历。</string>
<string name="calendars_export_action">导出</string>
<string name="calendars_restore_header">恢复</string>
<string name="calendars_restore_action">从 .ics 文件恢复</string>
<string name="calendars_restore_hint">从备份或其他日历应用导入事件。</string>
<string name="calendars_auto_backup">自动备份</string>
<string name="calendars_auto_backup_hint">定期将本地日历导出为 .ics 文件保存到文件夹。</string>
<string name="calendars_auto_backup_folder">备份文件夹</string>
<string name="calendars_auto_backup_folder_unset">点击选择文件夹</string>
<string name="calendars_auto_backup_interval">间隔</string>
<string name="calendars_auto_backup_every">每 %1$s</string>
<string name="calendars_auto_backup_interval_min">最短 30 分钟。</string>
<string name="calendars_auto_backup_status_never">尚未自动备份</string>
<string name="calendars_auto_backup_status_ok">上次备份:%1$s</string>
<string name="calendars_auto_backup_status_failed">上次备份失败:%1$s</string>
<string name="backup_channel_name">备份</string>
<string name="backup_channel_description">自动备份反复失败时发出警告。</string>
<string name="backup_failed_title">自动备份失败</string>
<string name="backup_failed_text">Calendula 无法写入备份文件。请在“设置”中检查备份文件夹。</string>
<string name="calendars_backup_failed">无法导出备份。</string>
<plurals name="calendars_backup_done">
<item quantity="other">已导出 %d 个事件。</item>
</plurals>
<string name="import_title">导入事件</string>
<string name="import_target_header">添加至日历</string>
<string name="import_empty">此文件中未找到事件。</string>
<string name="import_failed">无法读取此文件。</string>
<string name="import_no_calendar">没有可写入的日历用于导入。请先创建本地日历。</string>
<string name="import_done_title">导入完成</string>
<string name="import_done_dedup_note">已跳过日历中已存在的事件。</string>
<string name="import_done_added_label">已添加</string>
<string name="import_done_skipped_label">重复项</string>
<string name="import_close">关闭</string>
<string name="import_warning_recurrence">已跳过重复事件中部分已修改的发生项。</string>
<string name="import_warning_no_start">已跳过无开始时间的事件。</string>
<string name="import_warning_attendees">未导入参与者列表。</string>
<string name="import_warning_timezone">未知时区已回退为设备时区。</string>
<string name="import_button">导入</string>
<plurals name="import_title_count">
<item quantity="other">正在导入 %d 个事件</item>
</plurals>
<plurals name="import_event_count">
<item quantity="other">此文件中包含 %d 个事件。</item>
</plurals>
<plurals name="import_action">
<item quantity="other">导入 %d 个事件</item>
</plurals>
<plurals name="import_done_imported">
<item quantity="other">已导入 %d 个事件。</item>
</plurals>
<plurals name="import_done_skipped">
<item quantity="other">已跳过 %d 个(已存在于该日历)。</item>
</plurals>
<string name="shortcut_new_event_short">新事件</string>
<string name="shortcut_new_event_long">创建新事件</string>
<string name="qs_tile_new_event_label">新事件</string>
<string name="settings_qs_tile">添加快速设置磁贴</string>
<string name="settings_qs_tile_hint">在快速设置面板中添加“新事件”磁贴。</string>
<string name="crash_dialog_title">%1$s 已崩溃</string>
<string name="crash_dialog_message">%1$s 上次意外关闭。您可以将此报告作为问题发送以帮助修复。报告在您选择共享之前仅保留在设备上,不含任何个人数据或日历内容——仅包含以下技术细节。</string>
<string name="crash_dialog_report">报告</string>
<string name="crash_dialog_dismiss">暂不</string>
<string name="crash_report_issue_title">崩溃报告</string>
<string name="crash_report_clip_label">%1$s 崩溃报告</string>
<string name="crash_report_copied">报告已复制到剪贴板</string>
<string name="crash_report_open_failed">无法打开问题追踪器。报告已在剪贴板中。</string>
<string name="crash_report_body_template">感谢您报告 %1$s 的崩溃。请补充您记得的操作内容,然后提交。\n\n### 发生了什么\n\n\n### 崩溃报告\n%2$s\n</string>
<string name="crash_report_body_paste">_报告太长无法通过此链接附带——请从剪贴板粘贴。_</string>
<string name="special_dates_calendar_birthday">生日</string>
<string name="special_dates_calendar_anniversary">纪念日</string>
<string name="special_dates_calendar_custom">特殊日期</string>
<string name="special_dates_default_title_birthday">{name} 的生日({year}</string>
<string name="special_dates_default_title_anniversary">{name} 的纪念日({year}</string>
<string name="special_dates_default_title_custom">{name}</string>
</resources>

View File

@@ -128,7 +128,8 @@ class EventWriteMapperTest {
original: EventForm,
updated: EventForm,
series: Long = seriesStart,
): Map<String, Any?> = buildEventUpdateValues(original, updated, series, berlin)
exdate: String? = null,
): Map<String, Any?> = buildEventUpdateValues(original, updated, series, exdate, berlin)
/** The instant [local] names in [zoneId], as the provider would store it. */
private fun instantAt(local: String, zoneId: String): Long =
@@ -558,6 +559,239 @@ class EventWriteMapperTest {
assertThat(values[CalendarContract.Events.ALL_DAY]).isEqualTo(1)
}
// --- EXDATE follows the series when its times change (Codeberg #248) ---
/** A weekly series whose displayed occurrence runs 15 July 2026, 09:0010:00. */
private fun julySeries(): EventForm = form(
start = LocalDateTime(LocalDate(2026, 7, 15), LocalTime(9, 0)),
end = LocalDateTime(LocalDate(2026, 7, 15), LocalTime(10, 0)),
).copy(rrule = "FREQ=WEEKLY")
/** [julySeries] pushed to [hour]:00, the shift an "all events" time edit makes. */
private fun EventForm.atHour(hour: Int): EventForm = copy(
start = LocalDateTime(LocalDate(2026, 7, 15), LocalTime(hour, 0)),
end = LocalDateTime(LocalDate(2026, 7, 15), LocalTime(hour + 1, 0)),
)
@Test
fun `a series time edit moves its exclusions with the anchor`() {
// The bug: the stamp stayed at the old instant, which the moved series no
// longer generates, so the occurrence the user deleted came back.
val series = instantAt("2026-07-01T09:00", "Europe/Berlin")
val original = julySeries()
// 8 July 09:00 Berlin (CEST, +2) == 07:00Z; at 10:00 it must read 08:00Z.
val values = update(original, original.atHour(10), series, "20260708T070000Z")
assertThat(values[CalendarContract.Events.EXDATE]).isEqualTo("20260708T080000Z")
}
@Test
fun `an exclusion keeps its wall clock across a DST boundary`() {
// Anchor and edited occurrence are in July (CEST, +2); the excluded
// occurrence sits in January (CET, +1). Shifting by the millisecond delta
// measured at the edited occurrence would leave it an hour off.
val series = instantAt("2026-01-07T09:00", "Europe/Berlin")
val original = julySeries()
// 14 January 09:00 Berlin == 08:00Z; at 10:00 it must read 09:00Z.
val values = update(original, original.atHour(10), series, "20260114T080000Z")
assertThat(values[CalendarContract.Events.EXDATE]).isEqualTo("20260114T090000Z")
}
@Test
fun `pinning a series to another zone re-resolves its exclusions there`() {
val series = instantAt("2026-07-01T09:00", "Europe/Berlin")
val original = julySeries()
val values = update(
original,
original.copy(timezone = "Asia/Tokyo"),
series,
"20260716T070000Z",
)
// The exclusion still reads 09:00 — now 09:00 in Tokyo (+9) == 00:00Z.
assertThat(values[CalendarContract.Events.EXDATE]).isEqualTo("20260716T000000Z")
}
@Test
fun `an all-day series move shifts its exclusions by whole days`() {
val series = instantAt("2026-07-01T00:00", "UTC")
val original = form(
isAllDay = true,
start = LocalDateTime(LocalDate(2026, 7, 15), LocalTime(0, 0)),
end = LocalDateTime(LocalDate(2026, 7, 15), LocalTime(0, 0)),
).copy(rrule = "FREQ=WEEKLY")
val moved = original.copy(
start = LocalDateTime(LocalDate(2026, 7, 17), LocalTime(0, 0)),
end = LocalDateTime(LocalDate(2026, 7, 17), LocalTime(0, 0)),
)
assertThat(update(original, moved, series, "20260722")[CalendarContract.Events.EXDATE])
.isEqualTo("20260724")
}
@Test
fun `switching a series to all-day rewrites its exclusions as dates`() {
// The two forms aren't interchangeable: a date-time stamp on an all-day
// series matches no occurrence, so the exclusion would be lost.
val series = instantAt("2026-07-01T09:00", "Europe/Berlin")
val original = julySeries()
val values = update(original, original.copy(isAllDay = true), series, "20260722T070000Z")
assertThat(values[CalendarContract.Events.EXDATE]).isEqualTo("20260722")
}
@Test
fun `switching a series back to timed rewrites its exclusions as instants`() {
val series = instantAt("2026-07-01T00:00", "UTC")
val original = form(
isAllDay = true,
start = LocalDateTime(LocalDate(2026, 7, 15), LocalTime(0, 0)),
end = LocalDateTime(LocalDate(2026, 7, 15), LocalTime(0, 0)),
).copy(rrule = "FREQ=WEEKLY")
val timed = original.copy(
isAllDay = false,
start = LocalDateTime(LocalDate(2026, 7, 15), LocalTime(9, 0)),
end = LocalDateTime(LocalDate(2026, 7, 15), LocalTime(10, 0)),
)
// The excluded day gains the new 09:00 Berlin time-of-day == 07:00Z.
assertThat(update(original, timed, series, "20260722")[CalendarContract.Events.EXDATE])
.isEqualTo("20260722T070000Z")
}
@Test
fun `a text-only edit leaves the exclusions alone`() {
val original = julySeries()
val values = update(original, original.copy(title = "Renamed"), exdate = "20260722T070000Z")
assertThat(values).doesNotContainKey(CalendarContract.Events.EXDATE)
}
@Test
fun `changing only the rule rewrites no exclusions`() {
// The times are untouched, so every surviving occurrence keeps its instant
// and the stamps still name the right ones.
val original = julySeries()
val values = update(original, original.copy(rrule = "FREQ=DAILY"), exdate = "20260722T070000Z")
assertThat(values[CalendarContract.Events.RRULE]).isEqualTo("FREQ=DAILY")
assertThat(values).doesNotContainKey(CalendarContract.Events.EXDATE)
}
@Test
fun `an exdate form we do not write is left untouched`() {
// A sync adapter may store a TZID-parameterised or floating stamp. A stale
// stamp excludes nothing; a mangled one could exclude the wrong occurrence.
val original = julySeries()
val values = update(
original,
original.atHour(10),
instantAt("2026-07-01T09:00", "Europe/Berlin"),
"TZID=Europe/Berlin;20260722T090000",
)
assertThat(values).doesNotContainKey(CalendarContract.Events.EXDATE)
}
@Test
fun `removing the recurrence clears the exclusions with it`() {
// Dormant, not harmless: adding a recurrence back later would punch the old
// holes into the new one.
val original = julySeries()
val values = update(original, original.copy(rrule = null), exdate = "20260722T070000Z")
assertThat(values).containsEntry(CalendarContract.Events.EXDATE, null)
}
@Test
fun `undoing a series move lands the exclusions back where they started`() {
val series = instantAt("2026-01-07T09:00", "Europe/Berlin")
val original = julySeries()
val moved = original.copy(
start = LocalDateTime(LocalDate(2026, 7, 17), LocalTime(14, 30)),
end = LocalDateTime(LocalDate(2026, 7, 17), LocalTime(15, 30)),
)
val exdate = "20260722T070000Z"
val forward = update(original, moved, series, exdate)
val movedExdate = forward[CalendarContract.Events.EXDATE] as String
assertThat(movedExdate).isNotEqualTo(exdate)
val back = update(
moved,
original,
forward[CalendarContract.Events.DTSTART] as Long,
movedExdate,
)
assertThat(back[CalendarContract.Events.EXDATE]).isEqualTo(exdate)
}
@Test
fun `a series with no exclusions writes no exdate column`() {
val series = instantAt("2026-07-01T09:00", "Europe/Berlin")
val original = julySeries()
assertThat(update(original, original.atHour(10), series, exdate = null))
.doesNotContainKey(CalendarContract.Events.EXDATE)
}
// --- exdateAfter (the exclusions a "this and following" split inherits) ---
@Test
fun `a split carries only the exclusions past the split point`() {
// The occurrence at the split point is the one being edited, so it exists
// by definition — a stale exclusion for it would swallow the edit whole.
assertThat(
exdateAfter(
existingExdate = "20260708T080000Z,20260715T080000Z,20260722T080000Z",
beginMillis = instantAt("2026-07-15T08:00", "UTC"),
isAllDay = false,
),
).isEqualTo("20260722T080000Z")
}
@Test
fun `a split carries nothing when every exclusion is behind it`() {
assertThat(
exdateAfter("20260708T080000Z", instantAt("2026-07-15T08:00", "UTC"), isAllDay = false),
).isNull()
assertThat(exdateAfter(null, 0L, isAllDay = false)).isNull()
}
@Test
fun `all-day exclusions split on their UTC date`() {
assertThat(
exdateAfter("20260708,20260722", instantAt("2026-07-15T00:00", "UTC"), isAllDay = true),
).isEqualTo("20260722")
}
@Test
fun `an unreadable exclusion carries nothing across a split`() {
assertThat(
exdateAfter(
"20260722T080000Z,TZID=Europe/Berlin;20260729T100000",
instantAt("2026-07-15T08:00", "UTC"),
isAllDay = false,
),
).isNull()
}
@Test
fun `split exclusions move by the same shift as the new series start`() {
// What the split path composes: filter to the tail, then re-time it by the
// shift the user applied to the occurrence they split at.
val original = julySeries()
val carried = shiftedExdate(
existingExdate = exdateAfter(
"20260716T070000Z",
instantAt("2026-07-15T07:00", "UTC"),
isAllDay = false,
),
original = original,
updated = original.atHour(11),
zone = berlin,
)
// 16 July 09:00 Berlin, pushed two hours, is 11:00 Berlin == 09:00Z.
assertThat(carried).isEqualTo("20260716T090000Z")
}
@Test
fun `nothing to shift yields no exdate`() {
assertThat(shiftedExdate(null, julySeries(), julySeries().atHour(10), berlin)).isNull()
assertThat(shiftedExdate(" ", julySeries(), julySeries().atHour(10), berlin)).isNull()
}
// --- per-event colour ---
@Test

View File

@@ -172,9 +172,12 @@ F-Droid but not Play:
Until those are fixed, Play's graphics are managed by hand in the console. Then
pass `images:true` to the `listing` lane.
**Track.** Uploads go to `internal` by default; promotion to production stays a
manual action in the Play Console, matching the rule that UI releases wait for
on-device review. Override with the `PLAY_TRACK` repo variable.
**Track.** Uploads go straight to `production` at a full rollout
(`PLAY_RELEASE_STATUS=completed`). The merge to `main` is already the human
gate — a release only gets there after on-device review — so a second manual
promotion in the Play Console added delay without adding a decision. Set the
`PLAY_TRACK` repo variable (e.g. `internal`) to stage a release instead, or
`PLAY_RELEASE_STATUS=draft` to hold it unpublished.
### Manual re-sign / recovery
@@ -233,7 +236,7 @@ Two consequences worth remembering:
| Variable | Default | Purpose |
| --- | --- | --- |
| `PLAY_TRACK` | `internal` | Play track the bundle is uploaded to. |
| `PLAY_TRACK` | `production` | Play track the bundle is uploaded to. Set to `internal`/`alpha`/`beta` to stage instead. |
| `PLAY_RELEASE_STATUS` | `completed` | `completed`, `draft`, `inProgress` or `halted`. |
| `PLAY_DRY_RUN` | `false` | `true` validates the Play edit against the API and discards it — use to rehearse. |

View File

@@ -29,7 +29,7 @@ platform :android do
supply(
aab: aab,
track: options[:track] || "internal",
track: options[:track] || "production",
release_status: options[:release_status] || "completed",
# The APK belongs to F-Droid and the Codeberg download; Play only ever

View File

@@ -5,16 +5,16 @@ ksp = "2.3.11"
hilt = "2.60.1"
coreKtx = "1.19.0"
appcompat = "1.7.1"
lifecycleRuntime = "2.10.0"
lifecycleRuntime = "2.11.0"
activityCompose = "1.13.0"
composeBom = "2026.06.01"
# Material 3 Expressive APIs currently live only in the 1.5 alpha line.
# Pin explicitly to override the BOM (which ships stable 1.4.0).
# Re-evaluate when 1.5.0 stable lands.
material3 = "1.5.0-alpha25"
material3 = "1.5.0-alpha26"
datastore = "1.2.1"
junit = "6.1.2"
junitPlatform = "6.1.2"
junit = "6.1.3"
junitPlatform = "6.1.3"
truth = "1.4.5"
androidxJunit = "1.3.0"
espressoCore = "3.7.0"
@@ -26,7 +26,7 @@ lifecycleCompose = "2.10.0"
androidxTestRules = "1.7.0"
# Glance: 1.1.1 is the latest stable (1.2.0 is still rc, 1.3.0 alpha).
glance = "1.1.1"
work = "2.10.1"
work = "2.11.2"
documentfile = "1.1.0"
[libraries]