Added context menu to log and added tag creation

This commit is contained in:
Abdelilah El Aissaoui 2021-10-27 03:23:06 +02:00
parent cafe8f1b19
commit 414bce560f
5 changed files with 218 additions and 33 deletions

View File

@ -15,6 +15,7 @@ import app.AppStateManager
import app.app.Error
import app.app.ErrorsManager
import app.app.newErrorNow
import org.eclipse.jgit.lib.ObjectId
import java.io.File
import javax.inject.Inject
@ -238,6 +239,27 @@ class GitManager @Inject constructor(
statusManager.stageAll(safeGit)
}
fun checkoutCommit(revCommit: RevCommit) = managerScope.launch {
safeProcessing {
logManager.checkoutCommit(safeGit, revCommit)
coLoadLog()
}
}
fun createBranchOnCommit(branch: String, revCommit: RevCommit) = managerScope.launch {
safeProcessing {
logManager.createBranchOnCommit(safeGit, branch, revCommit)
coLoadLog()
}
}
fun createTagOnCommit(tag: String, revCommit: RevCommit) = managerScope.launch {
safeProcessing {
logManager.createTagOnCommit(safeGit, tag, revCommit)
coLoadLog()
}
}
var onRepositoryChanged: (path: String?) -> Unit = {}
private suspend fun safeProcessing(callback: suspend () -> Unit) {

View File

@ -9,7 +9,8 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.withContext
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.lib.Constants
import org.eclipse.jgit.lib.Ref
import org.eclipse.jgit.lib.ObjectId
import org.eclipse.jgit.revwalk.RevCommit
import javax.inject.Inject
@ -47,6 +48,31 @@ class LogManager @Inject constructor(
_logStatus.value = loadedStatus
}
suspend fun checkoutCommit(git: Git, revCommit: RevCommit) = withContext(Dispatchers.IO) {
git
.checkout()
.setName(revCommit.name)
.call()
}
suspend fun createBranchOnCommit(git: Git, branch: String, revCommit: RevCommit) = withContext(Dispatchers.IO) {
git
.checkout()
.setCreateBranch(true)
.setName(branch)
.setStartPoint(revCommit)
.call()
}
suspend fun createTagOnCommit(git: Git, tag: String, revCommit: RevCommit) = withContext(Dispatchers.IO) {
git
.tag()
.setAnnotated(true)
.setName(tag)
.setObjectId(revCommit)
.call()
}
}

View File

@ -16,7 +16,6 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.clipRect
import androidx.compose.ui.input.pointer.PointerIcon
import androidx.compose.ui.input.pointer.PointerIconDefaults
import androidx.compose.ui.input.pointer.pointerHoverIcon
import androidx.compose.ui.res.painterResource
@ -25,6 +24,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import app.DialogManager
import app.extensions.simpleName
import app.extensions.toSmartSystemString
import app.git.GitManager
@ -35,6 +35,8 @@ import app.theme.headerText
import app.theme.primaryTextColor
import app.theme.secondaryTextColor
import app.ui.components.ScrollableLazyColumn
import app.ui.dialogs.NewBranchDialog
import app.ui.dialogs.NewTagDialog
import org.eclipse.jgit.lib.ObjectIdRef
import org.eclipse.jgit.lib.Ref
import org.eclipse.jgit.revwalk.RevCommit
@ -59,8 +61,12 @@ private const val CANVAS_MIN_WIDTH = 100
@Composable
fun Log(
gitManager: GitManager,
dialogManager: DialogManager,
onRevCommitSelected: (RevCommit) -> Unit,
onUncommitedChangesSelected: () -> Unit,
onCheckoutCommit: (graphNode: GraphNode) -> Unit,
onCreateBranchOnCommit: (branchName: String, graphNode: GraphNode) -> Unit,
onCreateTagOnCommit: (tagName: String, graphNode: GraphNode) -> Unit,
selectedIndex: MutableState<Int> = remember { mutableStateOf(-1) }
) {
val logStatusState = gitManager.logStatus.collectAsState()
@ -184,38 +190,86 @@ fun Log(
itemsIndexed(items = commitList) { index, item ->
val commitRefs = item.refs
Row(
modifier = Modifier
.height(40.dp)
.fillMaxWidth()
.clickable {
selectedIndex.value = index
selectedUncommited.value = false
onRevCommitSelected(item)
},
Box(modifier = Modifier
.clickable {
selectedIndex.value = index
selectedUncommited.value = false
onRevCommitSelected(item)
}
) {
CommitsGraphLine(
modifier = Modifier
.width(graphWidth),
plotCommit = item
)
DividerLog(
modifier = Modifier
.draggable(
rememberDraggableState {
weightMod += it
},
Orientation.Horizontal
ContextMenuArea(
items = {
listOf(
ContextMenuItem(
label = "Checkout commit",
onClick = { onCheckoutCommit(item) }
),
ContextMenuItem(
label = "Create branch",
onClick = {
dialogManager.show {
NewBranchDialog(
onReject = {
dialogManager.dismiss()
},
onAccept = { branchName ->
onCreateBranchOnCommit(branchName, item)
dialogManager.dismiss()
}
)
}
}
),
ContextMenuItem(
label = "Create tag",
onClick = {
dialogManager.show {
NewTagDialog(
onReject = {
dialogManager.dismiss()
},
onAccept = { branchName ->
onCreateTagOnCommit(branchName, item)
dialogManager.dismiss()
}
)
}
}
),
)
},
) {
Row(
modifier = Modifier
.height(40.dp)
.fillMaxWidth(),
) {
CommitsGraphLine(
modifier = Modifier
.width(graphWidth),
plotCommit = item
)
)
CommitMessage(
modifier = Modifier.weight(1f),
commit = item,
selected = selectedIndex.value == index,
refs = commitRefs,
)
DividerLog(
modifier = Modifier
.draggable(
rememberDraggableState {
weightMod += it
},
Orientation.Horizontal
)
)
CommitMessage(
modifier = Modifier.weight(1f),
commit = item,
selected = selectedIndex.value == index,
refs = commitRefs,
)
}
}
}
}
}
@ -404,7 +458,7 @@ fun UncommitedChangesGraphLine(
@Composable
fun RefChip(modifier: Modifier = Modifier, ref: Ref) {
val icon = remember(ref) {
if(ref is ObjectIdRef.PeeledTag) {
if (ref is ObjectIdRef.PeeledTag) {
"tag.svg"
} else
"branch.svg"

View File

@ -91,10 +91,18 @@ fun RepositoryOpenPage(gitManager: GitManager, dialogManager: DialogManager) {
null -> {
Log(
gitManager = gitManager,
dialogManager = dialogManager,
selectedIndex = selectedIndexCommitLog,
onCheckoutCommit = { graphNode ->
gitManager.checkoutCommit(graphNode)
},
onCreateBranchOnCommit = { branch, graphNode ->
gitManager.createBranchOnCommit(branch, graphNode)
},
onCreateTagOnCommit = { tag, graphNode ->
gitManager.createTagOnCommit(tag, graphNode)
},
onRevCommitSelected = { commit ->
// TODO Move all this code to tree manager
selectedRevCommit = commit
uncommitedChangesSelected = false
},

View File

@ -0,0 +1,75 @@
package app.ui.dialogs
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusOrder
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@Composable
fun NewTagDialog(
onReject: () -> Unit,
onAccept: (tagName: String) -> Unit
) {
var tagField by remember { mutableStateOf("") }
val tagFieldFocusRequester = remember { FocusRequester() }
val buttonFieldFocusRequester = remember { FocusRequester() }
Column(
modifier = Modifier
.background(MaterialTheme.colors.background),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
OutlinedTextField(
modifier = Modifier
.focusOrder(tagFieldFocusRequester) {
this.next = buttonFieldFocusRequester
}
.width(300.dp),
value = tagField,
singleLine = true,
label = { Text("New tag name", fontSize = 14.sp) },
textStyle = TextStyle(fontSize = 14.sp),
onValueChange = {
tagField = it
},
)
Row(
modifier = Modifier
.padding(top = 16.dp)
.align(Alignment.End)
) {
TextButton(
modifier = Modifier.padding(end = 8.dp),
onClick = {
onReject()
}
) {
Text("Cancel")
}
Button(
modifier = Modifier.focusOrder(buttonFieldFocusRequester) {
this.previous = tagFieldFocusRequester
this.next = tagFieldFocusRequester
},
enabled = tagField.isNotEmpty(),
onClick = {
onAccept(tagField)
}
) {
Text("Create tag")
}
}
}
LaunchedEffect(Unit) {
tagFieldFocusRequester.requestFocus()
}
}