floating nav bar interraction

This commit is contained in:
m
2026-09-12 15:46:53 +02:00
parent a1f59a3455
commit 925151faf3
2 changed files with 106 additions and 27 deletions
@@ -30,9 +30,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.CreateNewFolder import androidx.compose.material.icons.filled.CreateNewFolder
import androidx.compose.material.icons.filled.DriveFileMove
import androidx.compose.material.icons.filled.Folder import androidx.compose.material.icons.filled.Folder
import androidx.compose.material.icons.filled.MergeType
import androidx.compose.material.icons.filled.Refresh import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.Card import androidx.compose.material3.Card
@@ -79,6 +77,7 @@ import com.vaultdrop.mobile.ui.components.ServerStatusBadge
import com.vaultdrop.mobile.ui.components.rememberSelectionState import com.vaultdrop.mobile.ui.components.rememberSelectionState
import com.vaultdrop.mobile.ui.navigation.FloatingNavBar import com.vaultdrop.mobile.ui.navigation.FloatingNavBar
import com.vaultdrop.mobile.ui.navigation.NavTab import com.vaultdrop.mobile.ui.navigation.NavTab
import com.vaultdrop.mobile.ui.navigation.SelectionNavBar
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import timber.log.Timber import timber.log.Timber
import java.util.Locale import java.util.Locale
@@ -215,30 +214,7 @@ fun FolderListScreen(
} }
}, },
actions = { actions = {
if (selection.active) { if (!selection.active) {
IconButton(
onClick = { showMoveDialog = true },
enabled = selection.ids.isNotEmpty(),
) {
Icon(
Icons.Filled.DriveFileMove,
contentDescription = stringResource(R.string.move_files),
)
}
IconButton(
onClick = {
val ids = selection.ids.toList()
selection.clear()
onBuildPdf(ids)
},
enabled = selection.ids.isNotEmpty(),
) {
Icon(
Icons.Filled.MergeType,
contentDescription = stringResource(R.string.selection_assemble),
)
}
} else {
ServerStatusBadge( ServerStatusBadge(
status = connectionStatus, status = connectionStatus,
onClick = connectionStatusViewModel::checkNow, onClick = connectionStatusViewModel::checkNow,
@@ -251,7 +227,19 @@ fun FolderListScreen(
) )
}, },
bottomBar = { bottomBar = {
if (selection.active) {
SelectionNavBar(
onMove = { showMoveDialog = true },
onBuildPdf = {
val ids = selection.ids.toList()
selection.clear()
onBuildPdf(ids)
},
enabled = selection.ids.isNotEmpty(),
)
} else {
FloatingNavBar(selected = selectedTab, onSelect = onTabSelected) FloatingNavBar(selected = selectedTab, onSelect = onTabSelected)
}
}, },
snackbarHost = { SnackbarHost(hostState = snackbarHostState) }, snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
) { padding -> ) { padding ->
@@ -12,7 +12,9 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.DriveFileMove
import androidx.compose.material.icons.filled.Folder import androidx.compose.material.icons.filled.Folder
import androidx.compose.material.icons.filled.MergeType
import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.Settings import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.outlined.Folder import androidx.compose.material.icons.outlined.Folder
@@ -119,3 +121,92 @@ fun FloatingNavBar(
} }
} }
} }
/** Barre d'actions affichée à la place de la nav quand le mode multi-sélection est actif. */
@Composable
fun SelectionNavBar(
onMove: () -> Unit,
onBuildPdf: () -> Unit,
enabled: Boolean,
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier
.fillMaxWidth()
.padding(start = 20.dp, end = 20.dp, bottom = 16.dp),
contentAlignment = Alignment.Center,
) {
Surface(
shape = RoundedCornerShape(30.dp),
color = MaterialTheme.colorScheme.surface,
shadowElevation = 8.dp,
modifier = Modifier.widthIn(max = 400.dp).fillMaxWidth(),
) {
Row(
modifier = Modifier.padding(vertical = 8.dp, horizontal = 8.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
SelectionAction(
label = stringResource(R.string.move_files),
icon = Icons.Filled.DriveFileMove,
enabled = enabled,
onClick = onMove,
modifier = Modifier.weight(1f),
)
SelectionAction(
label = stringResource(R.string.selection_assemble),
icon = Icons.Filled.MergeType,
enabled = enabled,
onClick = onBuildPdf,
modifier = Modifier.weight(1f),
)
}
}
}
}
@Composable
private fun SelectionAction(
label: String,
icon: ImageVector,
enabled: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
val tint = if (enabled) MaterialTheme.colorScheme.primary
else MaterialTheme.colorScheme.onSurfaceVariant
Surface(
onClick = onClick,
enabled = enabled,
shape = RoundedCornerShape(20.dp),
color = if (enabled) MaterialTheme.colorScheme.primaryContainer
else MaterialTheme.colorScheme.surfaceVariant,
modifier = modifier,
) {
Box(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 6.dp),
contentAlignment = Alignment.Center,
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Icon(
imageVector = icon,
contentDescription = null,
tint = tint,
modifier = Modifier.size(22.dp),
)
Text(
text = label,
color = tint,
fontSize = 11.sp,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(top = 2.dp),
)
}
}
}
}