Coverage Summary for Class: SettingsSubScreenScaffoldKt (com.georgeci.moneysurfer.feature.settings.components)

Class Class, % Method, % Branch, % Line, % Instruction, %
SettingsSubScreenScaffoldKt 100% (1/1) 75% (3/4) 33.3% (4/12) 63.4% (26/41) 65.5% (298/455)


 package com.georgeci.moneysurfer.feature.settings.components
 
 import androidx.compose.foundation.background
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.ColumnScope
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.rememberScrollState
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material3.CircularProgressIndicator
 import androidx.compose.material3.Scaffold
 import androidx.compose.material3.SnackbarHost
 import androidx.compose.material3.SnackbarHostState
 import androidx.compose.material3.TopAppBarDefaults
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import com.georgeci.moneysurfer.uikit.components.base.SurferPaneTopBar
 import com.georgeci.moneysurfer.uikit.modifier.surferContentContainer
 import com.georgeci.moneysurfer.uikit.modifier.surferSafeInsets
 import com.georgeci.moneysurfer.uikit.theme.AppTheme
 
 /**
  * Shared chrome for settings sub-screens (Backup, CSV export/import): themed
  * toolbar, snackbar host, scrollable column, and an optional modal progress
  * scrim while a long-running operation is in flight. [content] receives the
  * scaffold padding so screens can size their bottom spacer.
  */
 @Composable
 internal fun SettingsSubScreenScaffold(
     title: String,
     snackbarHostState: SnackbarHostState,
     onBack: () -> Unit,
     showProgressOverlay: Boolean,
     content: @Composable ColumnScope.(PaddingValues) -> Unit,
 ) {
     Scaffold(
         modifier = Modifier.surferSafeInsets(),
         containerColor = AppTheme.materialColors.surface,
         topBar = {
             SurferPaneTopBar(
                 title = title,
                 onBack = onBack,
                 colors = TopAppBarDefaults.topAppBarColors(
                     containerColor = AppTheme.materialColors.surface,
                     titleContentColor = AppTheme.materialColors.onSurface,
                 ),
             )
         },
         snackbarHost = { SnackbarHost(snackbarHostState) },
     ) { padding ->
         Box(modifier = Modifier.fillMaxSize()) {
             Column(
                 modifier = Modifier
                     .fillMaxSize()
                     .surferContentContainer()
                     .padding(top = padding.calculateTopPadding())
                     .verticalScroll(rememberScrollState()),
             ) {
                 content(padding)
             }
 
             if (showProgressOverlay) {
                 SettingsProgressOverlay()
             }
         }
     }
 }
 
 /**
  * Modal scrim while export/import is in flight. The `clickable` with no-op
  * onClick + null indication consumes pointer events so taps don't reach the
  * settings rows underneath.
  */
 @Composable
 private fun SettingsProgressOverlay() {
     val interactionSource = remember { MutableInteractionSource() }
     Box(
         modifier = Modifier
             .fillMaxSize()
             .background(AppTheme.materialColors.scrim.copy(alpha = SCRIM_ALPHA))
             .clickable(
                 interactionSource = interactionSource,
                 indication = null,
                 onClick = {},
             ),
         contentAlignment = Alignment.Center,
     ) {
         CircularProgressIndicator(color = AppTheme.materialColors.primary)
     }
 }
 
 private const val SCRIM_ALPHA = 0.4f