refactor holder screen for both folder and image panes

This commit is contained in:
Rohit Verma 2024-10-13 14:14:39 +05:30
parent 55c09395e4
commit 31c012f953
2 changed files with 53 additions and 22 deletions

View file

@ -1,6 +1,9 @@
package fr.free.nrw.commons.customselector.ui.screens package fr.free.nrw.commons.customselector.ui.screens
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -31,7 +34,9 @@ import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
@ -57,7 +62,8 @@ import fr.free.nrw.commons.ui.theme.CommonsTheme
fun CustomSelectorScreen( fun CustomSelectorScreen(
uiState: CustomSelectorState, uiState: CustomSelectorState,
onEvent: (CustomSelectorEvent)-> Unit, onEvent: (CustomSelectorEvent)-> Unit,
selectedImageIds: List<Long> selectedImageIds: ()-> Set<Long>,
hasPartialAccess: Boolean = false
) { ) {
val adaptiveInfo = currentWindowAdaptiveInfo() val adaptiveInfo = currentWindowAdaptiveInfo()
val navigator = rememberListDetailPaneScaffoldNavigator<Folder>() val navigator = rememberListDetailPaneScaffoldNavigator<Folder>()
@ -65,34 +71,34 @@ fun CustomSelectorScreen(
BackHandler(navigator.canNavigateBack()) { BackHandler(navigator.canNavigateBack()) {
navigator.navigateBack() navigator.navigateBack()
} }
LaunchedEffect(key1 = navigator.currentDestination, key2 = navigator.scaffoldValue) {
println("Current Dest:- ${navigator.currentDestination} | Scaffold Value:- ${navigator.scaffoldValue}")
}
ListDetailPaneScaffold( ListDetailPaneScaffold(
directive = navigator.scaffoldDirective.copy(horizontalPartitionSpacerSize = 0.dp), directive = navigator.scaffoldDirective.copy(horizontalPartitionSpacerSize = 0.dp),
value = navigator.scaffoldValue, value = navigator.scaffoldValue,
listPane = { listPane = {
AnimatedPane { AnimatedPane {
FoldersPane(uiState = uiState, FoldersPane(
uiState = uiState,
onFolderClick = { onFolderClick = {
onEvent(CustomSelectorEvent.OnFolderClick(it.bucketId)) onEvent(CustomSelectorEvent.OnFolderClick(it.bucketId))
navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, it) navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, it)
}, },
hasPartialAccess = hasPartialAccess,
adaptiveInfo = adaptiveInfo adaptiveInfo = adaptiveInfo
) )
} }
}, },
detailPane = { detailPane = {
AnimatedPane(modifier = Modifier) { AnimatedPane {
navigator.currentDestination?.content?.let { folder-> navigator.currentDestination?.content?.let { folder->
ImagesPane( ImagesPane(
uiState = uiState,
selectedFolder = folder, selectedFolder = folder,
selectedImages = selectedImageIds, selectedImages = selectedImageIds,
imageList = uiState.filteredImages,
onNavigateBack = { navigator.navigateBack() }, onNavigateBack = { navigator.navigateBack() },
onToggleImageSelection = { onEvent(CustomSelectorEvent.OnImageSelect(it)) }, onEvent = onEvent,
adaptiveInfo = adaptiveInfo adaptiveInfo = adaptiveInfo,
hasPartialAccess = hasPartialAccess
) )
} }
} }
@ -104,23 +110,42 @@ fun CustomSelectorScreen(
fun FoldersPane( fun FoldersPane(
uiState: CustomSelectorState, uiState: CustomSelectorState,
onFolderClick: (Folder)-> Unit, onFolderClick: (Folder)-> Unit,
adaptiveInfo: WindowAdaptiveInfo adaptiveInfo: WindowAdaptiveInfo,
hasPartialAccess: Boolean = false
) { ) {
val isCompatWidth by remember(adaptiveInfo.windowSizeClass) {
derivedStateOf { adaptiveInfo.windowSizeClass
.windowWidthSizeClass == WindowWidthSizeClass.COMPACT }
}
Scaffold( Scaffold(
topBar = { topBar = {
Surface(tonalElevation = 1.dp) { Surface(tonalElevation = 1.dp) {
CustomSelectorTopBar( CustomSelectorTopBar(
primaryText = stringResource(R.string.custom_selector_title), primaryText = stringResource(R.string.custom_selector_title),
onNavigateBack = { /*TODO*/ }, onNavigateBack = { /*TODO*/ },
showAlertIcon = true showAlertIcon = uiState.selectedImageIds.size > 20 && isCompatWidth,
selectionCount = uiState.selectedImageIds.size,
onAlertAction = { },
showSelectionCount = uiState.inSelectionMode && isCompatWidth
) )
} }
}, },
bottomBar = { bottomBar = {
Surface(tonalElevation = 1.dp) { AnimatedVisibility(
CustomSelectorBottomBar( visible = uiState.inSelectionMode,
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) enter = slideInVertically(initialOffsetY = { it }),
) exit = slideOutVertically(targetOffsetY = { it })
) {
Surface(tonalElevation = 1.dp) {
CustomSelectorBottomBar(
onPrimaryAction = { /*TODO("Implement action to upload selected images")*/},
onSecondaryAction = {
/*TODO("Implement action to mark/unmark images as not for upload")*/
},
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
)
}
} }
} }
) { innerPadding-> ) { innerPadding->
@ -130,16 +155,20 @@ fun FoldersPane(
.padding(innerPadding) .padding(innerPadding)
.fillMaxSize() .fillMaxSize()
) { ) {
if(adaptiveInfo.windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.COMPACT) { if(hasPartialAccess && isCompatWidth) {
PartialStorageAccessDialog( PartialStorageAccessDialog(
isVisible = true, onManageAction = { /*TODO("Request permission[READ_MEDIA_IMAGES]")*/ },
onManage = { /*TODO*/ },
modifier = Modifier.padding(8.dp) modifier = Modifier.padding(8.dp)
) )
} }
if(uiState.isLoading) { if(uiState.isLoading) {
CircularProgressIndicator() Box(
modifier = Modifier.fillMaxSize(1f),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator()
}
} else { } else {
LazyVerticalGrid( LazyVerticalGrid(
columns = GridCells.Adaptive(164.dp), columns = GridCells.Adaptive(164.dp),
@ -236,7 +265,8 @@ private fun CustomSelectorScreenPreview() {
CustomSelectorScreen( CustomSelectorScreen(
uiState = CustomSelectorState(), uiState = CustomSelectorState(),
onEvent = { }, onEvent = { },
selectedImageIds = emptyList() selectedImageIds = { emptySet() },
hasPartialAccess = true
) )
} }
} }

View file

@ -185,7 +185,8 @@ class CustomSelectorActivity :
CustomSelectorScreen( CustomSelectorScreen(
uiState = uiState, uiState = uiState,
onEvent = csViewModel::onEvent, onEvent = csViewModel::onEvent,
selectedImageIds = csViewModel.selectedImageIds selectedImageIds = { uiState.selectedImageIds },
hasPartialAccess = showPartialAccessIndicator
) )
} }
} }