Coverage Summary for Class: AccountChooserBottomSheetKt (com.georgeci.moneysurfer.feature.account.picker)

Class Method, % Branch, % Line, % Instruction, %
AccountChooserBottomSheetKt 0% (0/3) 0% (0/96) 0% (0/47) 0% (0/871)
AccountChooserBottomSheetKt$AccountChooserBottomSheet$5$1 0% (0/1) 0% (0/1) 0% (0/9)
Total 0% (0/4) 0% (0/96) 0% (0/48) 0% (0/880)


 package com.georgeci.moneysurfer.feature.account.picker
 
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.georgeci.moneysurfer.domain.formatter.MoneyFormatter
 import com.georgeci.moneysurfer.domain.primitives.AccountId
 import com.georgeci.moneysurfer.feature.account.generated.resources.Res
 import com.georgeci.moneysurfer.feature.account.generated.resources.accounts_manage_transfer_instead
 import com.georgeci.moneysurfer.feature.account.generated.resources.transaction_creation_account_add_new
 import com.georgeci.moneysurfer.feature.account.generated.resources.transaction_creation_account_add_new_subtitle
 import com.georgeci.moneysurfer.feature.account.generated.resources.transaction_creation_account_sheet_title
 import com.georgeci.moneysurfer.feature.account.generated.resources.transaction_creation_account_summary
 import com.georgeci.moneysurfer.feature.account.generated.resources.transaction_creation_account_summary_empty
 import com.georgeci.moneysurfer.uikit.icons.SurferIcons
 import com.georgeci.moneysurfer.utils.HandleSideEffect
 import org.jetbrains.compose.resources.pluralStringResource
 import org.jetbrains.compose.resources.stringResource
 import org.koin.compose.viewmodel.koinViewModel
 import org.koin.core.parameter.parametersOf
 
 /**
  * Bottom-sheet entry composable for picking an account. Hosted as a navigation entry; the
  * surrounding [androidx.compose.material3.ModalBottomSheet] is provided by
  * [com.georgeci.moneysurfer.navigation.BottomSheetSceneStrategy]. Visual layout lives
  * in [AccountChooserContent] — this composable just maps the ViewModel's state and effects.
  */
 @Composable
 fun AccountChooserBottomSheet(
     selectedAccountId: AccountId?,
     excludeAccountId: AccountId? = null,
     showTransferShortcut: Boolean = false,
     onDismiss: () -> Unit,
     onNavigateToAccountCreation: () -> Unit,
     onAccountPicked: (AccountId) -> Unit,
     onTransferRequested: () -> Unit = {},
     viewModel: AccountChooserViewModel = koinViewModel(
         key = "${selectedAccountId?.value.orEmpty()}|${excludeAccountId?.value.orEmpty()}",
     ) { parametersOf(selectedAccountId, excludeAccountId) },
 ) {
     val state by viewModel.collectAsStateWithLifecycle()
 
     viewModel.HandleSideEffect { effect ->
         when (effect) {
             AccountChooserEffect.Dismiss -> onDismiss()
             AccountChooserEffect.NavigateToAccountCreation -> onNavigateToAccountCreation()
             is AccountChooserEffect.PublishResult -> onAccountPicked(effect.id)
             AccountChooserEffect.RequestTransfer -> onTransferRequested()
         }
     }
 
     val content = state as? AccountChooserState.Content
     val accounts = content?.accounts.orEmpty()
     val totalsFormatted = content?.totalsFormatted.orEmpty()
 
     val summary = if (accounts.isEmpty() || totalsFormatted.isEmpty()) {
         stringResource(Res.string.transaction_creation_account_summary_empty)
     } else {
         pluralStringResource(
             Res.plurals.transaction_creation_account_summary,
             accounts.size,
             accounts.size,
             // One figure per currency; with a single currency this reads exactly as before.
             totalsFormatted.joinToString(" · "),
         )
     }
 
     AccountChooserContent(
         title = stringResource(Res.string.transaction_creation_account_sheet_title),
         summary = summary,
         accounts = accounts.map { account ->
             AccountPickerRow(
                 id = account.id,
                 name = account.name,
                 subtitle = account.currencyCode.value,
                 formattedBalance = MoneyFormatter.format(account.balance, account.currencyCode),
                 icon = SurferIcons.CreditCard,
             )
         },
         selectedId = state.selectedId,
         addNewLabel = stringResource(Res.string.transaction_creation_account_add_new),
         addNewSubtitle = stringResource(Res.string.transaction_creation_account_add_new_subtitle),
         onSelect = { id -> viewModel.onEvent(AccountChooserEvent.OnAccountSelected(id)) },
         onAddNew = { viewModel.onEvent(AccountChooserEvent.OnAddNewAccountClick) },
         onClose = { viewModel.onEvent(AccountChooserEvent.OnDismiss) },
         transferInsteadLabel = stringResource(Res.string.accounts_manage_transfer_instead)
             .takeIf { showTransferShortcut },
         onTransferInstead = { viewModel.onEvent(AccountChooserEvent.OnTransferInsteadClick) },
     )
 }