feat(ics): export — share single event + back up local calendars as .ics
Branch 1 of 2 for v2.7 (the .ics topic). Adds the write side of a hand-rolled RFC 5545 engine (zero deps, stays on kotlinx-datetime): - domain/ics: IcsText (escape + 75-octet folding), IcsEvent model, IcsWriter.writeCalendar. Timezone rule: all-day VALUE=DATE, one-off timed UTC Z, recurring timed TZID-labelled from EVENT_TIMEZONE (no VTIMEZONE — import resolves TZID against the OS tz db). - Single-event share from the detail screen (FileProvider + ACTION_SEND). - Whole-calendar backup of the writable local calendars to a SAF file (Settings -> Calendars -> Export as .ics), one combined VCALENDAR. - insertEvent now writes Events.UID_2445; legacy rows fall back to a stable synthesised UID at export time so a later restore won't dupe. - EXDATE / RECURRENCE-ID overrides are deliberately skipped this pass (documented v1 limit; import will skip them too). Engine + mapper unit-tested. Import (Branch 2, feat/ics-import) ships in the same v2.7 release; no tag until both land + on-device review. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -47,6 +47,9 @@
|
||||
<string name="event_detail_back">Zurück</string>
|
||||
<string name="event_detail_edit">Bearbeiten</string>
|
||||
<string name="event_detail_delete">Löschen</string>
|
||||
<string name="event_detail_share">Teilen</string>
|
||||
<string name="event_share_chooser_title">Termin teilen</string>
|
||||
<string name="event_share_failed">Termin konnte nicht geteilt werden.</string>
|
||||
<string name="event_delete_title">Termin löschen?</string>
|
||||
<string name="event_delete_body">Der Termin wird aus deinem Kalender und von allen synchronisierten Geräten entfernt.</string>
|
||||
<string name="event_delete_recurring_title">Wiederkehrenden Termin löschen</string>
|
||||
@@ -297,4 +300,13 @@
|
||||
<string name="calendars_delete_confirm_title">Kalender löschen?</string>
|
||||
<string name="calendars_delete_confirm_message">\"%1$s\" und alle zugehörigen Termine werden dauerhaft von diesem Gerät entfernt.</string>
|
||||
<string name="calendars_write_error">Änderung konnte nicht gespeichert werden.</string>
|
||||
<!-- Backup (whole-calendar .ics export) -->
|
||||
<string name="calendars_backup_header">Sicherung</string>
|
||||
<string name="calendars_backup_hint">Lokale Kalender werden nirgends synchronisiert – exportiere sie als .ics-Datei, um eine Kopie zu behalten.</string>
|
||||
<string name="calendars_backup_action">Als .ics-Datei exportieren</string>
|
||||
<string name="calendars_backup_failed">Sicherung konnte nicht exportiert werden.</string>
|
||||
<plurals name="calendars_backup_done">
|
||||
<item quantity="one">%d Termin exportiert.</item>
|
||||
<item quantity="other">%d Termine exportiert.</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
<string name="event_detail_back">Back</string>
|
||||
<string name="event_detail_edit">Edit</string>
|
||||
<string name="event_detail_delete">Delete</string>
|
||||
<string name="event_detail_share">Share</string>
|
||||
<string name="event_share_chooser_title">Share event</string>
|
||||
<string name="event_share_failed">Couldn\'t share this event.</string>
|
||||
<string name="event_delete_title">Delete event?</string>
|
||||
<string name="event_delete_body">The event is removed from your calendar and from every device it syncs to.</string>
|
||||
<string name="event_delete_recurring_title">Delete recurring event</string>
|
||||
@@ -294,6 +297,15 @@
|
||||
<string name="calendars_delete_confirm_title">Delete calendar?</string>
|
||||
<string name="calendars_delete_confirm_message">\"%1$s\" and all of its events will be permanently removed from this device.</string>
|
||||
<string name="calendars_write_error">Couldn\'t save the change.</string>
|
||||
<!-- Backup (whole-calendar .ics export) -->
|
||||
<string name="calendars_backup_header">Backup</string>
|
||||
<string name="calendars_backup_hint">Local calendars aren\'t synced anywhere, so export them to an .ics file to keep a copy.</string>
|
||||
<string name="calendars_backup_action">Export as .ics file</string>
|
||||
<string name="calendars_backup_failed">Couldn\'t export the backup.</string>
|
||||
<plurals name="calendars_backup_done">
|
||||
<item quantity="one">Exported %d event.</item>
|
||||
<item quantity="other">Exported %d events.</item>
|
||||
</plurals>
|
||||
<!-- Launcher long-press shortcuts -->
|
||||
<string name="shortcut_new_event_short">New event</string>
|
||||
<string name="shortcut_new_event_long">Create a new event</string>
|
||||
|
||||
7
app/src/main/res/xml/file_paths.xml
Normal file
7
app/src/main/res/xml/file_paths.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Exposes the cache subdirectory where IcsExporter stages files for sharing. -->
|
||||
<paths>
|
||||
<cache-path
|
||||
name="shared_ics"
|
||||
path="shared_ics/" />
|
||||
</paths>
|
||||
Reference in New Issue
Block a user