Added persistance of commit message
Merge message is also recovered when having conflicts
This commit is contained in:
parent
7335499f97
commit
67aff36bc4
@ -404,7 +404,7 @@ fun DiffLine(
|
||||
}
|
||||
|
||||
Text(
|
||||
text = line.text.replace("\t", " "), // this replace is a workaround until this issue gets fixed https://github.com/JetBrains/compose-jb/issues/615
|
||||
text = line.text.replace("\t", " "), // TODO this replace is a workaround until this issue gets fixed https://github.com/JetBrains/compose-jb/issues/615
|
||||
modifier = Modifier
|
||||
.padding(start = 8.dp)
|
||||
.fillMaxSize(),
|
||||
|
@ -40,6 +40,7 @@ import app.ui.components.SecondaryButton
|
||||
import app.ui.context_menu.*
|
||||
import app.viewmodels.StageStatus
|
||||
import app.viewmodels.StatusViewModel
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import org.eclipse.jgit.lib.RepositoryState
|
||||
|
||||
@Composable
|
||||
@ -53,7 +54,7 @@ fun UncommitedChanges(
|
||||
onHistoryFile: (String) -> Unit,
|
||||
) {
|
||||
val stageStatusState = statusViewModel.stageStatus.collectAsState()
|
||||
var commitMessage by remember { mutableStateOf(statusViewModel.savedCommitMessage) }
|
||||
var commitMessage by remember { mutableStateOf(statusViewModel.savedCommitMessage.message) }
|
||||
|
||||
val stageStatus = stageStatusState.value
|
||||
val staged: List<StatusEntry>
|
||||
@ -70,13 +71,18 @@ fun UncommitedChanges(
|
||||
val doCommit = { amend: Boolean ->
|
||||
statusViewModel.commit(commitMessage, amend)
|
||||
onStagedDiffEntrySelected(null)
|
||||
statusViewModel.savedCommitMessage = ""
|
||||
commitMessage = ""
|
||||
}
|
||||
|
||||
val canCommit = commitMessage.isNotEmpty() && staged.isNotEmpty()
|
||||
val canAmend = (commitMessage.isNotEmpty() || staged.isNotEmpty()) && statusViewModel.hasPreviousCommits
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
statusViewModel.commitMessageChangesFlow.collect { newCommitMessage ->
|
||||
commitMessage = newCommitMessage
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
AnimatedVisibility(
|
||||
visible = stageStatus is StageStatus.Loading,
|
||||
@ -94,7 +100,7 @@ fun UncommitedChanges(
|
||||
title = "Staged",
|
||||
allActionTitle = "Unstage all",
|
||||
actionTitle = "Unstage",
|
||||
selectedEntryType = if(selectedEntryType is DiffEntryType.StagedDiff) selectedEntryType else null,
|
||||
selectedEntryType = if (selectedEntryType is DiffEntryType.StagedDiff) selectedEntryType else null,
|
||||
actionColor = MaterialTheme.colors.unstageButton,
|
||||
statusEntries = staged,
|
||||
onDiffEntrySelected = onStagedDiffEntrySelected,
|
||||
@ -122,7 +128,7 @@ fun UncommitedChanges(
|
||||
.fillMaxWidth(),
|
||||
title = "Unstaged",
|
||||
actionTitle = "Stage",
|
||||
selectedEntryType = if(selectedEntryType is DiffEntryType.UnstagedDiff) selectedEntryType else null,
|
||||
selectedEntryType = if (selectedEntryType is DiffEntryType.UnstagedDiff) selectedEntryType else null,
|
||||
actionColor = MaterialTheme.colors.stageButton,
|
||||
statusEntries = unstaged,
|
||||
onDiffEntrySelected = onUnstagedDiffEntrySelected,
|
||||
@ -175,7 +181,8 @@ fun UncommitedChanges(
|
||||
value = commitMessage,
|
||||
onValueChange = {
|
||||
commitMessage = it
|
||||
statusViewModel.savedCommitMessage = it
|
||||
|
||||
statusViewModel.updateCommitMessage(it)
|
||||
},
|
||||
label = { Text("Write your commit message here", fontSize = 14.sp) },
|
||||
colors = textFieldColors(),
|
||||
@ -185,13 +192,19 @@ fun UncommitedChanges(
|
||||
when {
|
||||
repositoryState.isMerging -> MergeButtons(
|
||||
haveConflictsBeenSolved = unstaged.isEmpty(),
|
||||
onAbort = { statusViewModel.abortMerge() },
|
||||
onAbort = {
|
||||
statusViewModel.abortMerge()
|
||||
statusViewModel.updateCommitMessage("")
|
||||
},
|
||||
onMerge = { doCommit(false) }
|
||||
)
|
||||
repositoryState.isRebasing -> RebasingButtons(
|
||||
canContinue = staged.isNotEmpty() || unstaged.isNotEmpty(),
|
||||
haveConflictsBeenSolved = unstaged.isEmpty(),
|
||||
onAbort = { statusViewModel.abortRebase() },
|
||||
onAbort = {
|
||||
statusViewModel.abortRebase()
|
||||
statusViewModel.updateCommitMessage("")
|
||||
},
|
||||
onContinue = { statusViewModel.continueRebase() },
|
||||
onSkip = { statusViewModel.skipRebase() },
|
||||
)
|
||||
@ -502,7 +515,7 @@ private fun FileEntry(
|
||||
tint = statusEntry.iconColor,
|
||||
)
|
||||
|
||||
if(statusEntry.parentDirectoryPath.isNotEmpty()) {
|
||||
if (statusEntry.parentDirectoryPath.isNotEmpty()) {
|
||||
Text(
|
||||
text = statusEntry.parentDirectoryPath,
|
||||
modifier = Modifier.weight(1f, fill = false),
|
||||
|
@ -1,19 +1,21 @@
|
||||
package app.viewmodels
|
||||
|
||||
import app.extensions.isMerging
|
||||
import app.git.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.lib.RepositoryState
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
class StatusViewModel @Inject constructor(
|
||||
private val tabState: TabState,
|
||||
private val statusManager: StatusManager,
|
||||
private val branchesManager: BranchesManager,
|
||||
private val repositoryManager: RepositoryManager,
|
||||
private val rebaseManager: RebaseManager,
|
||||
private val mergeManager: MergeManager,
|
||||
private val logManager: LogManager,
|
||||
@ -21,11 +23,32 @@ class StatusViewModel @Inject constructor(
|
||||
private val _stageStatus = MutableStateFlow<StageStatus>(StageStatus.Loaded(listOf(), listOf()))
|
||||
val stageStatus: StateFlow<StageStatus> = _stageStatus
|
||||
|
||||
var savedCommitMessage: String = ""
|
||||
var savedCommitMessage = CommitMessage("", MessageType.NORMAL)
|
||||
|
||||
var hasPreviousCommits = true // When false, disable "amend previous commit"
|
||||
|
||||
private var lastUncommitedChangesState = false
|
||||
|
||||
/**
|
||||
* Notify the UI that the commit message has been changed by the view model
|
||||
*/
|
||||
private val _commitMessageChangesFlow = MutableSharedFlow<String>()
|
||||
val commitMessageChangesFlow: SharedFlow<String> = _commitMessageChangesFlow
|
||||
|
||||
private fun persistMessage() = tabState.runOperation(
|
||||
refreshType = RefreshType.NONE,
|
||||
) { git ->
|
||||
val messageToPersist = savedCommitMessage.message.ifBlank { null }
|
||||
|
||||
println("Persisting message: $messageToPersist")
|
||||
|
||||
if (git.repository.repositoryState.isMerging) {
|
||||
git.repository.writeMergeCommitMsg(messageToPersist)
|
||||
} else if (git.repository.repositoryState == RepositoryState.SAFE) {
|
||||
git.repository.writeCommitEditMsg(messageToPersist)
|
||||
}
|
||||
}
|
||||
|
||||
fun stage(statusEntry: StatusEntry) = tabState.runOperation(
|
||||
refreshType = RefreshType.UNCOMMITED_CHANGES,
|
||||
) { git ->
|
||||
@ -66,6 +89,21 @@ class StatusViewModel @Inject constructor(
|
||||
private suspend fun loadStatus(git: Git) {
|
||||
val previousStatus = _stageStatus.value
|
||||
|
||||
val requiredMessageType = if (git.repository.repositoryState == RepositoryState.MERGING) {
|
||||
MessageType.MERGE
|
||||
} else {
|
||||
MessageType.NORMAL
|
||||
}
|
||||
|
||||
if (requiredMessageType != savedCommitMessage.messageType) {
|
||||
savedCommitMessage = CommitMessage(messageByRepoState(git), requiredMessageType)
|
||||
_commitMessageChangesFlow.emit(savedCommitMessage.message)
|
||||
|
||||
} else if (savedCommitMessage.message.isEmpty()) {
|
||||
savedCommitMessage = savedCommitMessage.copy(message = messageByRepoState(git))
|
||||
_commitMessageChangesFlow.emit(savedCommitMessage.message)
|
||||
}
|
||||
|
||||
try {
|
||||
_stageStatus.value = StageStatus.Loading
|
||||
val status = statusManager.getStatus(git)
|
||||
@ -79,6 +117,17 @@ class StatusViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun messageByRepoState(git: Git): String {
|
||||
val message: String? = if (git.repository.repositoryState == RepositoryState.MERGING) {
|
||||
git.repository.readMergeCommitMsg()
|
||||
} else {
|
||||
git.repository.readCommitEditMsg()
|
||||
}
|
||||
|
||||
//TODO this replace is a workaround until this issue gets fixed https://github.com/JetBrains/compose-jb/issues/615
|
||||
return message.orEmpty().replace("\t", " ")
|
||||
}
|
||||
|
||||
private suspend fun loadHasUncommitedChanges(git: Git) = withContext(Dispatchers.IO) {
|
||||
lastUncommitedChangesState = statusManager.hasUncommitedChanges(git)
|
||||
}
|
||||
@ -92,6 +141,7 @@ class StatusViewModel @Inject constructor(
|
||||
message
|
||||
|
||||
statusManager.commit(git, commitMessage, amend)
|
||||
updateCommitMessage("")
|
||||
}
|
||||
|
||||
suspend fun refresh(git: Git) = withContext(Dispatchers.IO) {
|
||||
@ -148,6 +198,11 @@ class StatusViewModel @Inject constructor(
|
||||
|
||||
fileToDelete.delete()
|
||||
}
|
||||
|
||||
fun updateCommitMessage(message: String) {
|
||||
savedCommitMessage = savedCommitMessage.copy(message = message)
|
||||
persistMessage()
|
||||
}
|
||||
}
|
||||
|
||||
sealed class StageStatus {
|
||||
@ -155,3 +210,9 @@ sealed class StageStatus {
|
||||
data class Loaded(val staged: List<StatusEntry>, val unstaged: List<StatusEntry>) : StageStatus()
|
||||
}
|
||||
|
||||
data class CommitMessage(val message: String, val messageType: MessageType)
|
||||
|
||||
enum class MessageType {
|
||||
NORMAL,
|
||||
MERGE;
|
||||
}
|
Loading…
Reference in New Issue
Block a user