Log full cleanup
- Refactored log function into multiple sub functions - Removed use of DialogManager from Log - Merge branch now shows current branch instead of hardcoded "HEAD"
This commit is contained in:
parent
f9a2917bbd
commit
6c1dc32928
@ -20,6 +20,15 @@ class BranchesManager @Inject constructor() {
|
||||
val currentBranch: StateFlow<String>
|
||||
get() = _currentBranch
|
||||
|
||||
suspend fun currentBranchRef(git: Git): Ref? {
|
||||
val branchList = getBranches(git)
|
||||
val branchName = git
|
||||
.repository
|
||||
.fullBranch
|
||||
|
||||
return branchList.firstOrNull { it.name == branchName }
|
||||
}
|
||||
|
||||
suspend fun loadBranches(git: Git) = withContext(Dispatchers.IO) {
|
||||
val branchList = getBranches(git)
|
||||
|
||||
@ -58,7 +67,7 @@ class BranchesManager @Inject constructor() {
|
||||
}
|
||||
|
||||
suspend fun mergeBranch(git: Git, branch: Ref, fastForward: Boolean) = withContext(Dispatchers.IO) {
|
||||
val fastForwardMode = if(fastForward)
|
||||
val fastForwardMode = if (fastForward)
|
||||
MergeCommand.FastForwardMode.FF
|
||||
else
|
||||
MergeCommand.FastForwardMode.NO_FF
|
||||
|
@ -21,6 +21,7 @@ import javax.inject.Inject
|
||||
|
||||
class LogManager @Inject constructor(
|
||||
private val statusManager: StatusManager,
|
||||
private val branchesManager: BranchesManager,
|
||||
) {
|
||||
private val _logStatus = MutableStateFlow<LogStatus>(LogStatus.Loading)
|
||||
|
||||
@ -49,7 +50,7 @@ class LogManager @Inject constructor(
|
||||
|
||||
ensureActive()
|
||||
|
||||
val loadedStatus = LogStatus.Loaded(commitList)
|
||||
val loadedStatus = LogStatus.Loaded(commitList, branchesManager.currentBranchRef(git))
|
||||
|
||||
_logStatus.value = loadedStatus
|
||||
}
|
||||
@ -102,5 +103,5 @@ enum class ResetType {
|
||||
|
||||
sealed class LogStatus {
|
||||
object Loading : LogStatus()
|
||||
class Loaded(val plotCommitList: GraphCommitList) : LogStatus()
|
||||
class Loaded(val plotCommitList: GraphCommitList, val currentBranch: Ref?) : LogStatus()
|
||||
}
|
@ -4,22 +4,18 @@ import androidx.compose.animation.Crossfade
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
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.unit.dp
|
||||
import app.DialogManager
|
||||
import app.credentials.CredentialsState
|
||||
import app.git.DiffEntryType
|
||||
import app.git.GitManager
|
||||
import app.ui.dialogs.NewBranchDialog
|
||||
import app.ui.dialogs.PasswordDialog
|
||||
import app.ui.dialogs.UserPasswordDialog
|
||||
import app.ui.log.Log
|
||||
import openRepositoryDialog
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
import org.jetbrains.compose.splitpane.ExperimentalSplitPaneApi
|
||||
|
@ -27,76 +27,78 @@ fun MergeDialog(
|
||||
) {
|
||||
var fastForwardCheck by remember { mutableStateOf(fastForward) }
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(MaterialTheme.colors.background),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
|
||||
|
||||
Text(
|
||||
text = mergeBranchName,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
|
||||
|
||||
Text(
|
||||
text = "will be merged into",
|
||||
modifier = Modifier.padding(horizontal = 8.dp)
|
||||
)
|
||||
|
||||
Text(
|
||||
text = currentBranchName,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
}
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
MaterialDialog {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.mouseClickable {
|
||||
if(this.buttons.isPrimaryPressed) {
|
||||
fastForwardCheck = !fastForwardCheck
|
||||
}
|
||||
}
|
||||
.background(MaterialTheme.colors.background),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Checkbox(
|
||||
checked = fastForwardCheck,
|
||||
onCheckedChange = { checked ->
|
||||
fastForwardCheck = checked
|
||||
}
|
||||
)
|
||||
|
||||
Text(
|
||||
"Fast forward",
|
||||
modifier = Modifier
|
||||
.padding(start = 8.dp)
|
||||
)
|
||||
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(top = 16.dp)
|
||||
.align(Alignment.End)
|
||||
) {
|
||||
TextButton(
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
onClick = {
|
||||
onReject()
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text("Cancel")
|
||||
|
||||
|
||||
Text(
|
||||
text = mergeBranchName,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
|
||||
|
||||
Text(
|
||||
text = "will be merged into",
|
||||
modifier = Modifier.padding(horizontal = 8.dp)
|
||||
)
|
||||
|
||||
Text(
|
||||
text = currentBranchName,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
}
|
||||
Button(
|
||||
onClick = {
|
||||
onAccept(fastForwardCheck)
|
||||
}
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.mouseClickable {
|
||||
if (this.buttons.isPrimaryPressed) {
|
||||
fastForwardCheck = !fastForwardCheck
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text("Merge")
|
||||
Checkbox(
|
||||
checked = fastForwardCheck,
|
||||
onCheckedChange = { checked ->
|
||||
fastForwardCheck = checked
|
||||
}
|
||||
)
|
||||
|
||||
Text(
|
||||
"Fast forward",
|
||||
modifier = Modifier
|
||||
.padding(start = 8.dp)
|
||||
)
|
||||
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(top = 16.dp)
|
||||
.align(Alignment.End)
|
||||
) {
|
||||
TextButton(
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
onClick = {
|
||||
onReject()
|
||||
}
|
||||
) {
|
||||
Text("Cancel")
|
||||
}
|
||||
Button(
|
||||
onClick = {
|
||||
onAccept(fastForwardCheck)
|
||||
}
|
||||
) {
|
||||
Text("Merge")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,63 +26,65 @@ fun NewTagDialog(
|
||||
val tagFieldFocusRequester = remember { FocusRequester() }
|
||||
val buttonFieldFocusRequester = remember { FocusRequester() }
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(MaterialTheme.colors.background),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
OutlinedTextField(
|
||||
MaterialDialog {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.focusOrder(tagFieldFocusRequester) {
|
||||
this.next = buttonFieldFocusRequester
|
||||
}
|
||||
.width(300.dp)
|
||||
.onPreviewKeyEvent {
|
||||
if(it.key == Key.Enter) {
|
||||
onAccept(tagField)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
},
|
||||
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)
|
||||
.background(MaterialTheme.colors.background),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
TextButton(
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
onClick = {
|
||||
onReject()
|
||||
}
|
||||
) {
|
||||
Text("Cancel")
|
||||
}
|
||||
Button(
|
||||
modifier = Modifier.focusOrder(buttonFieldFocusRequester) {
|
||||
this.previous = tagFieldFocusRequester
|
||||
this.next = tagFieldFocusRequester
|
||||
OutlinedTextField(
|
||||
modifier = Modifier
|
||||
.focusOrder(tagFieldFocusRequester) {
|
||||
this.next = buttonFieldFocusRequester
|
||||
}
|
||||
.width(300.dp)
|
||||
.onPreviewKeyEvent {
|
||||
if (it.key == Key.Enter) {
|
||||
onAccept(tagField)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
},
|
||||
value = tagField,
|
||||
singleLine = true,
|
||||
label = { Text("New tag name", fontSize = 14.sp) },
|
||||
textStyle = TextStyle(fontSize = 14.sp),
|
||||
onValueChange = {
|
||||
tagField = it
|
||||
},
|
||||
enabled = tagField.isNotEmpty(),
|
||||
onClick = {
|
||||
onAccept(tagField)
|
||||
}
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(top = 16.dp)
|
||||
.align(Alignment.End)
|
||||
) {
|
||||
Text("Create tag")
|
||||
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()
|
||||
LaunchedEffect(Unit) {
|
||||
tagFieldFocusRequester.requestFocus()
|
||||
}
|
||||
}
|
||||
}
|
@ -24,51 +24,53 @@ fun ResetBranchDialog(
|
||||
) {
|
||||
var resetType by remember { mutableStateOf(ResetType.MIXED) }
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(MaterialTheme.colors.background),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
RadioButtonText(
|
||||
selected = resetType == ResetType.SOFT,
|
||||
onClick = {
|
||||
resetType = ResetType.SOFT
|
||||
},
|
||||
text = "Soft reset"
|
||||
)
|
||||
RadioButtonText(
|
||||
selected = resetType == ResetType.MIXED,
|
||||
onClick = {
|
||||
resetType = ResetType.MIXED
|
||||
},
|
||||
text = "Mixed reset"
|
||||
)
|
||||
RadioButtonText(
|
||||
selected = resetType == ResetType.HARD,
|
||||
onClick = {
|
||||
resetType = ResetType.HARD
|
||||
},
|
||||
text = "Hard reset"
|
||||
)
|
||||
Row(
|
||||
MaterialDialog {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(top = 16.dp)
|
||||
.align(Alignment.End)
|
||||
.background(MaterialTheme.colors.background),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
TextButton(
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
RadioButtonText(
|
||||
selected = resetType == ResetType.SOFT,
|
||||
onClick = {
|
||||
onReject()
|
||||
}
|
||||
) {
|
||||
Text("Cancel")
|
||||
}
|
||||
Button(
|
||||
resetType = ResetType.SOFT
|
||||
},
|
||||
text = "Soft reset"
|
||||
)
|
||||
RadioButtonText(
|
||||
selected = resetType == ResetType.MIXED,
|
||||
onClick = {
|
||||
onAccept(resetType)
|
||||
}
|
||||
resetType = ResetType.MIXED
|
||||
},
|
||||
text = "Mixed reset"
|
||||
)
|
||||
RadioButtonText(
|
||||
selected = resetType == ResetType.HARD,
|
||||
onClick = {
|
||||
resetType = ResetType.HARD
|
||||
},
|
||||
text = "Hard reset"
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(top = 16.dp)
|
||||
.align(Alignment.End)
|
||||
) {
|
||||
Text("Reset branch")
|
||||
TextButton(
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
onClick = {
|
||||
onReject()
|
||||
}
|
||||
) {
|
||||
Text("Cancel")
|
||||
}
|
||||
Button(
|
||||
onClick = {
|
||||
onAccept(resetType)
|
||||
}
|
||||
) {
|
||||
Text("Reset branch")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
@file:Suppress("UNUSED_PARAMETER")
|
||||
|
||||
package app.ui
|
||||
package app.ui.log
|
||||
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
@ -32,7 +32,6 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import app.DialogManager
|
||||
import app.extensions.*
|
||||
import app.git.GitManager
|
||||
import app.git.LogStatus
|
||||
@ -46,6 +45,7 @@ import app.ui.dialogs.MergeDialog
|
||||
import app.ui.dialogs.NewBranchDialog
|
||||
import app.ui.dialogs.NewTagDialog
|
||||
import app.ui.dialogs.ResetBranchDialog
|
||||
import app.ui.rememberNetworkImage
|
||||
import org.eclipse.jgit.lib.Ref
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
|
||||
@ -69,7 +69,6 @@ private const val CANVAS_MIN_WIDTH = 100
|
||||
@Composable
|
||||
fun Log(
|
||||
gitManager: GitManager,
|
||||
dialogManager: DialogManager,
|
||||
onRevCommitSelected: (RevCommit) -> Unit,
|
||||
onUncommitedChangesSelected: () -> Unit,
|
||||
selectedIndex: MutableState<Int> = remember { mutableStateOf(-1) }
|
||||
@ -78,11 +77,20 @@ fun Log(
|
||||
val logStatus = logStatusState.value
|
||||
|
||||
val selectedUncommited = remember { mutableStateOf(false) }
|
||||
val showLogDialog = remember { mutableStateOf<LogDialog>(LogDialog.None) }
|
||||
|
||||
|
||||
if (logStatus is LogStatus.Loaded) {
|
||||
val commitList = logStatus.plotCommitList
|
||||
|
||||
Box(
|
||||
LogDialogs(
|
||||
gitManager,
|
||||
currentBranch = logStatus.currentBranch,
|
||||
onResetShowLogDialog = { showLogDialog.value = LogDialog.None },
|
||||
showLogDialog = showLogDialog.value,
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
.background(MaterialTheme.colors.background)
|
||||
@ -95,112 +103,41 @@ fun Log(
|
||||
if (graphWidth.value < CANVAS_MIN_WIDTH)
|
||||
graphWidth = CANVAS_MIN_WIDTH.dp
|
||||
|
||||
GraphHeader(
|
||||
graphWidth = graphWidth,
|
||||
weightMod = weightMod,
|
||||
)
|
||||
ScrollableLazyColumn(
|
||||
modifier = Modifier
|
||||
.background(MaterialTheme.colors.background)
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
|
||||
stickyHeader {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(32.dp)
|
||||
.background(MaterialTheme.colors.headerBackground),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.width(graphWidth)
|
||||
.padding(start = 8.dp),
|
||||
text = "Graph",
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = MaterialTheme.colors.headerText,
|
||||
fontSize = 14.sp,
|
||||
maxLines = 1,
|
||||
)
|
||||
|
||||
DividerLog(
|
||||
modifier = Modifier.draggable(rememberDraggableState {
|
||||
weightMod.value += it
|
||||
}, Orientation.Horizontal)
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = 8.dp)
|
||||
.width(graphWidth),
|
||||
text = "Message",
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = MaterialTheme.colors.headerText,
|
||||
fontSize = 14.sp,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (hasUncommitedChanges)
|
||||
item {
|
||||
val textColor = if (selectedUncommited.value) {
|
||||
MaterialTheme.colors.primary
|
||||
} else
|
||||
MaterialTheme.colors.primaryTextColor
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.height(40.dp)
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
selectedIndex.value = -1
|
||||
selectedUncommited.value = true
|
||||
onUncommitedChangesSelected()
|
||||
},
|
||||
) {
|
||||
val hasPreviousCommits = commitList.count() > 0
|
||||
|
||||
UncommitedChangesGraphLine(
|
||||
modifier = Modifier
|
||||
.width(graphWidth),
|
||||
hasPreviousCommits = hasPreviousCommits,
|
||||
)
|
||||
|
||||
DividerLog(
|
||||
modifier = Modifier
|
||||
.draggable(
|
||||
rememberDraggableState {
|
||||
weightMod.value += it
|
||||
},
|
||||
Orientation.Horizontal
|
||||
)
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Spacer(modifier = Modifier.weight(2f))
|
||||
|
||||
Text(
|
||||
text = "Uncommited changes",
|
||||
fontStyle = FontStyle.Italic,
|
||||
modifier = Modifier.padding(start = 16.dp),
|
||||
fontSize = 14.sp,
|
||||
color = textColor,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.weight(2f))
|
||||
UncommitedChangesLine(
|
||||
selected = selectedUncommited.value,
|
||||
hasPreviousCommits = commitList.count() > 0,
|
||||
graphWidth = graphWidth,
|
||||
weightMod = weightMod,
|
||||
onUncommitedChangesSelected = {
|
||||
selectedIndex.value = -1
|
||||
selectedUncommited.value = true
|
||||
onUncommitedChangesSelected()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
itemsIndexed(items = commitList) { index, graphNode ->
|
||||
CommitLine(
|
||||
gitManager = gitManager,
|
||||
dialogManager = dialogManager,
|
||||
graphNode = graphNode,
|
||||
selected = selectedIndex.value == index,
|
||||
weightMod = weightMod,
|
||||
graphWidth = graphWidth,
|
||||
showCreateNewBranch = { showLogDialog.value = LogDialog.NewBranch(graphNode) },
|
||||
showCreateNewTag = { showLogDialog.value = LogDialog.NewTag(graphNode) },
|
||||
resetBranch = { showLogDialog.value = LogDialog.ResetBranch(graphNode) },
|
||||
onMergeBranch = { ref -> showLogDialog.value = LogDialog.MergeBranch(ref) },
|
||||
onRevCommitSelected = {
|
||||
selectedIndex.value = index
|
||||
selectedUncommited.value = false
|
||||
@ -214,28 +151,167 @@ fun Log(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LogDialogs(
|
||||
gitManager: GitManager,
|
||||
onResetShowLogDialog: () -> Unit,
|
||||
showLogDialog: LogDialog,
|
||||
currentBranch: Ref?,
|
||||
) {
|
||||
when(showLogDialog) {
|
||||
is LogDialog.NewBranch -> {
|
||||
NewBranchDialog(
|
||||
onReject = onResetShowLogDialog,
|
||||
onAccept = { branchName ->
|
||||
gitManager.createBranchOnCommit(branchName, showLogDialog.graphNode)
|
||||
onResetShowLogDialog()
|
||||
}
|
||||
)
|
||||
}
|
||||
is LogDialog.NewTag -> {
|
||||
NewTagDialog(
|
||||
onReject = onResetShowLogDialog,
|
||||
onAccept = { tagName ->
|
||||
gitManager.createTagOnCommit(tagName, showLogDialog.graphNode)
|
||||
onResetShowLogDialog()
|
||||
}
|
||||
)
|
||||
}
|
||||
is LogDialog.MergeBranch -> {
|
||||
if(currentBranch != null)
|
||||
MergeDialog(
|
||||
currentBranchName = currentBranch.simpleName,
|
||||
mergeBranchName = showLogDialog.ref.simpleName,
|
||||
onReject = onResetShowLogDialog,
|
||||
onAccept = { ff ->
|
||||
gitManager.mergeBranch(showLogDialog.ref, ff)
|
||||
onResetShowLogDialog()
|
||||
}
|
||||
)
|
||||
}
|
||||
is LogDialog.ResetBranch -> ResetBranchDialog(
|
||||
onReject = onResetShowLogDialog,
|
||||
onAccept = { resetType ->
|
||||
gitManager.resetToCommit(showLogDialog.graphNode, resetType)
|
||||
onResetShowLogDialog()
|
||||
}
|
||||
)
|
||||
LogDialog.None -> {}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun GraphHeader(
|
||||
graphWidth: Dp,
|
||||
weightMod: MutableState<Float>,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(32.dp)
|
||||
.background(MaterialTheme.colors.headerBackground),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.width(graphWidth)
|
||||
.padding(start = 8.dp),
|
||||
text = "Graph",
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = MaterialTheme.colors.headerText,
|
||||
fontSize = 14.sp,
|
||||
maxLines = 1,
|
||||
)
|
||||
|
||||
DividerLog(
|
||||
modifier = Modifier.draggable(rememberDraggableState {
|
||||
weightMod.value += it
|
||||
}, Orientation.Horizontal)
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = 8.dp)
|
||||
.width(graphWidth),
|
||||
text = "Message",
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = MaterialTheme.colors.headerText,
|
||||
fontSize = 14.sp,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun UncommitedChangesLine(
|
||||
selected: Boolean,
|
||||
hasPreviousCommits: Boolean,
|
||||
graphWidth: Dp,
|
||||
weightMod: MutableState<Float>,
|
||||
onUncommitedChangesSelected: () -> Unit
|
||||
) {
|
||||
val textColor = if (selected) {
|
||||
MaterialTheme.colors.primary
|
||||
} else
|
||||
MaterialTheme.colors.primaryTextColor
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.height(40.dp)
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
onUncommitedChangesSelected()
|
||||
},
|
||||
) {
|
||||
UncommitedChangesGraphLine(
|
||||
modifier = Modifier
|
||||
.width(graphWidth),
|
||||
hasPreviousCommits = hasPreviousCommits,
|
||||
)
|
||||
|
||||
DividerLog(
|
||||
modifier = Modifier
|
||||
.draggable(
|
||||
rememberDraggableState {
|
||||
weightMod.value += it
|
||||
},
|
||||
Orientation.Horizontal
|
||||
)
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Spacer(modifier = Modifier.weight(2f))
|
||||
|
||||
Text(
|
||||
text = "Uncommited changes",
|
||||
fontStyle = FontStyle.Italic,
|
||||
modifier = Modifier.padding(start = 16.dp),
|
||||
fontSize = 14.sp,
|
||||
color = textColor,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.weight(2f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun CommitLine(
|
||||
gitManager: GitManager,
|
||||
dialogManager: DialogManager,
|
||||
graphNode: GraphNode,
|
||||
selected: Boolean,
|
||||
weightMod: MutableState<Float>,
|
||||
graphWidth: Dp,
|
||||
showCreateNewBranch: () -> Unit,
|
||||
showCreateNewTag: () -> Unit,
|
||||
resetBranch: (GraphNode) -> Unit,
|
||||
onMergeBranch: (Ref) -> Unit,
|
||||
onRevCommitSelected: (GraphNode) -> Unit,
|
||||
) {
|
||||
val commitRefs = graphNode.refs
|
||||
var showCreateBranchDialog by remember(graphNode.id.name) { mutableStateOf(false) }
|
||||
if(showCreateBranchDialog)
|
||||
NewBranchDialog(
|
||||
onReject = {
|
||||
showCreateBranchDialog = false
|
||||
},
|
||||
onAccept = { branchName ->
|
||||
gitManager.createBranchOnCommit(branchName, graphNode)
|
||||
showCreateBranchDialog = false
|
||||
}
|
||||
)
|
||||
|
||||
Box(modifier = Modifier
|
||||
.clickable {
|
||||
@ -252,48 +328,20 @@ fun CommitLine(
|
||||
}),
|
||||
ContextMenuItem(
|
||||
label = "Create branch",
|
||||
onClick = {
|
||||
showCreateBranchDialog = true
|
||||
}
|
||||
onClick = showCreateNewBranch
|
||||
),
|
||||
ContextMenuItem(
|
||||
label = "Create tag",
|
||||
onClick = {
|
||||
dialogManager.show {
|
||||
NewTagDialog(
|
||||
onReject = {
|
||||
dialogManager.dismiss()
|
||||
},
|
||||
onAccept = { tagName ->
|
||||
gitManager.createTagOnCommit(tagName, graphNode)
|
||||
dialogManager.dismiss()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
onClick = showCreateNewTag
|
||||
),
|
||||
ContextMenuItem(
|
||||
label = "Revert commit",
|
||||
onClick = {
|
||||
gitManager.revertCommit(graphNode)
|
||||
}
|
||||
onClick = { gitManager.revertCommit(graphNode) }
|
||||
),
|
||||
|
||||
ContextMenuItem(
|
||||
label = "Reset current branch to this commit",
|
||||
onClick = {
|
||||
dialogManager.show {
|
||||
ResetBranchDialog(
|
||||
onReject = {
|
||||
dialogManager.dismiss()
|
||||
},
|
||||
onAccept = { resetType ->
|
||||
dialogManager.dismiss()
|
||||
gitManager.resetToCommit(graphNode, resetType)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
onClick = { resetBranch(graphNode) }
|
||||
)
|
||||
)
|
||||
},
|
||||
@ -326,21 +374,7 @@ fun CommitLine(
|
||||
selected = selected,
|
||||
refs = commitRefs,
|
||||
onCheckoutRef = { ref -> gitManager.checkoutRef(ref) },
|
||||
onMergeBranch = { ref ->
|
||||
dialogManager.show {
|
||||
MergeDialog(
|
||||
currentBranchName = "HEAD",
|
||||
mergeBranchName = ref.simpleName,
|
||||
onReject = {
|
||||
dialogManager.dismiss()
|
||||
},
|
||||
onAccept = { fastForward ->
|
||||
dialogManager.dismiss()
|
||||
gitManager.mergeBranch(ref, fastForward)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
onMergeBranch = { ref -> onMergeBranch(ref) },
|
||||
onDeleteBranch = { ref -> gitManager.deleteBranch(ref) }
|
||||
)
|
||||
}
|
12
src/main/kotlin/app/ui/log/LogDialog.kt
Normal file
12
src/main/kotlin/app/ui/log/LogDialog.kt
Normal file
@ -0,0 +1,12 @@
|
||||
package app.ui.log
|
||||
|
||||
import app.git.graph.GraphNode
|
||||
import org.eclipse.jgit.lib.Ref
|
||||
|
||||
sealed class LogDialog {
|
||||
object None: LogDialog()
|
||||
data class NewBranch(val graphNode: GraphNode): LogDialog()
|
||||
data class NewTag(val graphNode: GraphNode): LogDialog()
|
||||
data class ResetBranch(val graphNode: GraphNode): LogDialog()
|
||||
data class MergeBranch(val ref: Ref): LogDialog()
|
||||
}
|
Loading…
Reference in New Issue
Block a user