Added stash detail viewing & selected item state management
This commit is contained in:
parent
5493451719
commit
26edec3de3
11
src/main/kotlin/app/extensions/RevCommitExtensions.kt
Normal file
11
src/main/kotlin/app/extensions/RevCommitExtensions.kt
Normal file
@ -0,0 +1,11 @@
|
||||
package app.extensions
|
||||
|
||||
import org.eclipse.jgit.lib.Repository
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
|
||||
fun RevCommit.fullData(repository: Repository): RevCommit? {
|
||||
return if(this.tree == null)
|
||||
repository.parseCommit(this)
|
||||
else
|
||||
this
|
||||
}
|
@ -1,16 +1,13 @@
|
||||
package app.git
|
||||
|
||||
import app.extensions.fullData
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.diff.DiffEntry
|
||||
import org.eclipse.jgit.diff.DiffFormatter
|
||||
import org.eclipse.jgit.diff.EditList
|
||||
import org.eclipse.jgit.dircache.DirCacheIterator
|
||||
import org.eclipse.jgit.lib.Repository
|
||||
import org.eclipse.jgit.patch.HunkHeader
|
||||
import org.eclipse.jgit.revplot.PlotCommit
|
||||
import org.eclipse.jgit.revplot.PlotCommitList
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
import org.eclipse.jgit.revwalk.RevTree
|
||||
import org.eclipse.jgit.revwalk.RevWalk
|
||||
@ -60,11 +57,14 @@ class DiffManager @Inject constructor() {
|
||||
|
||||
|
||||
suspend fun commitDiffEntries(git: Git, commit: RevCommit): List<DiffEntry> = withContext(Dispatchers.IO) {
|
||||
val fullCommit = commit.fullData(git.repository) ?: return@withContext emptyList()
|
||||
|
||||
val repository = git.repository
|
||||
val parent = if (commit.parentCount == 0) {
|
||||
|
||||
val parent = if (fullCommit.parentCount == 0) {
|
||||
null
|
||||
} else
|
||||
commit.parents.first()
|
||||
fullCommit.parents.first().fullData(git.repository)
|
||||
|
||||
val oldTreeParser = if (parent != null)
|
||||
prepareTreeParser(repository, parent)
|
||||
@ -72,7 +72,7 @@ class DiffManager @Inject constructor() {
|
||||
CanonicalTreeParser()
|
||||
}
|
||||
|
||||
val newTreeParser = prepareTreeParser(repository, commit)
|
||||
val newTreeParser = prepareTreeParser(repository, fullCommit)
|
||||
|
||||
return@withContext git.diff()
|
||||
.setNewTree(newTreeParser)
|
||||
|
@ -23,7 +23,6 @@ class StashManager @Inject constructor() {
|
||||
}
|
||||
|
||||
suspend fun popStash(git: Git) = withContext(Dispatchers.IO) {
|
||||
|
||||
git
|
||||
.stashApply()
|
||||
.call()
|
||||
|
@ -26,20 +26,13 @@ import java.awt.Cursor
|
||||
@OptIn(ExperimentalSplitPaneApi::class, androidx.compose.ui.ExperimentalComposeUiApi::class)
|
||||
@Composable
|
||||
fun RepositoryOpenPage(gitManager: GitManager) {
|
||||
var selectedRevCommit by remember {
|
||||
mutableStateOf<RevCommit?>(null)
|
||||
}
|
||||
|
||||
var diffSelected by remember {
|
||||
mutableStateOf<DiffEntryType?>(null)
|
||||
}
|
||||
var uncommitedChangesSelected by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
var showNewBranchDialog by remember { mutableStateOf(false) }
|
||||
|
||||
val selectedIndexCommitLog = remember { mutableStateOf(-1) }
|
||||
var (selectedItem, setSelectedItem) = remember { mutableStateOf<SelectedItem>(SelectedItem.None) }
|
||||
|
||||
if(showNewBranchDialog) {
|
||||
NewBranchDialog(
|
||||
@ -76,7 +69,12 @@ fun RepositoryOpenPage(gitManager: GitManager) {
|
||||
) {
|
||||
Branches(gitManager = gitManager)
|
||||
Tags(gitManager = gitManager)
|
||||
Stashes(gitManager = gitManager)
|
||||
Stashes(
|
||||
gitManager = gitManager,
|
||||
onStashSelected = { stash ->
|
||||
setSelectedItem(SelectedItem.Stash(stash))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,7 +102,7 @@ fun RepositoryOpenPage(gitManager: GitManager) {
|
||||
HorizontalSplitPane(
|
||||
splitPaneState = rememberSplitPaneState(0.9f)
|
||||
) {
|
||||
first() {
|
||||
first {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
@ -114,14 +112,9 @@ fun RepositoryOpenPage(gitManager: GitManager) {
|
||||
null -> {
|
||||
Log(
|
||||
gitManager = gitManager,
|
||||
selectedIndex = selectedIndexCommitLog,
|
||||
onRevCommitSelected = { commit ->
|
||||
selectedRevCommit = commit
|
||||
uncommitedChangesSelected = false
|
||||
},
|
||||
onUncommitedChangesSelected = {
|
||||
gitManager.statusShouldBeUpdated()
|
||||
uncommitedChangesSelected = true
|
||||
selectedItem = selectedItem,
|
||||
onItemSelected = {
|
||||
setSelectedItem(it)
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -160,7 +153,7 @@ fun RepositoryOpenPage(gitManager: GitManager) {
|
||||
modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
) {
|
||||
if (uncommitedChangesSelected) {
|
||||
if (selectedItem == SelectedItem.UncommitedChanges) {
|
||||
UncommitedChanges(
|
||||
gitManager = gitManager,
|
||||
onStagedDiffEntrySelected = { diffEntry ->
|
||||
@ -173,16 +166,14 @@ fun RepositoryOpenPage(gitManager: GitManager) {
|
||||
diffSelected = DiffEntryType.UnstagedDiff(diffEntry)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
selectedRevCommit?.let {
|
||||
CommitChanges(
|
||||
gitManager = gitManager,
|
||||
commit = it,
|
||||
onDiffSelected = { diffEntry ->
|
||||
diffSelected = DiffEntryType.CommitDiff(diffEntry)
|
||||
}
|
||||
)
|
||||
}
|
||||
} else if(selectedItem is SelectedItem.CommitBasedItem) {
|
||||
CommitChanges(
|
||||
gitManager = gitManager,
|
||||
commit = selectedItem.revCommit,
|
||||
onDiffSelected = { diffEntry ->
|
||||
diffSelected = DiffEntryType.CommitDiff(diffEntry)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -192,3 +183,11 @@ fun RepositoryOpenPage(gitManager: GitManager) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class SelectedItem {
|
||||
object None : SelectedItem()
|
||||
object UncommitedChanges : SelectedItem()
|
||||
sealed class CommitBasedItem(val revCommit: RevCommit) : SelectedItem()
|
||||
class Commit(revCommit: RevCommit) : CommitBasedItem(revCommit)
|
||||
class Stash(revCommit: RevCommit) : CommitBasedItem(revCommit)
|
||||
}
|
@ -1,31 +1,23 @@
|
||||
package app.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
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.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.ScrollableLazyColumn
|
||||
import app.ui.components.SideMenuEntry
|
||||
import app.ui.components.SideMenuSubentry
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
|
||||
@Composable
|
||||
fun Stashes(gitManager: GitManager) {
|
||||
fun Stashes(
|
||||
gitManager: GitManager,
|
||||
onStashSelected: (commit: RevCommit) -> Unit,
|
||||
) {
|
||||
val stashStatusState = gitManager.stashStatus.collectAsState()
|
||||
val stashStatus = stashStatusState.value
|
||||
|
||||
@ -44,8 +36,10 @@ fun Stashes(gitManager: GitManager) {
|
||||
items(items = stashList) { stash ->
|
||||
StashRow(
|
||||
stash = stash,
|
||||
onClick = {
|
||||
onStashSelected(stash)
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -53,9 +47,10 @@ fun Stashes(gitManager: GitManager) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StashRow(stash: RevCommit) {
|
||||
private fun StashRow(stash: RevCommit, onClick: () -> Unit) {
|
||||
SideMenuSubentry(
|
||||
text = stash.name,
|
||||
iconResourcePath = "stash.svg",
|
||||
onClick = onClick,
|
||||
)
|
||||
}
|
@ -23,13 +23,14 @@ fun SideMenuSubentry(
|
||||
text: String,
|
||||
iconResourcePath: String,
|
||||
bold: Boolean = false,
|
||||
onClick: () -> Unit = {},
|
||||
additionalInfo: @Composable () -> Unit = {}
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.height(40.dp)
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = {}),
|
||||
.clickable(onClick = onClick),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
|
@ -9,7 +9,7 @@ import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.gestures.draggable
|
||||
import androidx.compose.foundation.gestures.rememberDraggableState
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Icon
|
||||
@ -40,6 +40,7 @@ import app.theme.headerBackground
|
||||
import app.theme.headerText
|
||||
import app.theme.primaryTextColor
|
||||
import app.theme.secondaryTextColor
|
||||
import app.ui.SelectedItem
|
||||
import app.ui.components.ScrollableLazyColumn
|
||||
import app.ui.dialogs.MergeDialog
|
||||
import app.ui.dialogs.NewBranchDialog
|
||||
@ -69,16 +70,19 @@ private const val CANVAS_MIN_WIDTH = 100
|
||||
@Composable
|
||||
fun Log(
|
||||
gitManager: GitManager,
|
||||
onRevCommitSelected: (RevCommit) -> Unit,
|
||||
onUncommitedChangesSelected: () -> Unit,
|
||||
selectedIndex: MutableState<Int> = remember { mutableStateOf(-1) }
|
||||
selectedItem: SelectedItem,
|
||||
onItemSelected: (SelectedItem) -> Unit,
|
||||
) {
|
||||
val logStatusState = gitManager.logStatus.collectAsState()
|
||||
val logStatus = logStatusState.value
|
||||
|
||||
val selectedUncommited = remember { mutableStateOf(false) }
|
||||
val showLogDialog = remember { mutableStateOf<LogDialog>(LogDialog.None) }
|
||||
|
||||
val selectedCommit = if (selectedItem is SelectedItem.Commit) {
|
||||
selectedItem.revCommit
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
if (logStatus is LogStatus.Loaded) {
|
||||
val commitList = logStatus.plotCommitList
|
||||
@ -115,23 +119,20 @@ fun Log(
|
||||
if (hasUncommitedChanges)
|
||||
item {
|
||||
UncommitedChangesLine(
|
||||
selected = selectedUncommited.value,
|
||||
selected = selectedItem == SelectedItem.UncommitedChanges,
|
||||
hasPreviousCommits = commitList.count() > 0,
|
||||
graphWidth = graphWidth,
|
||||
weightMod = weightMod,
|
||||
onUncommitedChangesSelected = {
|
||||
selectedIndex.value = -1
|
||||
selectedUncommited.value = true
|
||||
onUncommitedChangesSelected()
|
||||
onItemSelected(SelectedItem.UncommitedChanges)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
itemsIndexed(items = commitList) { index, graphNode ->
|
||||
items(items = commitList) { graphNode ->
|
||||
CommitLine(
|
||||
gitManager = gitManager,
|
||||
graphNode = graphNode,
|
||||
selected = selectedIndex.value == index,
|
||||
selected = selectedCommit?.name == graphNode.name,
|
||||
weightMod = weightMod,
|
||||
graphWidth = graphWidth,
|
||||
currentBranch = logStatus.currentBranch,
|
||||
@ -140,9 +141,7 @@ fun Log(
|
||||
resetBranch = { showLogDialog.value = LogDialog.ResetBranch(graphNode) },
|
||||
onMergeBranch = { ref -> showLogDialog.value = LogDialog.MergeBranch(ref) },
|
||||
onRevCommitSelected = {
|
||||
selectedIndex.value = index
|
||||
selectedUncommited.value = false
|
||||
onRevCommitSelected(it)
|
||||
onItemSelected(SelectedItem.Commit(graphNode))
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -197,7 +196,8 @@ fun LogDialogs(
|
||||
onResetShowLogDialog()
|
||||
}
|
||||
)
|
||||
LogDialog.None -> {}
|
||||
LogDialog.None -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user