diff --git a/.gemini/styleguide.md b/.gemini/styleguide.md index 3a5b03c4a..4c77a52be 100644 --- a/.gemini/styleguide.md +++ b/.gemini/styleguide.md @@ -31,6 +31,7 @@ When reviewing a pull request, focus on the following key areas: * Analyze camera configurations and use cases for potential performance bottlenecks. * Ensure coroutines and asynchronous operations are used efficiently. * **State Conflation in Adapters:** High-frequency stream data (e.g., nanosecond timestamps) should be rounded or conflated at the `UiStateAdapter` level before reaching the UI state, to avoid unnecessary recompositions. [Introduced in PR #514] + * **Deferred State Reading with Lambdas:** Pass lambda providers `() -> T` instead of raw values `T` to child composables when dealing with high-frequency updates (e.g., timers), to isolate recompositions to the child component. [Introduced in PR #515] 4. **Jetpack Compose & CameraX Usage** * Verify that Compose and CameraX APIs are used correctly and effectively. diff --git a/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureScreenComponents.kt b/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureScreenComponents.kt index 59578e45a..9117253f9 100644 --- a/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureScreenComponents.kt +++ b/ui/components/capture/src/main/java/com/google/jetpackcamera/ui/components/capture/CaptureScreenComponents.kt @@ -62,6 +62,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarResult import androidx.compose.material3.Text @@ -128,16 +129,28 @@ private const val FOCUS_INDICATOR_RESULT_DELAY = 100L * A composable that displays the elapsed time of a video recording in a "MM:SS" format. * This text is only visible during an active recording. * - * @param elapsedTimeUiState the [ElapsedTimeUiState] for this component. + * @param formattedTimeProvider a provider for the formatted time string. */ @Composable -fun ElapsedTimeText(modifier: Modifier = Modifier, elapsedTimeUiState: ElapsedTimeUiState) { - if (elapsedTimeUiState is ElapsedTimeUiState.Enabled) { +fun ElapsedTimeText( + modifier: Modifier = Modifier, + formattedTimeProvider: () -> ElapsedTimeUiState +) { + val formattedTime = when (val elapsedTimeUiState = formattedTimeProvider()) { + is ElapsedTimeUiState.Enabled -> { + elapsedTimeUiState.elapsedTimeNanos.nanoseconds + .toComponents { minutes, seconds, _ -> "%02d:%02d".format(minutes, seconds) } + } + ElapsedTimeUiState.Unavailable -> "" + } + if (formattedTime.isNotEmpty()) { Text( modifier = modifier, - text = elapsedTimeUiState.elapsedTimeNanos.nanoseconds - .toComponents { minutes, seconds, _ -> "%02d:%02d".format(minutes, seconds) }, - textAlign = TextAlign.Center + text = formattedTime, + textAlign = TextAlign.Center, + style = LocalTextStyle.current.copy( + fontFeatureSettings = "tnum" + ) ) } }