From 83a77c1bb0c9026ca43730b1333375a94bf9069f Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Thu, 22 Oct 2026 11:20:39 +0200 Subject: [PATCH] fix(settings): name the bundled sound in the default-sound rows Picking "Timer expired" as the default alarm or timer sound showed "Custom" in Settings, because the summary knew only the device default and silence. It now names the bundled sound, as the editors already do. ARCHITECTURE.md now names the exact bundled sentinel instead of a prefix the code does not recognise, lists clockula://media values in the alarm column, gives the timer column the same values, and says RingtoneCatalog lists the bundled sounds too. Refs #14 --- .../jeanlucmakiola/clockula/ui/settings/SettingsScreen.kt | 1 + docs/ARCHITECTURE.md | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsScreen.kt b/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsScreen.kt index eaeda0d..9ed7680 100644 --- a/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsScreen.kt +++ b/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsScreen.kt @@ -385,5 +385,6 @@ private fun selfCheckSummary(problemCount: Int?): String = when { internal fun ringtoneSummary(uri: String?): String = when { uri == null -> stringResource(R.string.ringtone_device_default) Ringtones.isSilent(uri) -> stringResource(R.string.ringtone_silent) + Ringtones.isBundled(uri) -> stringResource(R.string.ringtone_timer_expired) else -> stringResource(R.string.settings_ringtone_custom) } diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 192ed48..294e9b0 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -106,7 +106,7 @@ kit module: the kit's roadmap keeps schedulers app-local. | `data/zones/` | the ICU seam (M8): `ZoneNames`, `IcuZoneNames` (the only `android.icu` file in the app) and `ZoneDirectory`, the locale-keyed catalog cache and the DST-keyed display-name memo | | `data/stopwatch/` | `LapEntity`, `LapDao` (one `COUNT(*)` added in M7), `LapMapper`, `StopwatchStateStore`, `StopwatchRepository(+Impl)` | | `data/prefs/` | `SettingsPrefs`, `ClockPrefs`, `StopwatchPrefs`, `TimerPrefs`, `UiPrefs` | -| `data/ringtones/` | the two ringtone seams, `RingtoneCatalog` (the device's alarm sounds, titles, playability, a SAF grant) and `RingtonePreviewer`, plus their `System*` implementations, and `MediaLibrary`/`SystemMediaLibrary`, the picker's view of other apps' `MediaBrowserService` libraries | +| `data/ringtones/` | the two ringtone seams, `RingtoneCatalog` (the bundled and device alarm sounds, titles, playability, a SAF grant) and `RingtonePreviewer`, plus their `System*` implementations, and `MediaLibrary`/`SystemMediaLibrary`, the picker's view of other apps' `MediaBrowserService` libraries | | `data/time/` | `SystemWallClock`, `SystemElapsedRealtimeClock`, `SystemZoneProvider`, `AndroidBootIdProvider`, `RealTicker` | | `data/di/` | `DataModule`, `DatabaseModule`, `RepositoryModule`, `TimeModule`, `RingtoneModule`, `ZoneModule` (M8; one `@Binds`, `ZoneNames → IcuZoneNames`), `BackupModule` (M10) | | `data/backup/` | the backup's data-layer half (M10): `BackupDto`/`BackupCodec` (the pure JSON wire format, `ignoreUnknownKeys`, strict on known fields), `BackupDao` (one `@Transaction` replace-all over alarms/timers/world clocks; no schema or version change), `BackupRepository(+Impl)`, mapping through the existing `AlarmMapper`/`TimerMapper`/`WorldClockMapper`, never a second copy | @@ -167,7 +167,7 @@ JSON and M10's JSON backup all read the same vocabulary in a diff. | `enabled` | INTEGER | indexed; `enabled()` filters on it | | `repeat_days` | INTEGER | 7-bit mask, see below | | `skip_next_occurrence` | INTEGER | | -| `ringtone_uri`, `vibrate`, `snooze_minutes`, `snooze_limit`, `volume_ramp_seconds`, `dismiss_challenge` | nullable | **overrides**; `NULL` = inherit `ClockDefaults`. For `ringtone_uri`: `NULL` = inherit, `clockula://silent` = deliberate silence (§13), `clockula://tone/…` = a sound bundled in the APK (resolved by `BundledTones`, never `Uri.parse`d directly), anything else a content URI | +| `ringtone_uri`, `vibrate`, `snooze_minutes`, `snooze_limit`, `volume_ramp_seconds`, `dismiss_challenge` | nullable | **overrides**; `NULL` = inherit `ClockDefaults`. For `ringtone_uri`: `NULL` = inherit, `clockula://silent` = deliberate silence (§13), `clockula://tone/timer_expired` = the sound bundled in the APK (resolved by `BundledTones`, never `Uri.parse`d directly), `clockula://media?…` = another app's track (§13), anything else a content URI | | `delete_after_use` | INTEGER | v3 (M9): a transient alarm the `AlarmClock` contract asked for. Deleted rather than disabled when its cycle closes (§17) | | `created_at`, `updated_at` | INTEGER | wall-clock epoch millis | @@ -270,7 +270,7 @@ occurrence, so skipping it is dismissing it in advance. | `started_at_elapsed_realtime_millis` | INTEGER? | `RUNNING` only | | `ends_at_elapsed_realtime_millis` | INTEGER? | `RUNNING` only; **authoritative** | | `ends_at_wall_clock_millis` | INTEGER? | `RUNNING` only; **post-reboot fallback only** | -| `ringtone_uri` | TEXT? | `NULL` = inherit `ClockDefaults.timerRingtoneUri` | +| `ringtone_uri` | TEXT? | `NULL` = inherit `ClockDefaults.timerRingtoneUri`; otherwise the same values as the alarm's `ringtone_uri` | | `sort_order` | INTEGER | indexed | | `delete_after_use` | INTEGER | v3 (M9): a transient timer the contract asked for. Deleted rather than returned to IDLE when it is dismissed (§17) | | `created_at`, `updated_at` | INTEGER | wall-clock epoch millis |