diff --git a/apps/flipcash/features/bill-customization/src/main/kotlin/com/flipcash/app/bill/customization/features/TextureControls.kt b/apps/flipcash/features/bill-customization/src/main/kotlin/com/flipcash/app/bill/customization/features/TextureControls.kt index f36709b95..a08a7b4ae 100644 --- a/apps/flipcash/features/bill-customization/src/main/kotlin/com/flipcash/app/bill/customization/features/TextureControls.kt +++ b/apps/flipcash/features/bill-customization/src/main/kotlin/com/flipcash/app/bill/customization/features/TextureControls.kt @@ -91,10 +91,13 @@ internal fun TextureControls( } } + val blendModes = remember(state.blendModes) { + state.blendModes.map { it.blendMode } + } + val selectedTabIndex by remember(state.selectedBlendMode) { derivedStateOf { - val option = state.selectedBlendMode.blendMode - state.blendModes.map { it.blendMode }.indexOf(option).takeIf { it >= 0 } ?: 0 + blendModes.indexOf(state.selectedBlendMode.blendMode).takeIf { it >= 0 } ?: 0 } } @@ -106,7 +109,7 @@ internal fun TextureControls( indicator = {}, // no indicator divider = {} // no divider ) { - state.blendModes.map { it.blendMode }.forEachIndexed { index, mode -> + blendModes.forEachIndexed { index, mode -> BlendModeTab( mode = mode, isSelected = index == selectedTabIndex, diff --git a/apps/flipcash/features/cash/src/main/kotlin/com/flipcash/app/cash/internal/CashScreenContent.kt b/apps/flipcash/features/cash/src/main/kotlin/com/flipcash/app/cash/internal/CashScreenContent.kt index 8de8bb958..0e8910a57 100644 --- a/apps/flipcash/features/cash/src/main/kotlin/com/flipcash/app/cash/internal/CashScreenContent.kt +++ b/apps/flipcash/features/cash/src/main/kotlin/com/flipcash/app/cash/internal/CashScreenContent.kt @@ -7,7 +7,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -22,7 +22,7 @@ import com.getcode.ui.theme.CodeButton @Composable internal fun GiveScreenContent(viewModel: CashScreenViewModel) { val navigator = LocalCodeNavigator.current - val state by viewModel.stateFlow.collectAsState() + val state by viewModel.stateFlow.collectAsStateWithLifecycle() Column( modifier = Modifier.fillMaxSize(), ) { diff --git a/ui/biometrics/src/main/kotlin/com/getcode/ui/biometrics/Biometrics.kt b/ui/biometrics/src/main/kotlin/com/getcode/ui/biometrics/Biometrics.kt index d50a45d10..87ebe97bd 100644 --- a/ui/biometrics/src/main/kotlin/com/getcode/ui/biometrics/Biometrics.kt +++ b/ui/biometrics/src/main/kotlin/com/getcode/ui/biometrics/Biometrics.kt @@ -5,6 +5,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.ProvidableCompositionLocal import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableLongStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -62,7 +63,7 @@ fun rememberBiometricsState( } var lastAuthTimestamp by remember { - mutableStateOf(0L) + mutableLongStateOf(0L) } LaunchedEffect(checkBiometrics, requireBiometrics, canAuthenticate) { diff --git a/ui/components/src/main/kotlin/com/getcode/ui/components/SlideToConfirm.kt b/ui/components/src/main/kotlin/com/getcode/ui/components/SlideToConfirm.kt index de66eb614..8797ffb82 100644 --- a/ui/components/src/main/kotlin/com/getcode/ui/components/SlideToConfirm.kt +++ b/ui/components/src/main/kotlin/com/getcode/ui/components/SlideToConfirm.kt @@ -162,6 +162,7 @@ fun SlideToConfirm( }, ) { val currentIsLoading by rememberUpdatedState(isLoading) + val currentOnConfirm by rememberUpdatedState(onConfirm) val hapticFeedback = LocalHapticFeedback.current val density = LocalDensity.current val thumbSize = Thumb.Size @@ -210,7 +211,7 @@ fun SlideToConfirm( .filter { it == 1f } .collect { hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress) - onConfirm() + currentOnConfirm() // Give the caller a moment to set isLoading = true. // If they don't, the confirmation was rejected — reset. delay(200) diff --git a/ui/components/src/main/kotlin/com/getcode/ui/components/chat/messagecontents/Feedback.kt b/ui/components/src/main/kotlin/com/getcode/ui/components/chat/messagecontents/Feedback.kt index 8ee49dcdf..855af1f55 100644 --- a/ui/components/src/main/kotlin/com/getcode/ui/components/chat/messagecontents/Feedback.kt +++ b/ui/components/src/main/kotlin/com/getcode/ui/components/chat/messagecontents/Feedback.kt @@ -67,9 +67,11 @@ internal fun Feedback( ) } - val rxns = reactions - .sortedBy { it.sentAt } - .groupBy { it.emoji } + val rxns = remember(reactions) { + reactions + .sortedBy { it.sentAt } + .groupBy { it.emoji } + } rxns.onEach { (emoji, occurrences) -> EmojiCounter( diff --git a/ui/components/src/main/kotlin/com/getcode/ui/components/chat/messagecontents/MessageTextContent.kt b/ui/components/src/main/kotlin/com/getcode/ui/components/chat/messagecontents/MessageTextContent.kt index 2a35dccca..5b03d15de 100644 --- a/ui/components/src/main/kotlin/com/getcode/ui/components/chat/messagecontents/MessageTextContent.kt +++ b/ui/components/src/main/kotlin/com/getcode/ui/components/chat/messagecontents/MessageTextContent.kt @@ -352,7 +352,9 @@ private fun MarkupTextHandler( options.onMarkupClicked != null -> { val markupTextHelper = remember { MarkupTextHelper() } - val markups = options.markupsToResolve.map { Markup.create(it) } + val markups = remember(options.markupsToResolve) { + options.markupsToResolve.map { Markup.create(it) } + } val annotatedString = markupTextHelper.annotate(text.text, markups) val markupHoist = LocalTextLayoutResult.current