Capture uncaught exceptions on-device and let the user submit them, by hand, as a Gitea issue — no network access, no auto-upload (the app holds no INTERNET permission). Closes prod-readiness item 10; the issue templates also close item 7. - CrashReporter: uncaught-exception handler installed first in CalendulaApp.onCreate so startup crashes are caught too. Persists an allowlist-only report (app/Android/device version, locale, time, stack trace — nothing else) to filesDir/crash, then chains to the previous handler so the process still dies normally. Crash-loop detection + markHealthy reset. - buildCrashReport is pure/testable; CrashReportBuilderTest asserts the header is exactly the allowlisted lines (guards against PII creep). - Surfacing: next-launch dialog showing the full report verbatim (the privacy backstop) with a dismissed-marker so it doesn't nag; a Settings "Report a problem" row; and a minimal standalone CrashReportActivity that MainActivity routes to on a startup crash-loop, kept clear of the Hilt graph / DataStore theme. - submitCrashReport copies the report to the clipboard and opens the prefilled Gitea issues/new URL (long traces fall back to paste). - .gitea/ISSUE_TEMPLATE: crash_report, bug_report, feature_request. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
361 lines
23 KiB
XML
361 lines
23 KiB
XML
<resources>
|
|
<string name="app_name">Calendula</string>
|
|
<string name="app_tagline">A modern calendar.</string>
|
|
|
|
<!-- Loading / Failure / Success generic strings (used across screens) -->
|
|
<string name="state_loading">Loading…</string>
|
|
<string name="state_retry">Retry</string>
|
|
<string name="state_failure_unknown">Something went wrong.</string>
|
|
<string name="state_failure_permission">Calendar access is required.</string>
|
|
<string name="state_failure_permission_action">Grant access</string>
|
|
<string name="state_failure_no_calendars">No calendars configured.</string>
|
|
<string name="state_failure_no_calendars_action">Open system calendar settings</string>
|
|
<string name="state_failure_provider">Could not read the calendar.</string>
|
|
|
|
<!-- Permission flow (F1) -->
|
|
<string name="permission_rationale_title">See all your events, beautifully</string>
|
|
<string name="permission_rationale_body">Calendula needs access to your calendar to show and manage your events. That\'s the only thing it ever asks for.</string>
|
|
<string name="permission_request_button">Grant calendar access</string>
|
|
<string name="permission_denied_title">Calendar access denied</string>
|
|
<string name="permission_denied_body">Calendula cannot show events without calendar access. You can grant it again in the system settings.</string>
|
|
<string name="permission_open_settings_button">Open system settings</string>
|
|
<string name="permission_retry_button">Try again</string>
|
|
<string name="permission_benefit_private_title">Stays on your device</string>
|
|
<string name="permission_benefit_private_body">Your calendars are read locally and never leave the phone.</string>
|
|
<string name="permission_benefit_sync_title">All your calendars, together</string>
|
|
<string name="permission_benefit_sync_body">Google, CalDAV, local — anything synced to the device just appears.</string>
|
|
<string name="permission_benefit_privacy_title">No tracking, ever</string>
|
|
<string name="permission_benefit_privacy_body">Zero telemetry, zero analytics, no ads.</string>
|
|
<string name="permission_privacy_footnote">Stays on your device · no internet permission</string>
|
|
|
|
<!-- Month view (S1) -->
|
|
<string name="month_prev">Previous month</string>
|
|
<string name="month_next">Next month</string>
|
|
<string name="month_today_action">Today</string>
|
|
<string name="month_more_actions">More actions</string>
|
|
<string name="month_open_menu">Open menu</string>
|
|
<string name="month_action_settings">Settings</string>
|
|
<string name="month_a11y_today_prefix">Today</string>
|
|
|
|
<!-- Week view (S2) -->
|
|
<string name="week_today_action">This week</string>
|
|
<string name="week_number_label">Wk</string>
|
|
|
|
<!-- Day view (S3) -->
|
|
<string name="day_today_action">Today</string>
|
|
|
|
<!-- Event detail screen (S4) -->
|
|
<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>
|
|
<string name="event_delete_option_occurrence">Only this event</string>
|
|
<string name="event_delete_option_following">This and all following events</string>
|
|
<string name="event_delete_option_series">All events in the series</string>
|
|
<string name="event_edit_recurring_title">Edit recurring event</string>
|
|
<string name="event_delete_failed">Couldn\'t delete the event</string>
|
|
<string name="event_delete_write_denied">Calendula needs write access to delete events</string>
|
|
<string name="dialog_cancel">Cancel</string>
|
|
<string name="dialog_ok">OK</string>
|
|
|
|
<!-- Event form (v1.2 create) -->
|
|
<string name="event_edit_new_title">New event</string>
|
|
<string name="event_edit_close">Close</string>
|
|
<string name="event_edit_save">Save</string>
|
|
<string name="event_edit_title_hint">Add title</string>
|
|
<string name="event_edit_starts">Starts</string>
|
|
<string name="event_edit_ends">Ends</string>
|
|
<string name="event_edit_error_end_before_start">Ends before it starts</string>
|
|
<string name="event_edit_error_no_calendar">No writable calendar available</string>
|
|
<string name="event_edit_save_failed">Couldn\'t save the event</string>
|
|
<string name="event_edit_write_denied">Calendula needs write access to create events</string>
|
|
<string name="event_edit_more_fields">More fields</string>
|
|
<string name="event_edit_add">Add</string>
|
|
<string name="event_edit_add_reminder">Add reminder</string>
|
|
<string name="event_edit_remove_reminder">Remove reminder</string>
|
|
<string name="event_edit_reminder_custom">Custom</string>
|
|
<string name="reminder_unit_minutes">minutes</string>
|
|
<string name="reminder_unit_hours">hours</string>
|
|
<string name="reminder_unit_days">days</string>
|
|
<string name="reminder_unit_weeks">weeks</string>
|
|
<string name="event_edit_availability">Availability</string>
|
|
<string name="event_edit_visibility">Visibility</string>
|
|
|
|
<!-- Event form — per-event color -->
|
|
<string name="event_edit_color">Color</string>
|
|
<string name="event_edit_color_default">Calendar color</string>
|
|
<string name="event_edit_color_custom">Custom color</string>
|
|
<string name="event_edit_color_reset">Reset</string>
|
|
<string name="event_edit_color_unsupported">Not available for this calendar</string>
|
|
<string name="event_edit_color_unsupported_hint">This calendar publishes no color set. You can allow custom colors for such calendars in Settings.</string>
|
|
<string name="event_edit_color_sync_warning">This calendar may drop or overwrite the color on its next sync.</string>
|
|
|
|
<!-- Event form — save conflict (v2.0) -->
|
|
<string name="event_edit_conflict_title">Event changed elsewhere</string>
|
|
<string name="event_edit_conflict_body">While you were editing, this event was changed — by sync or another app. What should happen to your changes?</string>
|
|
<string name="event_edit_conflict_overwrite">Save my changes</string>
|
|
<string name="event_edit_conflict_overwrite_hint">Only fields you edited overwrite the outside change</string>
|
|
<string name="event_edit_conflict_discard">Discard my changes</string>
|
|
<string name="event_edit_conflict_discard_hint">The event stays as it is now</string>
|
|
<string name="event_edit_gone_title">Event deleted</string>
|
|
<string name="event_edit_gone_body">This event was deleted in the meantime, for example on another device. Your changes can no longer be saved.</string>
|
|
|
|
<!-- Event form — recurrence picker (v1.3) -->
|
|
<string name="event_edit_recurrence_none">Does not repeat</string>
|
|
<string name="event_edit_recurrence_custom">Custom</string>
|
|
<string name="event_edit_recurrence_every">Every</string>
|
|
<string name="recurrence_unit_days">days</string>
|
|
<string name="recurrence_unit_weeks">weeks</string>
|
|
<string name="recurrence_unit_months">months</string>
|
|
<string name="recurrence_unit_years">years</string>
|
|
<string name="event_edit_recurrence_ends">Ends</string>
|
|
<string name="event_edit_recurrence_end_never">Never</string>
|
|
<string name="event_edit_recurrence_end_until">On a date</string>
|
|
<string name="event_edit_recurrence_end_count">After a number of times</string>
|
|
<string name="event_edit_recurrence_times">times</string>
|
|
<string name="event_edit_error_recurrence_ends_before_start">Repeats end before the event starts</string>
|
|
<string name="event_availability_busy">Busy</string>
|
|
<string name="event_access_default">Default</string>
|
|
<string name="event_access_public">Public</string>
|
|
<string name="event_detail_all_day">All day</string>
|
|
<string name="event_detail_calendar">Calendar</string>
|
|
<string name="event_detail_calendar_unknown">Unknown calendar</string>
|
|
<string name="event_detail_location">Location</string>
|
|
<string name="event_detail_description">Description</string>
|
|
<string name="event_detail_attendees">Attendees</string>
|
|
<string name="event_detail_recurrence">Recurrence</string>
|
|
<string name="event_detail_recurring">Repeating event</string>
|
|
<string name="recurrence_daily">Every day</string>
|
|
<string name="recurrence_weekly">Every week</string>
|
|
<string name="recurrence_monthly">Every month</string>
|
|
<string name="recurrence_yearly">Every year</string>
|
|
<string name="recurrence_every_n_days">Every %1$d days</string>
|
|
<string name="recurrence_every_n_weeks">Every %1$d weeks</string>
|
|
<string name="recurrence_every_n_months">Every %1$d months</string>
|
|
<string name="recurrence_every_n_years">Every %1$d years</string>
|
|
<string name="recurrence_on_days">%1$s on %2$s</string>
|
|
<string name="recurrence_with_until">%1$s until %2$s</string>
|
|
<string name="recurrence_with_count">%1$s, %2$d times</string>
|
|
<string name="event_detail_not_found">This event no longer exists.</string>
|
|
<string name="event_attendee_accepted">Accepted</string>
|
|
<string name="event_attendee_declined">Declined</string>
|
|
<string name="event_attendee_tentative">Tentative</string>
|
|
<string name="event_attendee_needs_action">No response</string>
|
|
<string name="event_attendee_unknown">—</string>
|
|
|
|
<!-- Event detail — full read (v0.6) -->
|
|
<string name="event_detail_reminders">Reminders</string>
|
|
<string name="event_detail_timezone">Time zone</string>
|
|
<string name="event_status_tentative">Tentative</string>
|
|
<string name="event_status_cancelled">Cancelled</string>
|
|
<string name="event_availability_free">Free</string>
|
|
<string name="event_access_private">Private</string>
|
|
<string name="event_access_confidential">Confidential</string>
|
|
<string name="event_attendee_organizer">Organizer</string>
|
|
<string name="event_attendee_optional">Optional</string>
|
|
<string name="event_attendee_resource">Resource</string>
|
|
<string name="event_detail_self_response">Your response: %1$s</string>
|
|
<string name="reminder_at_time">At time of event</string>
|
|
<string name="reminder_default">Default reminder</string>
|
|
<plurals name="reminder_minutes">
|
|
<item quantity="one">%d minute before</item>
|
|
<item quantity="other">%d minutes before</item>
|
|
</plurals>
|
|
<plurals name="reminder_hours">
|
|
<item quantity="one">%d hour before</item>
|
|
<item quantity="other">%d hours before</item>
|
|
</plurals>
|
|
<plurals name="reminder_days">
|
|
<item quantity="one">%d day before</item>
|
|
<item quantity="other">%d days before</item>
|
|
</plurals>
|
|
<plurals name="reminder_weeks">
|
|
<item quantity="one">%d week before</item>
|
|
<item quantity="other">%d weeks before</item>
|
|
</plurals>
|
|
|
|
<!-- Shared event strings -->
|
|
<string name="event_untitled">(No title)</string>
|
|
|
|
<!-- Reminder notifications (v1.4) -->
|
|
<string name="reminder_channel_name">Event reminders</string>
|
|
<string name="reminder_channel_description">Notifications at the reminder times of your events</string>
|
|
<string name="reminder_onboarding_title">Never miss an event</string>
|
|
<string name="reminder_onboarding_body">Android doesn\'t show event reminders by itself — a calendar app has to. Let Calendula take that job.</string>
|
|
<string name="reminder_benefit_delivery_title">Reminders, delivered</string>
|
|
<string name="reminder_benefit_delivery_body">Every reminder on your events arrives as a notification, right on time.</string>
|
|
<string name="reminder_benefit_duplicates_title">Using a second calendar app?</string>
|
|
<string name="reminder_benefit_duplicates_body">If another app also posts reminders, you\'ll see them twice — turn them off there or here.</string>
|
|
<string name="reminder_benefit_reversible_title">Change it anytime</string>
|
|
<string name="reminder_benefit_reversible_body">The switch lives in Settings, under Notifications.</string>
|
|
<string name="reminder_onboarding_enable_button">Turn on reminders</string>
|
|
<string name="reminder_onboarding_skip_button">Not now</string>
|
|
|
|
<!-- View switcher (M1) -->
|
|
<string name="view_month">Month</string>
|
|
<string name="view_week">Week</string>
|
|
<string name="view_day">Day</string>
|
|
<string name="view_agenda">Agenda</string>
|
|
<string name="view_section">View</string>
|
|
|
|
<!-- Jump to date (drawer) -->
|
|
<string name="drawer_jump_to_date">Jump to date</string>
|
|
|
|
<!-- Agenda view -->
|
|
<string name="agenda_today_action">Today</string>
|
|
<string name="agenda_header_today">Today</string>
|
|
<string name="agenda_header_tomorrow">Tomorrow</string>
|
|
<string name="agenda_empty_title">Nothing scheduled</string>
|
|
<string name="agenda_empty_subtitle">Upcoming events will show up here.</string>
|
|
|
|
<!-- Home-screen widgets -->
|
|
<string name="widget_agenda_title">Upcoming</string>
|
|
<string name="widget_agenda_label">Calendula agenda</string>
|
|
<string name="widget_month_label">Calendula month</string>
|
|
<string name="widget_refresh">Refresh</string>
|
|
<string name="widget_new_event">New event</string>
|
|
<string name="widget_needs_permission">Open Calendula to grant calendar access</string>
|
|
<string name="widget_prev_month">Previous month</string>
|
|
<string name="widget_next_month">Next month</string>
|
|
<string name="widget_today">Today</string>
|
|
|
|
<!-- Calendar filter (M3) -->
|
|
<string name="filter_title">Calendars</string>
|
|
|
|
<!-- Settings (M4) -->
|
|
<string name="settings_title">Settings</string>
|
|
<string name="settings_back">Back</string>
|
|
<string name="settings_section_appearance">Appearance</string>
|
|
<string name="settings_theme">Theme</string>
|
|
<string name="settings_theme_system">System</string>
|
|
<string name="settings_theme_light">Light</string>
|
|
<string name="settings_theme_dark">Dark</string>
|
|
<string name="settings_dynamic_color">Dynamic colour</string>
|
|
<string name="settings_dynamic_color_unavailable">Requires Android 12 or newer</string>
|
|
<string name="settings_week_start">Week starts on</string>
|
|
<string name="settings_week_start_auto">Automatic</string>
|
|
<string name="settings_week_start_monday">Monday</string>
|
|
<string name="settings_week_start_sunday">Sunday</string>
|
|
<string name="settings_section_event_form">New event form</string>
|
|
<string name="settings_form_fields_hint">Fields shown by default — everything else sits behind \"More fields\"</string>
|
|
<string name="settings_color_unsupported">Allow colors on unsupported calendars</string>
|
|
<string name="settings_color_unsupported_hint">Some calendars (e.g. certain CalDAV) publish no color set; a custom event color may be dropped or overwritten on their next sync. That\'s a limitation of those calendars, not something Calendula can fix.</string>
|
|
<string name="settings_section_notifications">Notifications</string>
|
|
<string name="settings_reminders">Event reminders</string>
|
|
<string name="settings_reminders_hint">Seeing reminders twice? Another calendar app is posting them too — turn them off in one of the two.</string>
|
|
<string name="settings_default_reminder">Default reminder</string>
|
|
<string name="settings_default_reminder_allday">All-day events</string>
|
|
<string name="settings_allday_reminder_time">All-day reminder time</string>
|
|
<string name="settings_allday_reminder_time_hint">Reminders for all-day events fire at %1$s</string>
|
|
<string name="reminder_none">None</string>
|
|
<string name="reminder_use_default">Use default reminder</string>
|
|
<string name="reminder_custom_amount">Amount</string>
|
|
<string name="reminder_custom_with_value">Custom (%1$s)</string>
|
|
<string name="reminder_custom_set">Set</string>
|
|
<string name="settings_calendar_reminders_hint">Override the default per calendar — separately for timed and all-day events. A calendar can keep the default, drop it, or set its own.</string>
|
|
<string name="settings_calendar_reminder_inherits">Default (%1$s)</string>
|
|
<string name="settings_reliable_delivery">Reliable delivery</string>
|
|
<string name="settings_reliable_delivery_hint">Android may delay reminders to save battery. Exempt Calendula so they arrive on time.</string>
|
|
<string name="settings_reliable_delivery_exempt">Exempt from battery optimisation — reminders arrive on time.</string>
|
|
<string name="settings_section_calendars">Calendars</string>
|
|
<string name="settings_manage_calendars">Manage calendars</string>
|
|
<string name="settings_manage_calendars_hint">Create local calendars; manage synced ones</string>
|
|
<string name="settings_section_language">Language</string>
|
|
<string name="settings_language">App language</string>
|
|
<string name="settings_language_auto">System default</string>
|
|
<!-- Hub category subtitles -->
|
|
<string name="settings_appearance_subtitle">Theme, dynamic colour, week start</string>
|
|
<string name="settings_event_form_subtitle">Default fields for new events</string>
|
|
<string name="settings_notifications_subtitle">Event reminders</string>
|
|
<string name="settings_section_about">About</string>
|
|
<string name="settings_license">License</string>
|
|
<string name="settings_license_value">MIT</string>
|
|
<string name="settings_about_author">by Jean-Luc Makiola</string>
|
|
<string name="settings_about_source">Source</string>
|
|
<string name="settings_about_version">Version %1$s</string>
|
|
<string name="settings_about_logo_desc">Calendula app icon</string>
|
|
<string name="settings_report_problem">Report a problem</string>
|
|
<string name="settings_report_problem_hint">Send a crash report or open the issue tracker</string>
|
|
|
|
<!-- Calendar manager -->
|
|
<string name="calendars_title">Calendars</string>
|
|
<string name="calendars_local_header">Your calendars</string>
|
|
<string name="calendars_local_empty">No local calendars yet. Create one to keep events on this device only.</string>
|
|
<string name="calendars_add">Add calendar</string>
|
|
<string name="calendars_synced_header">Synced calendars</string>
|
|
<string name="calendars_synced_hint">These come from accounts on your device. Create and edit them in their own app.</string>
|
|
<string name="calendars_manage_in_app">Manage</string>
|
|
<string name="calendars_add_account">Add account</string>
|
|
<string name="calendars_new_title">New calendar</string>
|
|
<string name="calendars_edit_title">Edit calendar</string>
|
|
<string name="calendars_name_label">Name</string>
|
|
<string name="calendars_color_label">Color</string>
|
|
<string name="calendars_description_hint">Add a description</string>
|
|
<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>
|
|
<!-- Import (.ics) -->
|
|
<string name="import_title">Import events</string>
|
|
<string name="import_target_header">Add to calendar</string>
|
|
<string name="import_empty">No events found in this file.</string>
|
|
<string name="import_failed">Couldn\'t read this file.</string>
|
|
<string name="import_no_calendar">No writable calendar to import into. Create a local calendar first.</string>
|
|
<string name="import_done_title">Import complete</string>
|
|
<string name="import_close">Close</string>
|
|
<string name="import_warning_recurrence">Some changed occurrences of recurring events were skipped.</string>
|
|
<string name="import_warning_no_start">An event without a start time was skipped.</string>
|
|
<string name="import_warning_attendees">Guest lists weren\'t imported.</string>
|
|
<string name="import_warning_timezone">An unknown time zone fell back to your device\'s.</string>
|
|
<plurals name="import_event_count">
|
|
<item quantity="one">%d event in this file.</item>
|
|
<item quantity="other">%d events in this file.</item>
|
|
</plurals>
|
|
<plurals name="import_action">
|
|
<item quantity="one">Import %d event</item>
|
|
<item quantity="other">Import %d events</item>
|
|
</plurals>
|
|
<plurals name="import_done_imported">
|
|
<item quantity="one">Imported %d event.</item>
|
|
<item quantity="other">Imported %d events.</item>
|
|
</plurals>
|
|
<plurals name="import_done_skipped">
|
|
<item quantity="one">Skipped %d already in this calendar.</item>
|
|
<item quantity="other">Skipped %d already in this calendar.</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>
|
|
|
|
<string name="about_source_url" translatable="false">https://gitea.jeanlucmakiola.de/makiolaj/calendula</string>
|
|
<string name="about_license_url" translatable="false">https://gitea.jeanlucmakiola.de/makiolaj/calendula/src/branch/main/LICENSE</string>
|
|
|
|
<!-- Crash reporting: a captured report the user can submit, by hand, as a
|
|
Gitea issue (the app sends nothing automatically). -->
|
|
<string name="crash_dialog_title">Calendula crashed</string>
|
|
<string name="crash_dialog_message">Calendula closed unexpectedly last time. You can help fix it by sending this report as an issue. It stays on your device until you choose to share it, and includes no personal data or calendar content — only the technical details below.</string>
|
|
<string name="crash_dialog_report">Report</string>
|
|
<string name="crash_dialog_dismiss">Not now</string>
|
|
<string name="crash_report_issue_title">Crash report</string>
|
|
<string name="crash_report_clip_label">Calendula crash report</string>
|
|
<string name="crash_report_copied">Report copied to your clipboard</string>
|
|
<string name="crash_report_open_failed">Couldn\'t open the issue tracker. The report is on your clipboard.</string>
|
|
<string name="crash_report_body_template">Thanks for reporting a crash in Calendula. Please add anything you remember about what you were doing, then submit.\n\n### What happened\n\n\n### Crash report\n%1$s\n</string>
|
|
<string name="crash_report_body_paste">_(The report was too long for this link — paste it from your clipboard here.)_</string>
|
|
<string name="report_issue_url" translatable="false">https://gitea.jeanlucmakiola.de/makiolaj/calendula/issues/new</string>
|
|
<string name="report_issue_choose_url" translatable="false">https://gitea.jeanlucmakiola.de/makiolaj/calendula/issues/new/choose</string>
|
|
</resources>
|