Implemented context menu in side panel branches/tags

This commit is contained in:
Abdelilah El Aissaoui 2021-12-12 06:04:19 +01:00
parent e068ac42de
commit 2d32b77a69
8 changed files with 167 additions and 87 deletions

View File

@ -0,0 +1,3 @@
package app
const val MAX_SIDE_PANEL_ITEMS_HEIGHT = 300

View File

@ -1,5 +1,7 @@
package app.ui
import androidx.compose.foundation.ContextMenuArea
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
@ -7,9 +9,7 @@ import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
@ -18,6 +18,8 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import app.MAX_SIDE_PANEL_ITEMS_HEIGHT
import app.extensions.isLocal
import app.ui.components.ScrollableLazyColumn
import app.extensions.simpleName
import app.git.GitManager
@ -26,51 +28,83 @@ import app.theme.headerBackground
import app.theme.headerText
import app.ui.components.SideMenuEntry
import app.ui.components.SideMenuSubentry
import app.ui.components.entryHeight
import app.ui.context_menu.branchContextMenuItems
import app.ui.dialogs.MergeDialog
@Composable
fun Branches(gitManager: GitManager) {
val branches by gitManager.branches.collectAsState()
val currentBranch by gitManager.currentBranch.collectAsState()
val (mergeBranch, setMergeBranch) = remember { mutableStateOf<Ref?>(null) }
Column {
SideMenuEntry("Local branches")
val branchesHeight = branches.count() * 40
val maxHeight = if(branchesHeight < 300)
val branchesHeight = branches.count() * entryHeight
val maxHeight = if (branchesHeight < MAX_SIDE_PANEL_ITEMS_HEIGHT)
branchesHeight
else
300
MAX_SIDE_PANEL_ITEMS_HEIGHT
Box(modifier = Modifier.heightIn(max = maxHeight.dp)) {
ScrollableLazyColumn(modifier = Modifier.fillMaxWidth()) {
itemsIndexed(branches) { _, branch ->
BranchRow(
branch = branch,
isCurrentBranch = currentBranch == branch.name
isCurrentBranch = currentBranch == branch.name,
onCheckoutBranch = { gitManager.checkoutRef(branch) },
onMergeBranch = { setMergeBranch(branch) },
onDeleteBranch = { gitManager.deleteBranch(branch) },
)
}
}
}
}
if(mergeBranch != null) {
MergeDialog(
currentBranch,
mergeBranchName = mergeBranch.name,
onReject = { setMergeBranch(null) },
onAccept = { ff -> gitManager.mergeBranch(mergeBranch, ff) }
)
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun BranchRow(
branch: Ref,
isCurrentBranch: Boolean
isCurrentBranch: Boolean,
onCheckoutBranch: () -> Unit,
onMergeBranch: () -> Unit,
onDeleteBranch: () -> Unit,
) {
SideMenuSubentry(
text = branch.simpleName,
iconResourcePath = "branch.svg",
bold = isCurrentBranch,
) {
if (isCurrentBranch) {
Icon(
painter = painterResource("location.svg"),
contentDescription = null,
modifier = Modifier.padding(horizontal = 4.dp),
tint = MaterialTheme.colors.primary,
ContextMenuArea(
items = {
branchContextMenuItems(
isCurrentBranch = isCurrentBranch,
isLocal = branch.isLocal,
onCheckoutBranch = onCheckoutBranch,
onMergeBranch = onMergeBranch,
onDeleteBranch = onDeleteBranch,
)
}
) {
SideMenuSubentry(
text = branch.simpleName,
iconResourcePath = "branch.svg",
bold = isCurrentBranch,
) {
if (isCurrentBranch) {
Icon(
painter = painterResource("location.svg"),
contentDescription = null,
modifier = Modifier.padding(horizontal = 4.dp),
tint = MaterialTheme.colors.primary,
)
}
}
}
}

View File

@ -7,12 +7,14 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import app.MAX_SIDE_PANEL_ITEMS_HEIGHT
import app.ui.components.ScrollableLazyColumn
import app.extensions.simpleVisibleName
import app.git.GitManager
import app.git.RemoteInfo
import app.ui.components.SideMenuEntry
import app.ui.components.SideMenuSubentry
import app.ui.components.entryHeight
@Composable
fun Remotes(gitManager: GitManager) {
@ -22,11 +24,11 @@ fun Remotes(gitManager: GitManager) {
SideMenuEntry("Remotes")
val allBranches = remotes.map { it.branchesList }.flatten()
val remotesHeight = (allBranches.count() + remotes.count()) * 40
val maxHeight = if(remotesHeight < 300)
val remotesHeight = (allBranches.count() + remotes.count()) * entryHeight
val maxHeight = if(remotesHeight < MAX_SIDE_PANEL_ITEMS_HEIGHT)
remotesHeight
else
300
MAX_SIDE_PANEL_ITEMS_HEIGHT
Box(modifier = Modifier.heightIn(max = maxHeight.dp)) {
ScrollableLazyColumn(modifier = Modifier.fillMaxWidth()) {

View File

@ -1,29 +1,21 @@
package app.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.ContextMenuArea
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.items
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import app.MAX_SIDE_PANEL_ITEMS_HEIGHT
import app.extensions.simpleName
import app.ui.components.ScrollableLazyColumn
import app.git.GitManager
import app.git.StashStatus
import org.eclipse.jgit.revwalk.RevCommit
import app.theme.headerBackground
import app.theme.headerText
import app.ui.components.SideMenuEntry
import app.ui.components.SideMenuSubentry
import app.ui.components.entryHeight
import app.ui.context_menu.tagContextMenuItems
import org.eclipse.jgit.lib.Ref
@Composable
@ -31,25 +23,25 @@ fun Tags(gitManager: GitManager) {
val tagsState = gitManager.tags.collectAsState()
val tags = tagsState.value
Column {
SideMenuEntry(
text = "Tags",
)
val branchesHeight = tags.count() * 40
val maxHeight = if (branchesHeight < 300)
branchesHeight
val tagsHeight = tags.count() * entryHeight
val maxHeight = if (tagsHeight < MAX_SIDE_PANEL_ITEMS_HEIGHT)
tagsHeight
else
300
MAX_SIDE_PANEL_ITEMS_HEIGHT
Box(modifier = Modifier.heightIn(max = maxHeight.dp)) {
ScrollableLazyColumn(modifier = Modifier.fillMaxWidth()) {
items(items = tags) { tag ->
TagRow(
tag = tag,
onCheckoutTag = { gitManager.checkoutRef(tag) },
onDeleteTag = { gitManager.deleteTag(tag) }
)
}
}
}
@ -57,10 +49,24 @@ fun Tags(gitManager: GitManager) {
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun TagRow(tag: Ref) {
SideMenuSubentry(
text = tag.simpleName,
iconResourcePath = "tag.svg",
)
private fun TagRow(
tag: Ref,
onCheckoutTag: () -> Unit,
onDeleteTag: () -> Unit,
) {
ContextMenuArea(
items = {
tagContextMenuItems(
onCheckoutTag = onCheckoutTag,
onDeleteTag = onDeleteTag,
)
}
) {
SideMenuSubentry(
text = tag.simpleName,
iconResourcePath = "tag.svg",
)
}
}

View File

@ -19,6 +19,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import app.theme.primaryTextColor
const val entryHeight = 40
@Composable
fun SideMenuSubentry(
text: String,
@ -30,7 +32,7 @@ fun SideMenuSubentry(
) {
Row(
modifier = Modifier
.height(40.dp)
.height(entryHeight.dp)
.fillMaxWidth()
.clickable(onClick = onClick)
.padding(start = extraPadding),

View File

@ -0,0 +1,38 @@
package app.ui.context_menu
import androidx.compose.foundation.ContextMenuItem
import androidx.compose.foundation.ExperimentalFoundationApi
@OptIn(ExperimentalFoundationApi::class)
fun branchContextMenuItems(
isCurrentBranch: Boolean,
isLocal: Boolean,
onCheckoutBranch: () -> Unit,
onMergeBranch: () -> Unit,
onDeleteBranch: () -> Unit,
): List<ContextMenuItem> {
return mutableListOf(
ContextMenuItem(
label = "Checkout branch",
onClick = onCheckoutBranch
),
).apply {
if (!isCurrentBranch) {
add(
ContextMenuItem(
label = "Merge branch",
onClick = onMergeBranch
)
)
}
if (isLocal && !isCurrentBranch) {
add(
ContextMenuItem(
label = "Delete branch",
onClick = onDeleteBranch
)
)
}
}
}

View File

@ -0,0 +1,22 @@
package app.ui.context_menu
import androidx.compose.foundation.ContextMenuItem
import androidx.compose.foundation.ExperimentalFoundationApi
import app.extensions.isLocal
@OptIn(ExperimentalFoundationApi::class)
fun tagContextMenuItems(
onCheckoutTag: () -> Unit,
onDeleteTag: () -> Unit,
): List<ContextMenuItem> {
return mutableListOf(
ContextMenuItem(
label = "Checkout tag",
onClick = onCheckoutTag
),
ContextMenuItem(
label = "Delete tag",
onClick = onDeleteTag
)
)
}

View File

@ -15,7 +15,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.contentColorFor
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
@ -41,6 +40,8 @@ import app.images.rememberNetworkImage
import app.theme.*
import app.ui.SelectedItem
import app.ui.components.ScrollableLazyColumn
import app.ui.context_menu.branchContextMenuItems
import app.ui.context_menu.tagContextMenuItems
import app.ui.dialogs.MergeDialog
import app.ui.dialogs.NewBranchDialog
import app.ui.dialogs.NewTagDialog
@ -626,30 +627,13 @@ fun BranchChip(
color: Color,
) {
val contextMenuItemsList = {
mutableListOf(
ContextMenuItem(
label = "Checkout branch",
onClick = onCheckoutBranch
),
).apply {
if (!isCurrentBranch) {
add(
ContextMenuItem(
label = "Merge branch",
onClick = onMergeBranch
)
)
}
if (ref.isLocal && !isCurrentBranch) {
add(
ContextMenuItem(
label = "Delete branch",
onClick = onDeleteBranch
)
)
}
}
branchContextMenuItems(
isCurrentBranch = isCurrentBranch,
isLocal = ref.isLocal,
onCheckoutBranch = onCheckoutBranch,
onMergeBranch = onMergeBranch,
onDeleteBranch = onDeleteBranch,
)
}
var endingContent: @Composable () -> Unit = {}
@ -685,21 +669,10 @@ fun TagChip(
color: Color,
) {
val contextMenuItemsList = {
mutableListOf(
ContextMenuItem(
label = "Checkout tag",
onClick = onCheckoutTag
)
).apply {
if (ref.isLocal) {
add(
ContextMenuItem(
label = "Delete tag",
onClick = onDeleteTag
)
)
}
}
tagContextMenuItems(
onCheckoutTag = onCheckoutTag,
onDeleteTag = onDeleteTag,
)
}
RefChip(