Gitnuro/src/main/kotlin/app/ui/Branches.kt
2022-06-11 05:19:36 +02:00

125 lines
4.5 KiB
Kotlin

package app.ui
import androidx.compose.foundation.ContextMenuArea
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import app.extensions.isLocal
import app.extensions.simpleName
import app.ui.components.SideMenuPanel
import app.ui.components.SideMenuSubentry
import app.ui.context_menu.branchContextMenuItems
import app.ui.dialogs.MergeDialog
import app.ui.dialogs.RebaseDialog
import app.viewmodels.BranchesViewModel
import org.eclipse.jgit.lib.Ref
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun Branches(
branchesViewModel: BranchesViewModel,
) {
val branches by branchesViewModel.branches.collectAsState()
val currentBranchState = branchesViewModel.currentBranch.collectAsState()
val isExpanded by branchesViewModel.isExpanded.collectAsState()
val currentBranch = currentBranchState.value
val (mergeBranch, setMergeBranch) = remember { mutableStateOf<Ref?>(null) }
val (rebaseBranch, setRebaseBranch) = remember { mutableStateOf<Ref?>(null) }
SideMenuPanel(
title = "Local branches",
icon = painterResource("branch.svg"),
items = branches,
isExpanded = isExpanded,
onExpand = { branchesViewModel.onExpand() },
itemContent = { branch ->
BranchLineEntry(
branch = branch,
currentBranch = currentBranch,
isCurrentBranch = currentBranch?.name == branch.name,
onBranchClicked = { branchesViewModel.selectBranch(branch) },
onBranchDoubleClicked = { branchesViewModel.checkoutRef(branch) },
onCheckoutBranch = { branchesViewModel.checkoutRef(branch) },
onMergeBranch = { setMergeBranch(branch) },
onDeleteBranch = { branchesViewModel.deleteBranch(branch) },
onRebaseBranch = { setRebaseBranch(branch) },
onPushToRemoteBranch = { branchesViewModel.pushToRemoteBranch(branch) },
onPullFromRemoteBranch = { branchesViewModel.pullFromRemoteBranch(branch) },
)
}
)
if (mergeBranch != null && currentBranch != null) {
MergeDialog(
currentBranchName = currentBranch.simpleName,
mergeBranchName = mergeBranch.name,
onReject = { setMergeBranch(null) },
onAccept = { ff -> branchesViewModel.mergeBranch(mergeBranch, ff) }
)
}
if (rebaseBranch != null && currentBranch != null) {
RebaseDialog(
currentBranchName = currentBranch.simpleName,
rebaseBranchName = rebaseBranch.name,
onReject = { setRebaseBranch(null) },
onAccept = { branchesViewModel.rebaseBranch(rebaseBranch) }
)
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun BranchLineEntry(
branch: Ref,
currentBranch: Ref?,
isCurrentBranch: Boolean,
onBranchClicked: () -> Unit,
onBranchDoubleClicked: () -> Unit,
onCheckoutBranch: () -> Unit,
onMergeBranch: () -> Unit,
onRebaseBranch: () -> Unit,
onDeleteBranch: () -> Unit,
onPushToRemoteBranch: () -> Unit,
onPullFromRemoteBranch: () -> Unit,
) {
ContextMenuArea(
items = {
branchContextMenuItems(
branch = branch,
currentBranch = currentBranch,
isCurrentBranch = isCurrentBranch,
isLocal = branch.isLocal,
onCheckoutBranch = onCheckoutBranch,
onMergeBranch = onMergeBranch,
onDeleteBranch = onDeleteBranch,
onRebaseBranch = onRebaseBranch,
onPushToRemoteBranch = onPushToRemoteBranch,
onPullFromRemoteBranch = onPullFromRemoteBranch,
)
}
) {
SideMenuSubentry(
text = branch.simpleName,
iconResourcePath = "branch.svg",
bold = isCurrentBranch,
onClick = onBranchClicked,
onDoubleClick = onBranchDoubleClicked
) {
if (isCurrentBranch) {
Icon(
painter = painterResource("location.svg"),
contentDescription = null,
modifier = Modifier.padding(horizontal = 4.dp),
tint = MaterialTheme.colors.primaryVariant,
)
}
}
}
}