Adapted code to latest kotlin features & fixed typos

This commit is contained in:
Abdelilah El Aissaoui 2023-12-11 19:41:34 +01:00
parent c2e69d00f3
commit f530e487c7
No known key found for this signature in database
GPG Key ID: 7587FC860F594869
35 changed files with 139 additions and 161 deletions

View File

@ -35,7 +35,7 @@ Gitnuro has support for the following features:
- View your history log and all its branches. - View your history log and all its branches.
- Add (stage) & reset (unstage) files. - Add (stage) & reset (unstage) files.
- Stage & unstage of hunks. - Stage & unstage of hunks.
- Checkout files (revert changes of uncommited files). - Checkout files (revert changes of uncommitted files).
- Clone. - Clone.
- Commit. - Commit.
- Reset commits. - Reset commits.

View File

@ -1,3 +0,0 @@
package com.jetpackduba.gitnuro.exceptions
class UncommitedChangesDetectedException(msg: String) : GitnuroException(msg)

View File

@ -0,0 +1,3 @@
package com.jetpackduba.gitnuro.exceptions
class UncommittedChangesDetectedException(msg: String) : GitnuroException(msg)

View File

@ -3,12 +3,12 @@ package com.jetpackduba.gitnuro.git
import org.eclipse.jgit.transport.RemoteRefUpdate import org.eclipse.jgit.transport.RemoteRefUpdate
import java.io.File import java.io.File
sealed class CloneState { sealed interface CloneState {
object None : CloneState() data object None : CloneState
data class Cloning(val taskName: String, val progress: Int, val total: Int) : CloneState() data class Cloning(val taskName: String, val progress: Int, val total: Int) : CloneState
object Cancelling : CloneState() data object Cancelling : CloneState
data class Fail(val reason: String) : CloneState() data class Fail(val reason: String) : CloneState
data class Completed(val repoDir: File) : CloneState() data class Completed(val repoDir: File) : CloneState
} }
val RemoteRefUpdate.Status.isRejected: Boolean val RemoteRefUpdate.Status.isRejected: Boolean

View File

@ -6,8 +6,8 @@ import com.jetpackduba.gitnuro.git.workspace.StatusEntry
import com.jetpackduba.gitnuro.git.workspace.StatusType import com.jetpackduba.gitnuro.git.workspace.StatusType
import org.eclipse.jgit.diff.DiffEntry import org.eclipse.jgit.diff.DiffEntry
sealed class DiffEntryType { sealed interface DiffEntryType {
class CommitDiff(val diffEntry: DiffEntry) : DiffEntryType() { class CommitDiff(val diffEntry: DiffEntry) : DiffEntryType {
override val filePath: String override val filePath: String
get() = diffEntry.filePath get() = diffEntry.filePath
@ -15,7 +15,7 @@ sealed class DiffEntryType {
get() = diffEntry.toStatusType() get() = diffEntry.toStatusType()
} }
sealed class UncommitedDiff(val statusEntry: StatusEntry) : DiffEntryType() { sealed class UncommittedDiff(val statusEntry: StatusEntry) : DiffEntryType {
override val filePath: String override val filePath: String
get() = statusEntry.filePath get() = statusEntry.filePath
@ -23,8 +23,8 @@ sealed class DiffEntryType {
get() = statusEntry.statusType get() = statusEntry.statusType
} }
sealed class UnstagedDiff(statusEntry: StatusEntry) : UncommitedDiff(statusEntry) sealed class UnstagedDiff(statusEntry: StatusEntry) : UncommittedDiff(statusEntry)
sealed class StagedDiff(statusEntry: StatusEntry) : UncommitedDiff(statusEntry) sealed class StagedDiff(statusEntry: StatusEntry) : UncommittedDiff(statusEntry)
/** /**
* State used to represent staged changes when the repository state is not [org.eclipse.jgit.lib.RepositoryState.SAFE] * State used to represent staged changes when the repository state is not [org.eclipse.jgit.lib.RepositoryState.SAFE]
@ -39,7 +39,7 @@ sealed class DiffEntryType {
class SafeStagedDiff(statusEntry: StatusEntry) : StagedDiff(statusEntry) class SafeStagedDiff(statusEntry: StatusEntry) : StagedDiff(statusEntry)
class SafeUnstagedDiff(statusEntry: StatusEntry) : UnstagedDiff(statusEntry) class SafeUnstagedDiff(statusEntry: StatusEntry) : UnstagedDiff(statusEntry)
abstract val filePath: String val filePath: String
abstract val statusType: StatusType val statusType: StatusType
} }

View File

@ -108,13 +108,13 @@ class RawFileManager @Inject constructor(
} }
} }
sealed class EntryContent { sealed interface EntryContent {
object Missing : EntryContent() data object Missing : EntryContent
object InvalidObjectBlob : EntryContent() data object InvalidObjectBlob : EntryContent
data class Text(val rawText: RawText) : EntryContent() data class Text(val rawText: RawText) : EntryContent
object Submodule : EntryContent() data object Submodule : EntryContent
sealed class BinaryContent : EntryContent() sealed interface BinaryContent : EntryContent
data class ImageBinary(val imagePath: String, val contentType: String) : BinaryContent() data class ImageBinary(val imagePath: String, val contentType: String) : BinaryContent
object Binary : BinaryContent() data object Binary : BinaryContent
object TooLargeEntry : EntryContent() data object TooLargeEntry : EntryContent
} }

View File

@ -23,7 +23,7 @@ interface ProcessingInfo {
} }
sealed interface ProcessingState { sealed interface ProcessingState {
object None : ProcessingState data object None : ProcessingState
data class Processing( data class Processing(
val title: String, val title: String,
val subtitle: String, val subtitle: String,
@ -37,7 +37,7 @@ class TabState @Inject constructor(
private val scope: CoroutineScope, private val scope: CoroutineScope,
private val findCommitUseCase: FindCommitUseCase, private val findCommitUseCase: FindCommitUseCase,
) { ) {
private val _selectedItem = MutableStateFlow<SelectedItem>(SelectedItem.UncommitedChanges) private val _selectedItem = MutableStateFlow<SelectedItem>(SelectedItem.UncommittedChanges)
val selectedItem: StateFlow<SelectedItem> = _selectedItem val selectedItem: StateFlow<SelectedItem> = _selectedItem
private val _taskEvent = MutableSharedFlow<TaskEvent>() private val _taskEvent = MutableSharedFlow<TaskEvent>()
val taskEvent: SharedFlow<TaskEvent> = _taskEvent val taskEvent: SharedFlow<TaskEvent> = _taskEvent

View File

@ -1,6 +1,6 @@
package com.jetpackduba.gitnuro.git.branches package com.jetpackduba.gitnuro.git.branches
import com.jetpackduba.gitnuro.exceptions.UncommitedChangesDetectedException import com.jetpackduba.gitnuro.exceptions.UncommittedChangesDetectedException
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
@ -23,7 +23,7 @@ class MergeBranchUseCase @Inject constructor() {
.call() .call()
if (mergeResult.mergeStatus == MergeResult.MergeStatus.FAILED) { if (mergeResult.mergeStatus == MergeResult.MergeStatus.FAILED) {
throw UncommitedChangesDetectedException("Merge failed, makes sure you repository doesn't contain uncommited changes.") throw UncommittedChangesDetectedException("Merge failed, makes sure you repository doesn't contain uncommitted changes.")
} }
} }
} }

View File

@ -10,8 +10,6 @@ import org.eclipse.jgit.api.Git
import org.eclipse.jgit.diff.DiffEntry import org.eclipse.jgit.diff.DiffEntry
import org.eclipse.jgit.diff.DiffFormatter import org.eclipse.jgit.diff.DiffFormatter
import org.eclipse.jgit.dircache.DirCacheIterator import org.eclipse.jgit.dircache.DirCacheIterator
import org.eclipse.jgit.submodule.SubmoduleStatus
import org.eclipse.jgit.submodule.SubmoduleStatusType
import org.eclipse.jgit.treewalk.FileTreeIterator import org.eclipse.jgit.treewalk.FileTreeIterator
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.InvalidObjectException import java.io.InvalidObjectException
@ -21,7 +19,7 @@ class FormatDiffUseCase @Inject constructor(
private val formatHunksUseCase: FormatHunksUseCase, private val formatHunksUseCase: FormatHunksUseCase,
private val getDiffContentUseCase: GetDiffContentUseCase, private val getDiffContentUseCase: GetDiffContentUseCase,
private val canGenerateTextDiffUseCase: CanGenerateTextDiffUseCase, private val canGenerateTextDiffUseCase: CanGenerateTextDiffUseCase,
private val getDiffEntryForUncommitedDiffUseCase: GetDiffEntryForUncommitedDiffUseCase, private val getDiffEntryForUncommittedDiffUseCase: GetDiffEntryForUncommittedDiffUseCase,
private val getSubmodulesUseCase: GetSubmodulesUseCase, private val getSubmodulesUseCase: GetSubmodulesUseCase,
) { ) {
suspend operator fun invoke( suspend operator fun invoke(
@ -48,8 +46,8 @@ class FormatDiffUseCase @Inject constructor(
diffEntryType.diffEntry diffEntryType.diffEntry
} }
is DiffEntryType.UncommitedDiff -> { is DiffEntryType.UncommittedDiff -> {
getDiffEntryForUncommitedDiffUseCase(git, diffEntryType) getDiffEntryForUncommittedDiffUseCase(git, diffEntryType)
} }
} }

View File

@ -12,13 +12,13 @@ import org.eclipse.jgit.treewalk.EmptyTreeIterator
import org.eclipse.jgit.treewalk.filter.PathFilter import org.eclipse.jgit.treewalk.filter.PathFilter
import javax.inject.Inject import javax.inject.Inject
class GetDiffEntryForUncommitedDiffUseCase @Inject constructor( class GetDiffEntryForUncommittedDiffUseCase @Inject constructor(
private val getRepositoryStateUseCase: GetRepositoryStateUseCase, private val getRepositoryStateUseCase: GetRepositoryStateUseCase,
private val getCurrentBranchUseCase: GetCurrentBranchUseCase, private val getCurrentBranchUseCase: GetCurrentBranchUseCase,
) { ) {
suspend operator fun invoke( suspend operator fun invoke(
git: Git, git: Git,
diffEntryType: DiffEntryType.UncommitedDiff, diffEntryType: DiffEntryType.UncommittedDiff,
) = withContext(Dispatchers.IO) { ) = withContext(Dispatchers.IO) {
val statusEntry = diffEntryType.statusEntry val statusEntry = diffEntryType.statusEntry
val cached = diffEntryType is DiffEntryType.StagedDiff val cached = diffEntryType is DiffEntryType.StagedDiff

View File

@ -55,19 +55,19 @@ class GraphCommitList : RevCommitList<GraphNode>() {
private var parentId: AnyObjectId? = null private var parentId: AnyObjectId? = null
private val graphCommit = UncommitedChangesGraphNode() private val graphCommit = UncommittedChangesGraphNode()
fun addUncommitedChangesGraphCommit(parent: RevCommit) { fun addUncommittedChangesGraphCommit(parent: RevCommit) {
parentId = parent.id parentId = parent.id
graphCommit.lane = nextFreeLane() graphCommit.lane = nextFreeLane()
} }
override fun enter(index: Int, currCommit: GraphNode) { override fun enter(index: Int, currCommit: GraphNode) {
var isUncommitedChangesNodeParent = false var isUncommittedChangesNodeParent = false
if (currCommit.id == parentId) { if (currCommit.id == parentId) {
graphCommit.graphParent = currCommit graphCommit.graphParent = currCommit
currCommit.addChild(graphCommit, addFirst = true) currCommit.addChild(graphCommit, addFirst = true)
isUncommitedChangesNodeParent = true isUncommittedChangesNodeParent = true
} }
setupChildren(currCommit) setupChildren(currCommit)
@ -104,7 +104,7 @@ class GraphCommitList : RevCommitList<GraphNode>() {
var lengthOfReservedLane = -1 var lengthOfReservedLane = -1
if (isUncommitedChangesNodeParent) { if (isUncommittedChangesNodeParent) {
val length = laneLength[graphCommit.lane] val length = laneLength[graphCommit.lane]
if (length != null) { if (length != null) {
reservedLane = graphCommit.lane reservedLane = graphCommit.lane

View File

@ -2,12 +2,12 @@ package com.jetpackduba.gitnuro.git.graph
import org.eclipse.jgit.lib.ObjectId import org.eclipse.jgit.lib.ObjectId
class UncommitedChangesGraphNode : GraphNode(ObjectId(0, 0, 0, 0, 0)) { class UncommittedChangesGraphNode : GraphNode(ObjectId(0, 0, 0, 0, 0)) {
var graphParent: GraphNode? = null var graphParent: GraphNode? = null
override val graphParentCount: Int override val graphParentCount: Int
get() = 1 // Uncommited changes can have a max of 1 parent commit get() = 1 // Uncommitted changes can have a max of 1 parent commit
override fun getGraphParent(nth: Int): GraphNode { override fun getGraphParent(nth: Int): GraphNode {
return requireNotNull(graphParent) return requireNotNull(graphParent)

View File

@ -15,7 +15,7 @@ import javax.inject.Inject
class GetLogUseCase @Inject constructor() { class GetLogUseCase @Inject constructor() {
private var graphWalkCached: GraphWalk? = null private var graphWalkCached: GraphWalk? = null
suspend operator fun invoke(git: Git, currentBranch: Ref?, hasUncommitedChanges: Boolean, commitsLimit: Int) = suspend operator fun invoke(git: Git, currentBranch: Ref?, hasUncommittedChanges: Boolean, commitsLimit: Int) =
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
val commitList = GraphCommitList() val commitList = GraphCommitList()
val repositoryState = git.repository.repositoryState val repositoryState = git.repository.repositoryState
@ -35,8 +35,8 @@ class GetLogUseCase @Inject constructor() {
walk.markStartAllRefs(Constants.R_TAGS) walk.markStartAllRefs(Constants.R_TAGS)
walk.markStartAllRefs(Constants.R_STASH) walk.markStartAllRefs(Constants.R_STASH)
if (hasUncommitedChanges) if (hasUncommittedChanges)
commitList.addUncommitedChangesGraphCommit(logList.first()) commitList.addUncommittedChangesGraphCommit(logList.first())
commitList.source(walk) commitList.source(walk)
commitList.fillTo(commitsLimit) commitList.fillTo(commitsLimit)

View File

@ -19,7 +19,7 @@ class RevertCommitUseCase @Inject constructor() {
val failingResult: MergeResult? = revertCommand.failingResult val failingResult: MergeResult? = revertCommand.failingResult
when (failingResult?.mergeStatus) { when (failingResult?.mergeStatus) {
MergeResult.MergeStatus.FAILED -> throw RevertCommitException("Revert failed. Clear your workspace from uncommited changes.") MergeResult.MergeStatus.FAILED -> throw RevertCommitException("Revert failed. Clear your workspace from uncommitted changes.")
MergeResult.MergeStatus.CONFLICTING -> throw RevertCommitException("Revert failed. Fix the conflicts and commit the desired changes.") MergeResult.MergeStatus.CONFLICTING -> throw RevertCommitException("Revert failed. Fix the conflicts and commit the desired changes.")
MergeResult.MergeStatus.ABORTED -> throw RevertCommitException("Revert aborted.") MergeResult.MergeStatus.ABORTED -> throw RevertCommitException("Revert aborted.")
else -> {} else -> {}

View File

@ -1,6 +1,6 @@
package com.jetpackduba.gitnuro.git.rebase package com.jetpackduba.gitnuro.git.rebase
import com.jetpackduba.gitnuro.exceptions.UncommitedChangesDetectedException import com.jetpackduba.gitnuro.exceptions.UncommittedChangesDetectedException
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
@ -17,7 +17,7 @@ class RebaseBranchUseCase @Inject constructor() {
.call() .call()
if (rebaseResult.status == RebaseResult.Status.UNCOMMITTED_CHANGES) { if (rebaseResult.status == RebaseResult.Status.UNCOMMITTED_CHANGES) {
throw UncommitedChangesDetectedException("Rebase failed, the repository contains uncommited changes.") throw UncommittedChangesDetectedException("Rebase failed, the repository contains uncommitted changes.")
} }
} }
} }

View File

@ -1,6 +1,6 @@
package com.jetpackduba.gitnuro.git.rebase package com.jetpackduba.gitnuro.git.rebase
import com.jetpackduba.gitnuro.exceptions.UncommitedChangesDetectedException import com.jetpackduba.gitnuro.exceptions.UncommittedChangesDetectedException
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
@ -18,9 +18,9 @@ class ResumeRebaseInteractiveUseCase @Inject constructor() {
when (rebaseResult.status) { when (rebaseResult.status) {
RebaseResult.Status.FAILED -> throw UncommitedChangesDetectedException("Rebase interactive failed.") RebaseResult.Status.FAILED -> throw UncommittedChangesDetectedException("Rebase interactive failed.")
RebaseResult.Status.UNCOMMITTED_CHANGES, RebaseResult.Status.CONFLICTS -> throw UncommitedChangesDetectedException( RebaseResult.Status.UNCOMMITTED_CHANGES, RebaseResult.Status.CONFLICTS -> throw UncommittedChangesDetectedException(
"You can't have uncommited changes before starting a rebase interactive" "You can't have uncommitted changes before starting a rebase interactive"
) )
else -> {} else -> {}

View File

@ -1,6 +1,6 @@
package com.jetpackduba.gitnuro.git.rebase package com.jetpackduba.gitnuro.git.rebase
import com.jetpackduba.gitnuro.exceptions.UncommitedChangesDetectedException import com.jetpackduba.gitnuro.exceptions.UncommittedChangesDetectedException
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
@ -29,9 +29,9 @@ class StartRebaseInteractiveUseCase @Inject constructor() {
.call() .call()
when (rebaseResult.status) { when (rebaseResult.status) {
RebaseResult.Status.FAILED -> throw UncommitedChangesDetectedException("Rebase interactive failed.") RebaseResult.Status.FAILED -> throw UncommittedChangesDetectedException("Rebase interactive failed.")
RebaseResult.Status.UNCOMMITTED_CHANGES, RebaseResult.Status.CONFLICTS -> throw UncommitedChangesDetectedException( RebaseResult.Status.UNCOMMITTED_CHANGES, RebaseResult.Status.CONFLICTS -> throw UncommittedChangesDetectedException(
"You can't have uncommited changes before starting a rebase interactive" "You can't have uncommitted changes before starting a rebase interactive"
) )
else -> {} else -> {}

View File

@ -33,7 +33,7 @@ class PullBranchUseCase @Inject constructor(
if (pullWithRebase) { if (pullWithRebase) {
message = when (pullResult.rebaseResult.status) { message = when (pullResult.rebaseResult.status) {
RebaseResult.Status.UNCOMMITTED_CHANGES -> "The pull with rebase has failed because you have got uncommited changes" RebaseResult.Status.UNCOMMITTED_CHANGES -> "The pull with rebase has failed because you have got uncommitted changes"
RebaseResult.Status.CONFLICTS -> "Pull with rebase has conflicts, fix them to continue" RebaseResult.Status.CONFLICTS -> "Pull with rebase has conflicts, fix them to continue"
else -> message else -> message
} }

View File

@ -30,7 +30,7 @@ class PullFromSpecificBranchUseCase @Inject constructor(
if (rebase) { if (rebase) {
message = when (pullResult.rebaseResult.status) { message = when (pullResult.rebaseResult.status) {
RebaseResult.Status.UNCOMMITTED_CHANGES -> "The pull with rebase has failed because you have got uncommited changes" RebaseResult.Status.UNCOMMITTED_CHANGES -> "The pull with rebase has failed because you have got uncommitted changes"
RebaseResult.Status.CONFLICTS -> "Pull with rebase has conflicts, fix them to continue" RebaseResult.Status.CONFLICTS -> "Pull with rebase has conflicts, fix them to continue"
else -> message else -> message
} }

View File

@ -6,7 +6,7 @@ import kotlinx.coroutines.withContext
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
import javax.inject.Inject import javax.inject.Inject
class CheckHasUncommitedChangesUseCase @Inject constructor() { class CheckHasUncommittedChangesUseCase @Inject constructor() {
suspend operator fun invoke(git: Git) = withContext(Dispatchers.IO) { suspend operator fun invoke(git: Git) = withContext(Dispatchers.IO) {
val status = git val status = git
.status() .status()

View File

@ -107,7 +107,7 @@ fun Blame(
style = MaterialTheme.typography.body2, style = MaterialTheme.typography.body2,
) )
Text( Text(
text = commit?.shortMessage ?: "Uncommited change", text = commit?.shortMessage ?: "Uncommitted change",
style = MaterialTheme.typography.caption, style = MaterialTheme.typography.caption,
maxLines = 1, maxLines = 1,
modifier = Modifier.padding(start = 16.dp), modifier = Modifier.padding(start = 16.dp),

View File

@ -26,13 +26,12 @@ import com.jetpackduba.gitnuro.git.DiffEntryType
import com.jetpackduba.gitnuro.theme.* import com.jetpackduba.gitnuro.theme.*
import com.jetpackduba.gitnuro.ui.components.* import com.jetpackduba.gitnuro.ui.components.*
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenu import com.jetpackduba.gitnuro.ui.context_menu.ContextMenu
import com.jetpackduba.gitnuro.ui.context_menu.commitedChangesEntriesContextMenuItems import com.jetpackduba.gitnuro.ui.context_menu.committedChangesEntriesContextMenuItems
import com.jetpackduba.gitnuro.viewmodels.CommitChangesState import com.jetpackduba.gitnuro.viewmodels.CommitChangesState
import com.jetpackduba.gitnuro.viewmodels.CommitChangesViewModel import com.jetpackduba.gitnuro.viewmodels.CommitChangesViewModel
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.eclipse.jgit.diff.DiffEntry import org.eclipse.jgit.diff.DiffEntry
import org.eclipse.jgit.lib.ObjectId
import org.eclipse.jgit.lib.PersonIdent import org.eclipse.jgit.lib.PersonIdent
import org.eclipse.jgit.revwalk.RevCommit import org.eclipse.jgit.revwalk.RevCommit
@ -314,7 +313,7 @@ fun CommitLogChanges(
items(items = diffEntries) { diffEntry -> items(items = diffEntries) { diffEntry ->
ContextMenu( ContextMenu(
items = { items = {
commitedChangesEntriesContextMenuItems( committedChangesEntriesContextMenuItems(
diffEntry, diffEntry,
onBlame = { onBlame(diffEntry.filePath) }, onBlame = { onBlame(diffEntry.filePath) },
onHistory = { onHistory(diffEntry.filePath) }, onHistory = { onHistory(diffEntry.filePath) },

View File

@ -30,7 +30,6 @@ import com.jetpackduba.gitnuro.ui.diff.Diff
import com.jetpackduba.gitnuro.ui.log.Log import com.jetpackduba.gitnuro.ui.log.Log
import com.jetpackduba.gitnuro.viewmodels.BlameState import com.jetpackduba.gitnuro.viewmodels.BlameState
import com.jetpackduba.gitnuro.viewmodels.TabViewModel import com.jetpackduba.gitnuro.viewmodels.TabViewModel
import org.eclipse.jgit.lib.Ref
import org.eclipse.jgit.lib.RepositoryState import org.eclipse.jgit.lib.RepositoryState
import org.eclipse.jgit.revwalk.RevCommit import org.eclipse.jgit.revwalk.RevCommit
import org.jetbrains.compose.splitpane.ExperimentalSplitPaneApi import org.jetbrains.compose.splitpane.ExperimentalSplitPaneApi
@ -338,8 +337,8 @@ fun MainContentView(
.fillMaxHeight() .fillMaxHeight()
) { ) {
when (selectedItem) { when (selectedItem) {
SelectedItem.UncommitedChanges -> { SelectedItem.UncommittedChanges -> {
UncommitedChanges( UncommittedChanges(
selectedEntryType = diffSelected, selectedEntryType = diffSelected,
repositoryState = repositoryState, repositoryState = repositoryState,
onStagedDiffEntrySelected = { diffEntry -> onStagedDiffEntrySelected = { diffEntry ->
@ -410,10 +409,10 @@ fun SplitterScope.repositorySplitter() {
} }
} }
sealed class SelectedItem { sealed interface SelectedItem {
object None : SelectedItem() data object None : SelectedItem
object UncommitedChanges : SelectedItem() data object UncommittedChanges : SelectedItem
sealed class CommitBasedItem(val revCommit: RevCommit) : SelectedItem() sealed class CommitBasedItem(val revCommit: RevCommit) : SelectedItem
class Ref(val ref: org.eclipse.jgit.lib.Ref, revCommit: RevCommit) : CommitBasedItem(revCommit) class Ref(val ref: org.eclipse.jgit.lib.Ref, revCommit: RevCommit) : CommitBasedItem(revCommit)
class Commit(revCommit: RevCommit) : CommitBasedItem(revCommit) class Commit(revCommit: RevCommit) : CommitBasedItem(revCommit)
class Stash(revCommit: RevCommit) : CommitBasedItem(revCommit) class Stash(revCommit: RevCommit) : CommitBasedItem(revCommit)

View File

@ -51,7 +51,7 @@ import com.jetpackduba.gitnuro.viewmodels.StatusViewModel
import org.eclipse.jgit.lib.RepositoryState import org.eclipse.jgit.lib.RepositoryState
@Composable @Composable
fun UncommitedChanges( fun UncommittedChanges(
statusViewModel: StatusViewModel = gitnuroViewModel(), statusViewModel: StatusViewModel = gitnuroViewModel(),
selectedEntryType: DiffEntryType?, selectedEntryType: DiffEntryType?,
repositoryState: RepositoryState, repositoryState: RepositoryState,
@ -61,7 +61,7 @@ fun UncommitedChanges(
onHistoryFile: (String) -> Unit, onHistoryFile: (String) -> Unit,
) { ) {
val stageStatus = statusViewModel.stageState.collectAsState().value val stageStatus = statusViewModel.stageState.collectAsState().value
val swapUncommitedChanges by statusViewModel.swapUncommitedChanges.collectAsState() val swapUncommittedChanges by statusViewModel.swapUncommittedChanges.collectAsState()
var commitMessage by remember(statusViewModel) { mutableStateOf(statusViewModel.savedCommitMessage.message) } var commitMessage by remember(statusViewModel) { mutableStateOf(statusViewModel.savedCommitMessage.message) }
val stagedListState by statusViewModel.stagedLazyListState.collectAsState() val stagedListState by statusViewModel.stagedLazyListState.collectAsState()
val unstagedListState by statusViewModel.unstagedLazyListState.collectAsState() val unstagedListState by statusViewModel.unstagedLazyListState.collectAsState()
@ -221,7 +221,7 @@ fun UncommitedChanges(
) )
} }
if (swapUncommitedChanges) { if (swapUncommittedChanges) {
unstagedView() unstagedView()
stagedView() stagedView()
} else { } else {
@ -319,7 +319,7 @@ fun UncommitedChanges(
} }
) )
else -> UncommitedChangesButtons( else -> UncommittedChangesButtons(
canCommit = canCommit, canCommit = canCommit,
canAmend = canAmend, canAmend = canAmend,
isAmend = isAmend, isAmend = isAmend,
@ -335,7 +335,7 @@ fun UncommitedChanges(
} }
@Composable @Composable
fun UncommitedChangesButtons( fun UncommittedChangesButtons(
canCommit: Boolean, canCommit: Boolean,
canAmend: Boolean, canAmend: Boolean,
isAmend: Boolean, isAmend: Boolean,
@ -678,7 +678,7 @@ private fun EntriesList(
) { ) {
items(statusEntries, key = { it.filePath }) { statusEntry -> items(statusEntries, key = { it.filePath }) { statusEntry ->
val isEntrySelected = selectedEntryType != null && val isEntrySelected = selectedEntryType != null &&
selectedEntryType is DiffEntryType.UncommitedDiff && // Added for smartcast selectedEntryType is DiffEntryType.UncommittedDiff && // Added for smartcast
selectedEntryType.statusEntry == statusEntry selectedEntryType.statusEntry == statusEntry
FileEntry( FileEntry(
statusEntry = statusEntry, statusEntry = statusEntry,

View File

@ -6,7 +6,7 @@ import com.jetpackduba.gitnuro.AppIcons
import org.eclipse.jgit.diff.DiffEntry import org.eclipse.jgit.diff.DiffEntry
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
fun commitedChangesEntriesContextMenuItems( fun committedChangesEntriesContextMenuItems(
diffEntry: DiffEntry, diffEntry: DiffEntry,
onBlame: () -> Unit, onBlame: () -> Unit,
onHistory: () -> Unit, onHistory: () -> Unit,

View File

@ -402,14 +402,14 @@ private fun Branches(settingsViewModel: SettingsViewModel) {
@Composable @Composable
private fun Layout(settingsViewModel: SettingsViewModel) { private fun Layout(settingsViewModel: SettingsViewModel) {
val swapUncommitedChanges by settingsViewModel.swapUncommittedChangesFlow.collectAsState() val swapUncommittedChanges by settingsViewModel.swapUncommittedChangesFlow.collectAsState()
SettingToggle( SettingToggle(
title = "Swap position for staged/unstaged views", title = "Swap position for staged/unstaged views",
subtitle = "Show the list of unstaged changes above the list of staged changes", subtitle = "Show the list of unstaged changes above the list of staged changes",
value = swapUncommitedChanges, value = swapUncommittedChanges,
onValueChanged = { value -> onValueChanged = { value ->
settingsViewModel.swapUncommitedChanges = value settingsViewModel.swapUncommittedChanges = value
} }
) )
} }

View File

@ -798,7 +798,7 @@ fun HunkHeader(
// Hunks options are only visible when repository is a normal state (not during merge/rebase) // Hunks options are only visible when repository is a normal state (not during merge/rebase)
if ( if (
(diffEntryType is DiffEntryType.SafeStagedDiff || diffEntryType is DiffEntryType.SafeUnstagedDiff) && (diffEntryType is DiffEntryType.SafeStagedDiff || diffEntryType is DiffEntryType.SafeUnstagedDiff) &&
(diffEntryType is DiffEntryType.UncommitedDiff && // Added just to make smartcast work (diffEntryType is DiffEntryType.UncommittedDiff && // Added just to make smartcast work
diffEntryType.statusEntry.statusType == StatusType.MODIFIED) diffEntryType.statusEntry.statusType == StatusType.MODIFIED)
) { ) {
val buttonText: String val buttonText: String
@ -914,8 +914,8 @@ private fun DiffHeader(
) )
} }
if (diffEntryType is DiffEntryType.UncommitedDiff) { if (diffEntryType is DiffEntryType.UncommittedDiff) {
UncommitedDiffFileHeaderButtons( UncommittedDiffFileHeaderButtons(
diffEntryType, diffEntryType,
onUnstageFile = onUnstageFile, onUnstageFile = onUnstageFile,
onStageFile = onStageFile onStageFile = onStageFile
@ -1020,8 +1020,8 @@ fun DiffTypeButtons(
} }
@Composable @Composable
fun UncommitedDiffFileHeaderButtons( fun UncommittedDiffFileHeaderButtons(
diffEntryType: DiffEntryType.UncommitedDiff, diffEntryType: DiffEntryType.UncommittedDiff,
onUnstageFile: (StatusEntry) -> Unit, onUnstageFile: (StatusEntry) -> Unit,
onStageFile: (StatusEntry) -> Unit onStageFile: (StatusEntry) -> Unit
) { ) {
@ -1167,7 +1167,7 @@ fun DiffLineText(line: Line, diffEntryType: DiffEntryType, onActionTriggered: ()
val isHovered by hoverInteraction.collectIsHoveredAsState() val isHovered by hoverInteraction.collectIsHoveredAsState()
Box(modifier = Modifier.hoverable(hoverInteraction)) { Box(modifier = Modifier.hoverable(hoverInteraction)) {
if (isHovered && diffEntryType is DiffEntryType.UncommitedDiff && line.lineType != LineType.CONTEXT) { if (isHovered && diffEntryType is DiffEntryType.UncommittedDiff && line.lineType != LineType.CONTEXT) {
val color: Color = if (diffEntryType is DiffEntryType.StagedDiff) { val color: Color = if (diffEntryType is DiffEntryType.StagedDiff) {
MaterialTheme.colors.error MaterialTheme.colors.error
} else { } else {

View File

@ -28,7 +28,6 @@ import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.drawscope.clipRect import androidx.compose.ui.graphics.drawscope.clipRect
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.input.key.onPreviewKeyEvent import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.input.pointer.PointerIcon
import androidx.compose.ui.input.pointer.pointerHoverIcon import androidx.compose.ui.input.pointer.pointerHoverIcon
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
@ -59,7 +58,6 @@ import kotlinx.coroutines.launch
import org.eclipse.jgit.lib.Ref import org.eclipse.jgit.lib.Ref
import org.eclipse.jgit.lib.RepositoryState import org.eclipse.jgit.lib.RepositoryState
import org.eclipse.jgit.revwalk.RevCommit import org.eclipse.jgit.revwalk.RevCommit
import java.awt.Cursor
private val colors = listOf( private val colors = listOf(
Color(0xFF42a5f5), Color(0xFF42a5f5),
@ -151,8 +149,8 @@ private fun LogLoaded(
} }
} }
launch { launch {
logViewModel.scrollToUncommitedChanges.collect { logViewModel.scrollToUncommittedChanges.collect {
scrollToUncommitedChanges(verticalScrollState, commitList) scrollToUncommittedChanges(verticalScrollState, commitList)
} }
} }
} }
@ -318,7 +316,7 @@ suspend fun scrollToCommit(
if (index >= 0) verticalScrollState.scrollToItem(index) if (index >= 0) verticalScrollState.scrollToItem(index)
} }
suspend fun scrollToUncommitedChanges( suspend fun scrollToUncommittedChanges(
verticalScrollState: LazyListState, verticalScrollState: LazyListState,
commitList: GraphCommitList, commitList: GraphCommitList,
) { ) {
@ -459,17 +457,17 @@ fun MessagesList(
modifier = Modifier.height(LINE_HEIGHT.dp) modifier = Modifier.height(LINE_HEIGHT.dp)
.clipToBounds() .clipToBounds()
.fillMaxWidth() .fillMaxWidth()
.clickable { logViewModel.selectUncommitedChanges() } .clickable { logViewModel.selectUncommittedChanges() }
) { ) {
UncommitedChangesGraphNode( UncommittedChangesGraphNode(
hasPreviousCommits = commitList.isNotEmpty(), hasPreviousCommits = commitList.isNotEmpty(),
isSelected = selectedItem is SelectedItem.UncommitedChanges, isSelected = selectedItem is SelectedItem.UncommittedChanges,
modifier = Modifier.offset(-horizontalScrollState.value.dp) modifier = Modifier.offset(-horizontalScrollState.value.dp)
) )
UncommitedChangesLine( UncommittedChangesLine(
graphWidth = graphWidth, graphWidth = graphWidth,
isSelected = selectedItem == SelectedItem.UncommitedChanges, isSelected = selectedItem == SelectedItem.UncommittedChanges,
statusSummary = logStatus.statusSummary, statusSummary = logStatus.statusSummary,
repositoryState = repositoryState, repositoryState = repositoryState,
) )
@ -630,7 +628,7 @@ fun GraphHeader(
} }
@Composable @Composable
fun UncommitedChangesLine( fun UncommittedChangesLine(
graphWidth: Dp, graphWidth: Dp,
isSelected: Boolean, isSelected: Boolean,
repositoryState: RepositoryState, repositoryState: RepositoryState,
@ -649,7 +647,7 @@ fun UncommitedChangesLine(
repositoryState.isMerging -> "Pending changes to merge" repositoryState.isMerging -> "Pending changes to merge"
repositoryState.isCherryPicking -> "Pending changes to cherry-pick" repositoryState.isCherryPicking -> "Pending changes to cherry-pick"
repositoryState.isReverting -> "Pending changes to revert" repositoryState.isReverting -> "Pending changes to revert"
else -> "Uncommited changes" else -> "Uncommitted changes"
} }
Text( Text(
@ -1078,7 +1076,7 @@ fun CommitNode(
} }
@Composable @Composable
fun UncommitedChangesGraphNode( fun UncommittedChangesGraphNode(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
hasPreviousCommits: Boolean, hasPreviousCommits: Boolean,
isSelected: Boolean, isSelected: Boolean,

View File

@ -3,10 +3,10 @@ package com.jetpackduba.gitnuro.ui.log
import com.jetpackduba.gitnuro.git.graph.GraphNode import com.jetpackduba.gitnuro.git.graph.GraphNode
import org.eclipse.jgit.lib.Ref import org.eclipse.jgit.lib.Ref
sealed class LogDialog { sealed interface LogDialog {
object None : LogDialog() data object None : LogDialog
data class NewBranch(val graphNode: GraphNode) : LogDialog() data class NewBranch(val graphNode: GraphNode) : LogDialog
data class NewTag(val graphNode: GraphNode) : LogDialog() data class NewTag(val graphNode: GraphNode) : LogDialog
data class ResetBranch(val graphNode: GraphNode) : LogDialog() data class ResetBranch(val graphNode: GraphNode) : LogDialog
data class ChangeDefaultBranch(val ref: Ref) : LogDialog() data class ChangeDefaultBranch(val ref: Ref) : LogDialog
} }

View File

@ -115,9 +115,9 @@ class CommitChangesViewModel @Inject constructor(
} }
} }
sealed class CommitChangesState { sealed interface CommitChangesState {
object Loading : CommitChangesState() data object Loading : CommitChangesState
data class Loaded(val commit: RevCommit, val changes: List<DiffEntry>, val changesFiltered: List<DiffEntry>) : data class Loaded(val commit: RevCommit, val changes: List<DiffEntry>, val changesFiltered: List<DiffEntry>) :
CommitChangesState() CommitChangesState
} }

View File

@ -106,8 +106,8 @@ class DiffViewModel @Inject constructor(
// If it's a different file or different state (index or workdir), reset the scroll state // If it's a different file or different state (index or workdir), reset the scroll state
if ( if (
oldDiffEntryType?.filePath != diffEntryType.filePath || oldDiffEntryType?.filePath != diffEntryType.filePath ||
oldDiffEntryType is DiffEntryType.UncommitedDiff && oldDiffEntryType is DiffEntryType.UncommittedDiff &&
diffEntryType is DiffEntryType.UncommitedDiff && diffEntryType is DiffEntryType.UncommittedDiff &&
oldDiffEntryType.statusEntry.filePath == diffEntryType.statusEntry.filePath && oldDiffEntryType.statusEntry.filePath == diffEntryType.statusEntry.filePath &&
oldDiffEntryType::class != diffEntryType::class oldDiffEntryType::class != diffEntryType::class
) { ) {

View File

@ -19,7 +19,7 @@ import com.jetpackduba.gitnuro.git.remote_operations.PullFromSpecificBranchUseCa
import com.jetpackduba.gitnuro.git.remote_operations.PushToSpecificBranchUseCase import com.jetpackduba.gitnuro.git.remote_operations.PushToSpecificBranchUseCase
import com.jetpackduba.gitnuro.git.tags.CreateTagOnCommitUseCase import com.jetpackduba.gitnuro.git.tags.CreateTagOnCommitUseCase
import com.jetpackduba.gitnuro.git.tags.DeleteTagUseCase import com.jetpackduba.gitnuro.git.tags.DeleteTagUseCase
import com.jetpackduba.gitnuro.git.workspace.CheckHasUncommitedChangesUseCase import com.jetpackduba.gitnuro.git.workspace.CheckHasUncommittedChangesUseCase
import com.jetpackduba.gitnuro.git.workspace.GetStatusSummaryUseCase import com.jetpackduba.gitnuro.git.workspace.GetStatusSummaryUseCase
import com.jetpackduba.gitnuro.git.workspace.StatusSummary import com.jetpackduba.gitnuro.git.workspace.StatusSummary
import com.jetpackduba.gitnuro.preferences.AppSettings import com.jetpackduba.gitnuro.preferences.AppSettings
@ -50,7 +50,7 @@ private const val LOG_MIN_TIME_IN_MS_TO_SHOW_LOAD = 500L
class LogViewModel @Inject constructor( class LogViewModel @Inject constructor(
private val getLogUseCase: GetLogUseCase, private val getLogUseCase: GetLogUseCase,
private val getStatusSummaryUseCase: GetStatusSummaryUseCase, private val getStatusSummaryUseCase: GetStatusSummaryUseCase,
private val checkHasUncommittedChangesUseCase: CheckHasUncommitedChangesUseCase, private val checkHasUncommittedChangesUseCase: CheckHasUncommittedChangesUseCase,
private val getCurrentBranchUseCase: GetCurrentBranchUseCase, private val getCurrentBranchUseCase: GetCurrentBranchUseCase,
private val checkoutRefUseCase: CheckoutRefUseCase, private val checkoutRefUseCase: CheckoutRefUseCase,
private val createBranchOnCommitUseCase: CreateBranchOnCommitUseCase, private val createBranchOnCommitUseCase: CreateBranchOnCommitUseCase,
@ -86,7 +86,7 @@ class LogViewModel @Inject constructor(
.filterIsInstance<SelectedItem.CommitBasedItem>() .filterIsInstance<SelectedItem.CommitBasedItem>()
.map { it.revCommit } .map { it.revCommit }
val scrollToUncommitedChanges: Flow<SelectedItem.UncommitedChanges> = tabState.taskEvent val scrollToUncommittedChanges: Flow<SelectedItem.UncommittedChanges> = tabState.taskEvent
.filterIsInstance<TaskEvent.ScrollToGraphItem>() .filterIsInstance<TaskEvent.ScrollToGraphItem>()
.map { it.selectedItem } .map { it.selectedItem }
.filterIsInstance() .filterIsInstance()
@ -123,7 +123,7 @@ class LogViewModel @Inject constructor(
RefreshType.UNCOMMITTED_CHANGES_AND_LOG, RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
) { refreshType -> ) { refreshType ->
if (refreshType == RefreshType.UNCOMMITTED_CHANGES) { if (refreshType == RefreshType.UNCOMMITTED_CHANGES) {
uncommitedChangesLoadLog(tabState.git) uncommittedChangesLoadLog(tabState.git)
} else } else
refresh(tabState.git) refresh(tabState.git)
} }
@ -143,7 +143,7 @@ class LogViewModel @Inject constructor(
git = git, git = git,
) )
val hasUncommitedChanges = statusSummary.total > 0 val hasUncommittedChanges = statusSummary.total > 0
val commitsLimit = if (appSettings.commitsLimitEnabled) { val commitsLimit = if (appSettings.commitsLimitEnabled) {
appSettings.commitsLimit appSettings.commitsLimit
} else } else
@ -154,10 +154,10 @@ class LogViewModel @Inject constructor(
} else } else
-1 -1
val log = getLogUseCase(git, currentBranch, hasUncommitedChanges, commitsLimit) val log = getLogUseCase(git, currentBranch, hasUncommittedChanges, commitsLimit)
_logStatus.value = _logStatus.value =
LogStatus.Loaded(hasUncommitedChanges, log, currentBranch, statusSummary, commitsLimitDisplayed) LogStatus.Loaded(hasUncommittedChanges, log, currentBranch, statusSummary, commitsLimitDisplayed)
// Remove search filter if the log has been updated // Remove search filter if the log has been updated
_logSearchFilterResults.value = LogSearch.NotSearching _logSearchFilterResults.value = LogSearch.NotSearching
@ -271,11 +271,11 @@ class LogViewModel @Inject constructor(
deleteTagUseCase(git, tag) deleteTagUseCase(git, tag)
} }
private suspend fun uncommitedChangesLoadLog(git: Git) { private suspend fun uncommittedChangesLoadLog(git: Git) {
val currentBranch = getCurrentBranchUseCase(git) val currentBranch = getCurrentBranchUseCase(git)
val hasUncommitedChanges = checkHasUncommittedChangesUseCase(git) val hasUncommittedChanges = checkHasUncommittedChangesUseCase(git)
val statsSummary = if (hasUncommitedChanges) { val statsSummary = if (hasUncommittedChanges) {
getStatusSummaryUseCase( getStatusSummaryUseCase(
git = git, git = git,
) )
@ -286,7 +286,7 @@ class LogViewModel @Inject constructor(
if (previousLogStatusValue is LogStatus.Loaded) { if (previousLogStatusValue is LogStatus.Loaded) {
val newLogStatusValue = LogStatus.Loaded( val newLogStatusValue = LogStatus.Loaded(
hasUncommittedChanges = hasUncommitedChanges, hasUncommittedChanges = hasUncommittedChanges,
plotCommitList = previousLogStatusValue.plotCommitList, plotCommitList = previousLogStatusValue.plotCommitList,
currentBranch = currentBranch, currentBranch = currentBranch,
statusSummary = statsSummary, statusSummary = statsSummary,
@ -309,10 +309,10 @@ class LogViewModel @Inject constructor(
rebaseBranchUseCase(git, ref) rebaseBranchUseCase(git, ref)
} }
fun selectUncommitedChanges() = tabState.runOperation( fun selectUncommittedChanges() = tabState.runOperation(
refreshType = RefreshType.NONE, refreshType = RefreshType.NONE,
) { ) {
tabState.newSelectedItem(SelectedItem.UncommitedChanges) tabState.newSelectedItem(SelectedItem.UncommittedChanges)
val searchValue = _logSearchFilterResults.value val searchValue = _logSearchFilterResults.value
if (searchValue is LogSearch.SearchResults) { if (searchValue is LogSearch.SearchResults) {
@ -445,22 +445,22 @@ class LogViewModel @Inject constructor(
} }
} }
sealed class LogStatus { sealed interface LogStatus {
data object Loading : LogStatus() data object Loading : LogStatus
class Loaded( class Loaded(
val hasUncommittedChanges: Boolean, val hasUncommittedChanges: Boolean,
val plotCommitList: GraphCommitList, val plotCommitList: GraphCommitList,
val currentBranch: Ref?, val currentBranch: Ref?,
val statusSummary: StatusSummary, val statusSummary: StatusSummary,
val commitsLimit: Int, val commitsLimit: Int,
) : LogStatus() ) : LogStatus
} }
sealed class LogSearch { sealed interface LogSearch {
data object NotSearching : LogSearch() data object NotSearching : LogSearch
data class SearchResults( data class SearchResults(
val commits: List<GraphNode>, val commits: List<GraphNode>,
val index: Int, val index: Int,
val totalCount: Int = commits.count(), val totalCount: Int = commits.count(),
) : LogSearch() ) : LogSearch
} }

View File

@ -44,7 +44,7 @@ class SettingsViewModel @Inject constructor(
appSettings.commitsLimitEnabled = value appSettings.commitsLimitEnabled = value
} }
var swapUncommitedChanges: Boolean var swapUncommittedChanges: Boolean
get() = appSettings.swapUncommittedChanges get() = appSettings.swapUncommittedChanges
set(value) { set(value) {
appSettings.swapUncommittedChanges = value appSettings.swapUncommittedChanges = value

View File

@ -49,7 +49,7 @@ class StatusViewModel @Inject constructor(
private val getStatusUseCase: GetStatusUseCase, private val getStatusUseCase: GetStatusUseCase,
private val getStagedUseCase: GetStagedUseCase, private val getStagedUseCase: GetStagedUseCase,
private val getUnstagedUseCase: GetUnstagedUseCase, private val getUnstagedUseCase: GetUnstagedUseCase,
private val checkHasUncommitedChangesUseCase: CheckHasUncommitedChangesUseCase, private val checkHasUncommittedChangesUseCase: CheckHasUncommittedChangesUseCase,
private val doCommitUseCase: DoCommitUseCase, private val doCommitUseCase: DoCommitUseCase,
private val loadAuthorUseCase: LoadAuthorUseCase, private val loadAuthorUseCase: LoadAuthorUseCase,
private val saveAuthorUseCase: SaveAuthorUseCase, private val saveAuthorUseCase: SaveAuthorUseCase,
@ -72,7 +72,7 @@ class StatusViewModel @Inject constructor(
private val _searchFilterStaged = MutableStateFlow(TextFieldValue("")) private val _searchFilterStaged = MutableStateFlow(TextFieldValue(""))
val searchFilterStaged: StateFlow<TextFieldValue> = _searchFilterStaged val searchFilterStaged: StateFlow<TextFieldValue> = _searchFilterStaged
val swapUncommitedChanges = appSettings.swapUncommittedChangesFlow val swapUncommittedChanges = appSettings.swapUncommittedChangesFlow
val rebaseInteractiveState = sharedRepositoryStateManager.rebaseInteractiveState val rebaseInteractiveState = sharedRepositoryStateManager.rebaseInteractiveState
private val _stageState = MutableStateFlow<StageState>(StageState.Loading) private val _stageState = MutableStateFlow<StageState>(StageState.Loading)
@ -128,7 +128,7 @@ class StatusViewModel @Inject constructor(
var hasPreviousCommits = true // When false, disable "amend previous commit" var hasPreviousCommits = true // When false, disable "amend previous commit"
private var lastUncommitedChangesState = false private var lastUncommittedChangesState = false
val stagedLazyListState = MutableStateFlow(LazyListState(0, 0)) val stagedLazyListState = MutableStateFlow(LazyListState(0, 0))
val unstagedLazyListState = MutableStateFlow(LazyListState(0, 0)) val unstagedLazyListState = MutableStateFlow(LazyListState(0, 0))
@ -276,8 +276,8 @@ class StatusViewModel @Inject constructor(
return message.orEmpty().replace("\t", " ") return message.orEmpty().replace("\t", " ")
} }
private suspend fun loadHasUncommitedChanges(git: Git) = withContext(Dispatchers.IO) { private suspend fun loadHasUncommittedChanges(git: Git) = withContext(Dispatchers.IO) {
lastUncommitedChangesState = checkHasUncommitedChangesUseCase(git) lastUncommittedChangesState = checkHasUncommittedChangesUseCase(git)
} }
fun amend(isAmend: Boolean) { fun amend(isAmend: Boolean) {
@ -346,23 +346,7 @@ class StatusViewModel @Inject constructor(
suspend fun refresh(git: Git) = withContext(Dispatchers.IO) { suspend fun refresh(git: Git) = withContext(Dispatchers.IO) {
loadStatus(git) loadStatus(git)
loadHasUncommitedChanges(git) loadHasUncommittedChanges(git)
}
/**
* Checks if there are uncommited changes and returns if the state has changed (
*/
suspend fun updateHasUncommitedChanges(git: Git): Boolean {
val hadUncommitedChanges = this.lastUncommitedChangesState
loadStatus(git)
loadHasUncommitedChanges(git)
val hasNowUncommitedChanges = this.lastUncommitedChangesState
hasPreviousCommits = checkHasPreviousCommitsUseCase(git)
// Return true to update the log only if the uncommitedChanges status has changed
return (hasNowUncommitedChanges != hadUncommitedChanges)
} }
fun continueRebase(message: String) = tabState.safeProcessing( fun continueRebase(message: String) = tabState.safeProcessing(
@ -469,15 +453,15 @@ class StatusViewModel @Inject constructor(
} }
} }
sealed class StageState { sealed interface StageState {
object Loading : StageState() data object Loading : StageState
data class Loaded( data class Loaded(
val staged: List<StatusEntry>, val staged: List<StatusEntry>,
val stagedFiltered: List<StatusEntry>, val stagedFiltered: List<StatusEntry>,
val unstaged: List<StatusEntry>, val unstaged: List<StatusEntry>,
val unstagedFiltered: List<StatusEntry>, val unstagedFiltered: List<StatusEntry>,
val isPartiallyReloading: Boolean val isPartiallyReloading: Boolean
) : StageState() ) : StageState
} }
data class CommitMessage(val message: String, val messageType: MessageType) data class CommitMessage(val message: String, val messageType: MessageType)

View File

@ -169,7 +169,7 @@ class TabViewModel @Inject constructor(
directory.absolutePath directory.absolutePath
onRepositoryChanged(path) onRepositoryChanged(path)
tabState.newSelectedItem(selectedItem = SelectedItem.UncommitedChanges) tabState.newSelectedItem(selectedItem = SelectedItem.UncommittedChanges)
newDiffSelected = null newDiffSelected = null
refreshRepositoryInfo() refreshRepositoryInfo()
@ -272,11 +272,11 @@ class TabViewModel @Inject constructor(
} else { } else {
printLog(TAG, "Changes detected, partial refresh") printLog(TAG, "Changes detected, partial refresh")
checkUncommitedChanges() checkUncommittedChanges()
} }
} }
private suspend fun checkUncommitedChanges() = tabState.runOperation( private suspend fun checkUncommittedChanges() = tabState.runOperation(
refreshType = RefreshType.NONE, refreshType = RefreshType.NONE,
) { ) {
updateDiffEntry() updateDiffEntry()
@ -445,5 +445,5 @@ sealed interface BlameState {
data class Loaded(val filePath: String, val blameResult: BlameResult, val isMinimized: Boolean = false) : BlameState data class Loaded(val filePath: String, val blameResult: BlameResult, val isMinimized: Boolean = false) : BlameState
object None : BlameState data object None : BlameState
} }