fix: translate the call timer, and stop folding hours into its minutes field

The call timer's formatDuration had a different problem from the workout one —
no English words, just "%02d:%02d" — but two real ones underneath.

A call past an hour rendered as "65:12": hours were folded into the minutes
field rather than shown. It now switches to a three-field form at an hour and
keeps the two-field form below it, so a five-minute call still reads "05:23"
rather than the "00:05:23" that reusing DurationTag.formatTime would have
given.

The pattern moves into string resources. The separator and field order belong
to the translator, and String.format without an explicit locale follows the
JVM-wide default rather than the locale Compose is configured with — not the
same thing in an app that ships its own language picker, where the two can
disagree on digit shaping.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019egdJyBHnrATZHjs86up8f
This commit is contained in:
Claude
2026-09-17 16:18:19 +00:00
parent 623faa87e8
commit b3b1844a67
2 changed files with 27 additions and 2 deletions
@@ -50,6 +50,8 @@ import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import com.vitorpamplona.amethyst.commons.resources.Res
import com.vitorpamplona.amethyst.commons.resources.call_calling
import com.vitorpamplona.amethyst.commons.resources.call_duration_hours_minutes_seconds
import com.vitorpamplona.amethyst.commons.resources.call_duration_minutes_seconds
import com.vitorpamplona.amethyst.ui.note.BaseUserPicture
import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
@@ -400,10 +402,28 @@ fun GroupCallNames(
}
}
/**
* Elapsed call time as a clock: `05:23`, and `1:05:23` once the call passes an hour.
*
* Hours are not folded into the minutes field — the previous version rendered a 65-minute call
* as "65:12".
*
* The pattern comes from a string resource rather than a literal so the separator and field
* order stay the translator's, and so the numbers are formatted with the locale Compose is
* configured with. `String.format` without an explicit locale follows the JVM-wide default,
* which is not the same thing in an app that has its own language picker.
*/
@Composable
fun formatDuration(seconds: Long): String {
val mins = seconds / 60
val hours = seconds / 3600
val mins = (seconds % 3600) / 60
val secs = seconds % 60
return "%02d:%02d".format(mins, secs)
return if (hours > 0) {
stringRes(Res.string.call_duration_hours_minutes_seconds, hours, mins, secs)
} else {
stringRes(Res.string.call_duration_minutes_seconds, mins, secs)
}
}
@Composable
@@ -1296,6 +1296,11 @@
<string name="call_calling">Calling\u2026</string>
<string name="call_connecting">Connecting\u2026</string>
<string name="call_ended">Call ended</string>
<!-- Elapsed call time. %1$d is minutes and %2$d seconds in the short form; in the long
form %1$d is hours, %2$d minutes and %3$d seconds. Separator and field order are the
translator's to change. -->
<string name="call_duration_minutes_seconds">%1$02d:%2$02d</string>
<string name="call_duration_hours_minutes_seconds">%1$d:%2$02d:%3$02d</string>
<string name="call_dismiss">Dismiss</string>
<string name="call_switch_camera">Switch camera</string>
<string name="call_voice">Voice call</string>