You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
5.3 KiB

package org.calculate.taigamobile.ui.screens.projectselector
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import androidx.paging.compose.LazyPagingItems
import org.calculate.taigamobile.R
import org.calculate.taigamobile.domain.entities.Project
import org.calculate.taigamobile.ui.components.editors.SelectorList
import org.calculate.taigamobile.ui.components.editors.SelectorListConstants
import org.calculate.taigamobile.ui.theme.TaigaMobileTheme
import org.calculate.taigamobile.ui.components.containers.ContainerBox
import org.calculate.taigamobile.ui.utils.subscribeOnError
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import retrofit2.http.Header
@Composable
fun ProjectSelectorScreen(
navController: NavController,
showMessage: (message: Int) -> Unit = {},
) {
val viewModel: ProjectSelectorViewModel = viewModel()
LaunchedEffect(Unit) {
viewModel.onOpen()
}
val coroutineScope = rememberCoroutineScope()
val projects = viewModel.projects
projects.subscribeOnError(showMessage)
val currentProjectId by viewModel.currentProjectId.collectAsState()
var isSelectorVisible by remember { mutableStateOf(true) }
val selectorAnimationDuration = SelectorListConstants.defaultAnimDurationMillis
fun navigateBack() = coroutineScope.launch {
isSelectorVisible = false
delay(selectorAnimationDuration.toLong())
navController.popBackStack()
}
ProjectSelectorScreenContent(
projects = projects,
isVisible = isSelectorVisible,
currentProjectId = currentProjectId,
selectorAnimationDuration = selectorAnimationDuration,
navigateBack = ::navigateBack,
searchProjects = { viewModel.searchProjects(it) },
selectProject = {
viewModel.selectProject(it)
navigateBack()
}
)
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ProjectSelectorScreenContent(
projects: LazyPagingItems<Project>? = null,
isVisible: Boolean = false,
currentProjectId: Long = -1,
selectorAnimationDuration: Int = SelectorListConstants.defaultAnimDurationMillis,
navigateBack: () -> Unit = {},
searchProjects: (String) -> Unit = {},
selectProject: (Project) -> Unit = {}
) = Box(
Modifier.fillMaxSize(),
contentAlignment = Alignment.TopStart
) {
if (projects == null) return@Box
SelectorList(
titleHintId = R.string.search_projects_hint,
itemsLazy = projects,
isVisible = isVisible,
searchData = searchProjects,
navigateBack = navigateBack,
animationDurationMillis = selectorAnimationDuration
) {
ItemProject(
project = it,
currentProjectId = currentProjectId,
onClick = { selectProject(it) }
)
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun ItemProject(
project: Project,
currentProjectId: Long,
onClick: () -> Unit = {}
) = ContainerBox(
verticalPadding = 16.dp,
onClick = onClick
) {
Row(
modifier = Modifier.fillMaxSize(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Column(Modifier.weight(0.8f)) {
project.takeIf { it.isMember || it.isAdmin || it.isOwner }?.let {
Text(
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.primary,
text = stringResource(
when {
project.isOwner -> R.string.project_owner
project.isAdmin -> R.string.project_admin
project.isMember -> R.string.project_member
else -> 0
}
)
)
}
Text(
text = stringResource(R.string.project_name_template).format(
project.name,
project.slug
)
)
}
if (project.id == currentProjectId) {
Image(
painter = painterResource(R.drawable.ic_check),
contentDescription = null,
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary),
modifier = Modifier.weight(0.2f)
)
}
}
}
@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF)
@Composable
fun ProjectSelectorScreenPreview() = TaigaMobileTheme {
ProjectSelectorScreenContent(isVisible = true)
}