Implemented stash and refactored hasUncommitedChanges code
This commit is contained in:
parent
719d4a2654
commit
04a9fc2c25
@ -23,6 +23,7 @@ class GitManager {
|
|||||||
private val logManager = LogManager()
|
private val logManager = LogManager()
|
||||||
private val remoteOperationsManager = RemoteOperationsManager()
|
private val remoteOperationsManager = RemoteOperationsManager()
|
||||||
private val branchesManager = BranchesManager()
|
private val branchesManager = BranchesManager()
|
||||||
|
private val stashManager = StashManager()
|
||||||
|
|
||||||
private val managerScope = CoroutineScope(SupervisorJob())
|
private val managerScope = CoroutineScope(SupervisorJob())
|
||||||
|
|
||||||
@ -43,6 +44,9 @@ class GitManager {
|
|||||||
val branches: StateFlow<List<Ref>>
|
val branches: StateFlow<List<Ref>>
|
||||||
get() = branchesManager.branches
|
get() = branchesManager.branches
|
||||||
|
|
||||||
|
val stashStatus: StateFlow<StashStatus>
|
||||||
|
get() = stashManager.stashStatus
|
||||||
|
|
||||||
val latestDirectoryOpened: File?
|
val latestDirectoryOpened: File?
|
||||||
get() = File(preferences.latestOpenedRepositoryPath).parentFile
|
get() = File(preferences.latestOpenedRepositoryPath).parentFile
|
||||||
|
|
||||||
@ -124,7 +128,8 @@ class GitManager {
|
|||||||
logManager.loadLog(safeGit)
|
logManager.loadLog(safeGit)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasUncommitedChanges(): Boolean = statusManager.hasUncommitedChanges(safeGit)
|
val hasUncommitedChanges: StateFlow<Boolean>
|
||||||
|
get() = statusManager.hasUncommitedChanges
|
||||||
|
|
||||||
fun diffFormat(diffEntry: DiffEntry): String {
|
fun diffFormat(diffEntry: DiffEntry): String {
|
||||||
val byteArrayOutputStream = ByteArrayOutputStream()
|
val byteArrayOutputStream = ByteArrayOutputStream()
|
||||||
@ -155,9 +160,19 @@ class GitManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun refreshRepositoryInfo() = managerScope.launch {
|
private fun refreshRepositoryInfo() = managerScope.launch {
|
||||||
|
statusManager.loadHasUncommitedChanges(safeGit)
|
||||||
branchesManager.loadBranches(safeGit)
|
branchesManager.loadBranches(safeGit)
|
||||||
|
stashManager.loadStashList(safeGit)
|
||||||
loadLog()
|
loadLog()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun stash() = managerScope.launch {
|
||||||
|
stashManager.stash(safeGit)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun popStash() = managerScope.launch {
|
||||||
|
stashManager.popStash(safeGit)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import androidx.compose.material.MaterialTheme
|
|||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.font.FontStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import git.LogStatus
|
import git.LogStatus
|
||||||
@ -39,12 +40,15 @@ fun Log(
|
|||||||
.background(MaterialTheme.colors.surface)
|
.background(MaterialTheme.colors.surface)
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
|
val hasUncommitedChanges by gitManager.hasUncommitedChanges.collectAsState()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.background(MaterialTheme.colors.surface)
|
.background(MaterialTheme.colors.surface)
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
if (gitManager.hasUncommitedChanges())
|
|
||||||
|
if (hasUncommitedChanges)
|
||||||
item {
|
item {
|
||||||
val textColor = if (selectedUncommited.value) {
|
val textColor = if (selectedUncommited.value) {
|
||||||
MaterialTheme.colors.primary
|
MaterialTheme.colors.primary
|
||||||
@ -66,12 +70,13 @@ fun Log(
|
|||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = "Uncommited changes",
|
text = "Uncommited changes",
|
||||||
fontWeight = FontWeight.Bold,
|
fontStyle = FontStyle.Italic,
|
||||||
modifier = Modifier.padding(start = 16.dp),
|
modifier = Modifier.padding(start = 16.dp),
|
||||||
color = textColor,
|
color = textColor,
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text = "You",
|
text = "You",
|
||||||
|
fontStyle = FontStyle.Italic,
|
||||||
modifier = Modifier.padding(start = 16.dp),
|
modifier = Modifier.padding(start = 16.dp),
|
||||||
color = MaterialTheme.colors.secondaryTextColor,
|
color = MaterialTheme.colors.secondaryTextColor,
|
||||||
)
|
)
|
||||||
|
@ -29,12 +29,13 @@ fun RepositorySelected(gitManager: GitManager, repository: Repository) {
|
|||||||
val selectedIndexCommitLog = remember { mutableStateOf(-1) }
|
val selectedIndexCommitLog = remember { mutableStateOf(-1) }
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
Box(
|
Column (
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(0.15f)
|
.weight(0.15f)
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
) {
|
) {
|
||||||
Branches(gitManager = gitManager)
|
Branches(gitManager = gitManager)
|
||||||
|
Stashes(gitManager = gitManager)
|
||||||
}
|
}
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
102
src/main/kotlin/Stashes.kt
Normal file
102
src/main/kotlin/Stashes.kt
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
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.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 git.StashStatus
|
||||||
|
import org.eclipse.jgit.revwalk.RevCommit
|
||||||
|
import theme.headerBackground
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Stashes(gitManager: GitManager) {
|
||||||
|
val stashStatusState = gitManager.stashStatus.collectAsState()
|
||||||
|
val stashStatus = stashStatusState.value
|
||||||
|
|
||||||
|
val stashList = if (stashStatus is StashStatus.Loaded)
|
||||||
|
stashStatus.stashes
|
||||||
|
else
|
||||||
|
listOf()
|
||||||
|
|
||||||
|
Card(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.fillMaxHeight(0.5f)
|
||||||
|
.padding(8.dp)
|
||||||
|
) {
|
||||||
|
Column {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(MaterialTheme.colors.headerBackground)
|
||||||
|
.padding(vertical = 16.dp)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
text = "Stashes",
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
color = MaterialTheme.colors.primary,
|
||||||
|
maxLines = 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
LazyColumn(modifier = Modifier.weight(5f)) {
|
||||||
|
items(items = stashList) { stash ->
|
||||||
|
StashRow(
|
||||||
|
stash = stash,
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun StashRow(stash: RevCommit) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.height(56.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clickable(onClick = {}),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
|
||||||
|
Icon(
|
||||||
|
painter = painterResource("stash.svg"),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.size(24.dp),
|
||||||
|
tint = MaterialTheme.colors.primary,
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = stash.name,
|
||||||
|
modifier = Modifier.weight(1f, fill = true),
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
)
|
||||||
|
|
||||||
|
IconButton(
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.size(32.dp)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.MoreVert,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = MaterialTheme.colors.primary,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
46
src/main/kotlin/git/StashManager.kt
Normal file
46
src/main/kotlin/git/StashManager.kt
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.eclipse.jgit.api.Git
|
||||||
|
import org.eclipse.jgit.revwalk.RevCommit
|
||||||
|
|
||||||
|
class StashManager {
|
||||||
|
private val _stashStatus = MutableStateFlow<StashStatus>(StashStatus.Loaded(listOf()))
|
||||||
|
val stashStatus: StateFlow<StashStatus>
|
||||||
|
get() = _stashStatus
|
||||||
|
|
||||||
|
suspend fun stash(git: Git) = withContext(Dispatchers.IO) {
|
||||||
|
git
|
||||||
|
.stashCreate()
|
||||||
|
.call()
|
||||||
|
|
||||||
|
loadStashList(git)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun popStash(git: Git) = withContext(Dispatchers.IO) {
|
||||||
|
git
|
||||||
|
.stashApply()
|
||||||
|
.call()
|
||||||
|
|
||||||
|
loadStashList(git)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun loadStashList(git: Git) = withContext(Dispatchers.IO) {
|
||||||
|
_stashStatus.value = StashStatus.Loading
|
||||||
|
|
||||||
|
val stashList = git
|
||||||
|
.stashList()
|
||||||
|
.call()
|
||||||
|
|
||||||
|
_stashStatus.value = StashStatus.Loaded(stashList.toList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sealed class StashStatus {
|
||||||
|
object Loading : StashStatus()
|
||||||
|
data class Loaded(val stashes: List<RevCommit>) : StashStatus()
|
||||||
|
}
|
@ -15,11 +15,17 @@ class StatusManager {
|
|||||||
val stageStatus: StateFlow<StageStatus>
|
val stageStatus: StateFlow<StageStatus>
|
||||||
get() = _stageStatus
|
get() = _stageStatus
|
||||||
|
|
||||||
fun hasUncommitedChanges(git: Git): Boolean {
|
private val _hasUncommitedChanges = MutableStateFlow<Boolean>(false)
|
||||||
return git
|
val hasUncommitedChanges: StateFlow<Boolean>
|
||||||
|
get() = _hasUncommitedChanges
|
||||||
|
|
||||||
|
suspend fun loadHasUncommitedChanges(git: Git) = withContext(Dispatchers.IO) {
|
||||||
|
val hasUncommitedChanges = git
|
||||||
.status()
|
.status()
|
||||||
.call()
|
.call()
|
||||||
.hasUncommittedChanges()
|
.hasUncommittedChanges()
|
||||||
|
|
||||||
|
_hasUncommitedChanges.value = hasUncommitedChanges
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun loadStatus(git: Git) = withContext(Dispatchers.IO) {
|
suspend fun loadStatus(git: Git) = withContext(Dispatchers.IO) {
|
||||||
|
@ -57,7 +57,9 @@ fun Gitnuro(gitManager: GitManager) {
|
|||||||
gitManager.openRepository(f.selectedFile)
|
gitManager.openRepository(f.selectedFile)
|
||||||
},
|
},
|
||||||
onPull = { gitManager.pull() },
|
onPull = { gitManager.pull() },
|
||||||
onPush = { gitManager.push() }
|
onPush = { gitManager.push() },
|
||||||
|
onStash = { gitManager.stash() },
|
||||||
|
onPopStash = { gitManager.popStash() },
|
||||||
)
|
)
|
||||||
|
|
||||||
Crossfade(targetState = repositorySelectionStatus) {
|
Crossfade(targetState = repositorySelectionStatus) {
|
||||||
@ -100,6 +102,8 @@ fun GMenu(
|
|||||||
onRepositoryOpen: () -> Unit,
|
onRepositoryOpen: () -> Unit,
|
||||||
onPull: () -> Unit,
|
onPull: () -> Unit,
|
||||||
onPush: () -> Unit,
|
onPush: () -> Unit,
|
||||||
|
onStash: () -> Unit,
|
||||||
|
onPopStash: () -> Unit,
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@ -122,5 +126,15 @@ fun GMenu(
|
|||||||
) {
|
) {
|
||||||
Text("Push")
|
Text("Push")
|
||||||
}
|
}
|
||||||
|
OutlinedButton(
|
||||||
|
onClick = onStash
|
||||||
|
) {
|
||||||
|
Text("Stash")
|
||||||
|
}
|
||||||
|
OutlinedButton(
|
||||||
|
onClick = onPopStash
|
||||||
|
) {
|
||||||
|
Text("Pop stash")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
1
src/main/resources/branch.svg
Normal file
1
src/main/resources/branch.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" ?><svg height="1024" width="640" xmlns="http://www.w3.org/2000/svg"><path d="M512 192c-70.625 0-128 57.344-128 128 0 47.219 25.875 88.062 64 110.281V448c0 0 0 128-128 128-53.062 0-94.656 11.375-128 28.812V302.28099999999995c38.156-22.219 64-63.062 64-110.281 0-70.656-57.344-128-128-128S0 121.34400000000005 0 192c0 47.219 25.844 88.062 64 110.281V721.75C25.844 743.938 0 784.75 0 832c0 70.625 57.344 128 128 128s128-57.375 128-128c0-33.5-13.188-63.75-34.25-86.625C240.375 722.5 270.656 704 320 704c254 0 256-256 256-256v-17.719c38.125-22.219 64-63.062 64-110.281C640 249.34400000000005 582.625 192 512 192zM128 128c35.406 0 64 28.594 64 64s-28.594 64-64 64-64-28.594-64-64S92.594 128 128 128zM128 896c-35.406 0-64-28.625-64-64 0-35.312 28.594-64 64-64s64 28.688 64 64C192 867.375 163.406 896 128 896zM512 384c-35.375 0-64-28.594-64-64s28.625-64 64-64 64 28.594 64 64S547.375 384 512 384z"/></svg>
|
After Width: | Height: | Size: 917 B |
1
src/main/resources/stash.svg
Normal file
1
src/main/resources/stash.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 12v7H5v-7H3v7c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-7h-2zm-6 .67l2.59-2.58L17 11.5l-5 5-5-5 1.41-1.41L11 12.67V3h2z"/></svg>
|
After Width: | Height: | Size: 271 B |
Loading…
Reference in New Issue
Block a user