Changed side panel headers to be expandables and improved its UI

This commit is contained in:
Abdelilah El Aissaoui 2022-02-03 14:47:25 +01:00
parent 09d4184c40
commit 832189e91e
7 changed files with 166 additions and 106 deletions

View file

@ -2,12 +2,7 @@ package app.ui
import androidx.compose.foundation.ContextMenuArea
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.*
@ -16,9 +11,7 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import app.extensions.isLocal
import app.extensions.simpleName
import app.maxSidePanelHeight
import app.ui.components.ScrollableLazyColumn
import app.ui.components.SideMenuEntry
import app.ui.components.SideMenuPanel
import app.ui.components.SideMenuSubentry
import app.ui.context_menu.branchContextMenuItems
import app.ui.dialogs.MergeDialog
@ -35,29 +28,21 @@ fun Branches(
val currentBranch by branchesViewModel.currentBranch.collectAsState()
val (mergeBranch, setMergeBranch) = remember { mutableStateOf<Ref?>(null) }
val (rebaseBranch, setRebaseBranch) = remember { mutableStateOf<Ref?>(null) }
val maxHeight = remember(branches) { maxSidePanelHeight(branches.count()) }
Column {
SideMenuEntry("Local branches")
ScrollableLazyColumn(
modifier = Modifier
.fillMaxWidth()
.heightIn(max = maxHeight.dp)
.background(MaterialTheme.colors.background)
) {
itemsIndexed(branches) { _, branch ->
BranchLineEntry(
branch = branch,
isCurrentBranch = currentBranch == branch.name,
onBranchClicked = { onBranchClicked(branch) },
onCheckoutBranch = { branchesViewModel.checkoutRef(branch) },
onMergeBranch = { setMergeBranch(branch) },
onDeleteBranch = { branchesViewModel.deleteBranch(branch) },
onRebaseBranch = { setRebaseBranch(branch) },
)
}
}
SideMenuPanel(
title = "Local branches",
icon = painterResource("branch.svg"),
items = branches
) { branch ->
BranchLineEntry(
branch = branch,
isCurrentBranch = currentBranch == branch.name,
onBranchClicked = { onBranchClicked(branch) },
onCheckoutBranch = { branchesViewModel.checkoutRef(branch) },
onMergeBranch = { setMergeBranch(branch) },
onDeleteBranch = { branchesViewModel.deleteBranch(branch) },
onRebaseBranch = { setRebaseBranch(branch) },
)
}
if (mergeBranch != null) {

View file

@ -1,48 +1,36 @@
package app.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import app.extensions.simpleVisibleName
import app.git.RemoteInfo
import app.maxSidePanelHeight
import app.ui.components.ScrollableLazyColumn
import app.ui.components.SideMenuEntry
import app.ui.components.SideMenuPanel
import app.ui.components.SideMenuSubentry
import app.viewmodels.RemotesViewModel
@Composable
fun Remotes(remotesViewModel: RemotesViewModel) {
val remotes by remotesViewModel.remotes.collectAsState()
val allBranches = remotes.map { it.branchesList }.flatten()
val maxHeight = remember(remotes) { maxSidePanelHeight(allBranches.count() + remotes.count()) }
Column {
SideMenuEntry("Remotes")
ScrollableLazyColumn(
modifier = Modifier
.fillMaxWidth()
.heightIn(max = maxHeight.dp)
.background(MaterialTheme.colors.background)
) {
items(remotes) { remote ->
RemoteRow(
remote = remote,
)
}
}
val itemsCount = remember(remotes) {
val allBranches = remotes.map { it.branchesList }.flatten()
allBranches.count() + remotes.count()
}
SideMenuPanel(
title = "Remotes",
icon = painterResource("cloud.svg"),
items = remotes,
itemsCountForMaxHeight = itemsCount,
itemContent = { remoteInfo ->
RemoteRow(remoteInfo)
}
)
}
@Composable

View file

@ -10,10 +10,12 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import app.maxSidePanelHeight
import app.ui.components.ScrollableLazyColumn
import app.ui.components.SideMenuEntry
import app.ui.components.SideMenuPanel
import app.ui.components.SideMenuSubentry
import app.viewmodels.StashStatus
import app.viewmodels.StashesViewModel
@ -32,29 +34,18 @@ fun Stashes(
else
listOf()
val maxHeight = remember(stashList) { maxSidePanelHeight(stashList.count()) }
Column {
SideMenuEntry(
text = "Stashes",
)
ScrollableLazyColumn(
modifier = Modifier
.fillMaxWidth()
.heightIn(max = maxHeight.dp)
.background(MaterialTheme.colors.background)
) {
items(items = stashList) { stash ->
StashRow(
stash = stash,
onClick = {
onStashSelected(stash)
}
)
}
SideMenuPanel(
title = "Stashes",
icon = painterResource("stash.svg"),
items = stashList,
itemContent = { stashInfo ->
StashRow(
stash = stashInfo,
onClick = { onStashSelected(stashInfo) }
)
}
}
)
}

View file

@ -12,11 +12,13 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import app.extensions.simpleName
import app.maxSidePanelHeight
import app.ui.components.ScrollableLazyColumn
import app.ui.components.SideMenuEntry
import app.ui.components.SideMenuPanel
import app.ui.components.SideMenuSubentry
import app.ui.context_menu.tagContextMenuItems
import app.viewmodels.TagsViewModel
@ -29,31 +31,20 @@ fun Tags(
) {
val tagsState = tagsViewModel.tags.collectAsState()
val tags = tagsState.value
val maxHeight = remember(tags) { maxSidePanelHeight(tags.count()) }
Column {
SideMenuEntry(
text = "Tags",
)
ScrollableLazyColumn(
modifier = Modifier
.fillMaxWidth()
.heightIn(max = maxHeight.dp)
.background(MaterialTheme.colors.background)
) {
items(items = tags) { tag ->
TagRow(
tag = tag,
onTagClicked = { onTagClicked(tag) },
onCheckoutTag = { tagsViewModel.checkoutRef(tag) },
onDeleteTag = { tagsViewModel.deleteTag(tag) }
)
}
SideMenuPanel(
title = "Tags",
items = tags,
icon = painterResource("tag.svg"),
itemContent = { tag ->
TagRow(
tag = tag,
onTagClicked = { onTagClicked(tag) },
onCheckoutTag = { tagsViewModel.checkoutRef(tag) },
onDeleteTag = { tagsViewModel.deleteTag(tag) }
)
}
}
)
}
@OptIn(ExperimentalFoundationApi::class)

View file

@ -0,0 +1,35 @@
package app.ui.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun VerticalExpandable(
header: @Composable () -> Unit,
child: @Composable () -> Unit,
) {
var isExpanded by remember {
mutableStateOf(true)
}
Column {
Box(
modifier = Modifier.clickable {
isExpanded = !isExpanded
}
) {
header()
}
AnimatedVisibility(visible = isExpanded) {
child()
}
}
}

View file

@ -1,15 +1,15 @@
package app.ui.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.*
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@ -20,6 +20,8 @@ import app.theme.secondaryTextColor
@Composable
fun SideMenuEntry(
text: String,
icon: Painter? = null,
itemsCount: Int,
) {
Row(
modifier = Modifier
@ -28,14 +30,34 @@ fun SideMenuEntry(
.background(color = MaterialTheme.colors.headerBackground),
verticalAlignment = Alignment.CenterVertically,
) {
if(icon != null) {
Icon(
painter = icon,
contentDescription = null,
tint = MaterialTheme.colors.primaryTextColor,
modifier = Modifier
.padding(start = 8.dp)
.size(16.dp),
)
}
Text(
text = text,
modifier = Modifier
.padding(horizontal = 8.dp),
.padding(horizontal = 8.dp)
.weight(1f),
maxLines = 1,
fontSize = 14.sp,
color = MaterialTheme.colors.primaryTextColor,
overflow = TextOverflow.Ellipsis,
)
Text(
text = itemsCount.toString(),
fontSize = 14.sp,
color = MaterialTheme.colors.secondaryTextColor,
modifier = Modifier.padding(end = 8.dp),
)
}
}

View file

@ -0,0 +1,48 @@
package app.ui.components
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.unit.dp
import app.maxSidePanelHeight
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun <T> SideMenuPanel(
title: String,
icon: Painter? = null,
items: List<T>,
itemsCountForMaxHeight: Int = items.count(),
itemContent: @Composable (T) -> Unit,
) {
val maxHeight = remember(items) { maxSidePanelHeight(itemsCountForMaxHeight) }
VerticalExpandable(
header = {
SideMenuEntry(
text = title,
icon = icon,
itemsCount = items.count()
)
},
) {
ScrollableLazyColumn(
modifier = Modifier
.fillMaxWidth()
.heightIn(max = maxHeight.dp)
.background(MaterialTheme.colors.background)
) {
items(items) { item ->
itemContent(item)
}
}
}
}