Add support multiselect
This commit is contained in:
parent
c1d122b3b7
commit
bbc8132406
@ -24,8 +24,12 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.*
|
||||
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
||||
import com.jetpackduba.gitnuro.git.DiffEntryType
|
||||
import com.jetpackduba.gitnuro.git.graph.GraphNode
|
||||
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
||||
import com.jetpackduba.gitnuro.keybindings.matchesBinding
|
||||
import com.jetpackduba.gitnuro.ui.changes.CommitChanges
|
||||
import com.jetpackduba.gitnuro.ui.changes.MultiCommitChanges
|
||||
import com.jetpackduba.gitnuro.ui.changes.UncommitedChanges
|
||||
import com.jetpackduba.gitnuro.ui.components.PrimaryButton
|
||||
import com.jetpackduba.gitnuro.ui.components.ScrollableColumn
|
||||
import com.jetpackduba.gitnuro.ui.dialogs.*
|
||||
@ -379,45 +383,60 @@ fun MainContentView(
|
||||
modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
) {
|
||||
val safeSelectedItem = selectedItem
|
||||
if (safeSelectedItem == SelectedItem.UncommitedChanges) {
|
||||
UncommitedChanges(
|
||||
selectedEntryType = diffSelected,
|
||||
repositoryState = repositoryState,
|
||||
onStagedDiffEntrySelected = { diffEntry ->
|
||||
tabViewModel.minimizeBlame()
|
||||
when (selectedItem) {
|
||||
SelectedItem.UncommitedChanges -> {
|
||||
UncommitedChanges(
|
||||
selectedEntryType = diffSelected,
|
||||
repositoryState = repositoryState,
|
||||
onStagedDiffEntrySelected = { diffEntry ->
|
||||
tabViewModel.minimizeBlame()
|
||||
|
||||
tabViewModel.newDiffSelected = if (diffEntry != null) {
|
||||
if (repositoryState == RepositoryState.SAFE)
|
||||
DiffEntryType.SafeStagedDiff(diffEntry)
|
||||
else
|
||||
DiffEntryType.UnsafeStagedDiff(diffEntry)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
},
|
||||
onUnstagedDiffEntrySelected = { diffEntry ->
|
||||
tabViewModel.minimizeBlame()
|
||||
|
||||
tabViewModel.newDiffSelected = if (diffEntry != null) {
|
||||
if (repositoryState == RepositoryState.SAFE)
|
||||
DiffEntryType.SafeStagedDiff(diffEntry)
|
||||
tabViewModel.newDiffSelected = DiffEntryType.SafeUnstagedDiff(diffEntry)
|
||||
else
|
||||
DiffEntryType.UnsafeStagedDiff(diffEntry)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
},
|
||||
onUnstagedDiffEntrySelected = { diffEntry ->
|
||||
tabViewModel.minimizeBlame()
|
||||
|
||||
if (repositoryState == RepositoryState.SAFE)
|
||||
tabViewModel.newDiffSelected = DiffEntryType.SafeUnstagedDiff(diffEntry)
|
||||
else
|
||||
tabViewModel.newDiffSelected = DiffEntryType.UnsafeUnstagedDiff(diffEntry)
|
||||
},
|
||||
onBlameFile = { tabViewModel.blameFile(it) },
|
||||
onHistoryFile = { tabViewModel.fileHistory(it) }
|
||||
)
|
||||
} else if (safeSelectedItem is SelectedItem.CommitBasedItem) {
|
||||
CommitChanges(
|
||||
selectedItem = safeSelectedItem,
|
||||
diffSelected = diffSelected,
|
||||
onDiffSelected = { diffEntry ->
|
||||
tabViewModel.minimizeBlame()
|
||||
tabViewModel.newDiffSelected = DiffEntryType.CommitDiff(diffEntry)
|
||||
},
|
||||
onBlame = { tabViewModel.blameFile(it) },
|
||||
onHistory = { tabViewModel.fileHistory(it) },
|
||||
)
|
||||
tabViewModel.newDiffSelected = DiffEntryType.UnsafeUnstagedDiff(diffEntry)
|
||||
},
|
||||
onBlameFile = { tabViewModel.blameFile(it) },
|
||||
onHistoryFile = { tabViewModel.fileHistory(it) }
|
||||
)
|
||||
}
|
||||
is SelectedItem.CommitBasedItem -> {
|
||||
CommitChanges(
|
||||
selectedItem = selectedItem,
|
||||
diffSelected = diffSelected,
|
||||
onDiffSelected = { diffEntry ->
|
||||
tabViewModel.minimizeBlame()
|
||||
tabViewModel.newDiffSelected = DiffEntryType.CommitDiff(diffEntry)
|
||||
},
|
||||
onBlame = { tabViewModel.blameFile(it) },
|
||||
onHistory = { tabViewModel.fileHistory(it) },
|
||||
)
|
||||
}
|
||||
is SelectedItem.MultiCommitBasedItem -> {
|
||||
MultiCommitChanges(
|
||||
selectedItem = selectedItem,
|
||||
diffSelected = diffSelected,
|
||||
onDiffSelected = { diffEntry ->
|
||||
tabViewModel.minimizeBlame()
|
||||
tabViewModel.newDiffSelected = DiffEntryType.CommitDiff(diffEntry)
|
||||
},
|
||||
onBlame = { tabViewModel.blameFile(it) },
|
||||
onHistory = { tabViewModel.fileHistory(it) },
|
||||
)
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -450,8 +469,21 @@ fun SplitterScope.repositorySplitter() {
|
||||
sealed class SelectedItem {
|
||||
object None : SelectedItem()
|
||||
object UncommitedChanges : SelectedItem()
|
||||
data class MultiCommitBasedItem(
|
||||
val itemList: List<RevCommit>,
|
||||
val targetCommit: RevCommit,
|
||||
) : SelectedItem()
|
||||
sealed class CommitBasedItem(val revCommit: RevCommit) : SelectedItem()
|
||||
class Ref(revCommit: RevCommit) : CommitBasedItem(revCommit)
|
||||
class Commit(revCommit: RevCommit) : CommitBasedItem(revCommit)
|
||||
class Stash(revCommit: RevCommit) : CommitBasedItem(revCommit)
|
||||
}
|
||||
|
||||
fun SelectedItem.containCommit(commit: RevCommit): Boolean {
|
||||
return when (this) {
|
||||
is SelectedItem.UncommitedChanges,
|
||||
is SelectedItem.None -> false
|
||||
is SelectedItem.MultiCommitBasedItem -> this.itemList.contains(commit)
|
||||
is SelectedItem.CommitBasedItem -> this.revCommit == commit
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.jetpackduba.gitnuro.ui
|
||||
package com.jetpackduba.gitnuro.ui.changes
|
||||
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
@ -19,12 +19,14 @@ import androidx.compose.ui.unit.dp
|
||||
import com.jetpackduba.gitnuro.extensions.*
|
||||
import com.jetpackduba.gitnuro.git.DiffEntryType
|
||||
import com.jetpackduba.gitnuro.theme.*
|
||||
import com.jetpackduba.gitnuro.ui.SelectedItem
|
||||
import com.jetpackduba.gitnuro.ui.components.AvatarImage
|
||||
import com.jetpackduba.gitnuro.ui.components.ScrollableLazyColumn
|
||||
import com.jetpackduba.gitnuro.ui.components.TooltipText
|
||||
import com.jetpackduba.gitnuro.ui.components.gitnuroViewModel
|
||||
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenu
|
||||
import com.jetpackduba.gitnuro.ui.context_menu.commitedChangesEntriesContextMenuItems
|
||||
import com.jetpackduba.gitnuro.viewmodels.CommitChanges
|
||||
import com.jetpackduba.gitnuro.viewmodels.CommitChangesStatus
|
||||
import com.jetpackduba.gitnuro.viewmodels.CommitChangesViewModel
|
||||
import kotlinx.coroutines.delay
|
||||
@ -253,65 +255,77 @@ fun CommitLogChanges(
|
||||
)
|
||||
}
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.height(40.dp)
|
||||
.fillMaxWidth()
|
||||
.handMouseClickable {
|
||||
onDiffSelected(diffEntry)
|
||||
}
|
||||
.backgroundIf(
|
||||
condition = diffSelected is DiffEntryType.CommitDiff && diffSelected.diffEntry == diffEntry,
|
||||
color = MaterialTheme.colors.backgroundSelected,
|
||||
),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Spacer(modifier = Modifier.weight(2f))
|
||||
|
||||
Row {
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 8.dp)
|
||||
.size(16.dp),
|
||||
imageVector = diffEntry.icon,
|
||||
contentDescription = null,
|
||||
tint = diffEntry.iconColor,
|
||||
)
|
||||
|
||||
if (diffEntry.parentDirectoryPath.isNotEmpty()) {
|
||||
Text(
|
||||
text = diffEntry.parentDirectoryPath.removeSuffix("/"),
|
||||
modifier = Modifier.weight(1f, fill = false),
|
||||
maxLines = 1,
|
||||
softWrap = false,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.body2,
|
||||
color = MaterialTheme.colors.onBackgroundSecondary,
|
||||
)
|
||||
|
||||
Text(
|
||||
text = "/",
|
||||
maxLines = 1,
|
||||
softWrap = false,
|
||||
style = MaterialTheme.typography.body2,
|
||||
overflow = TextOverflow.Visible,
|
||||
color = MaterialTheme.colors.onBackgroundSecondary,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = diffEntry.fileName,
|
||||
maxLines = 1,
|
||||
softWrap = false,
|
||||
modifier = Modifier.padding(end = 16.dp),
|
||||
style = MaterialTheme.typography.body2,
|
||||
color = MaterialTheme.colors.onBackground,
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.weight(2f))
|
||||
|
||||
}
|
||||
CommitLogChangesItem(
|
||||
diffEntry = diffEntry,
|
||||
diffSelected = diffSelected,
|
||||
onDiffSelected = { onDiffSelected(diffEntry) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun CommitLogChangesItem(
|
||||
diffEntry: DiffEntry,
|
||||
diffSelected: DiffEntryType?,
|
||||
onDiffSelected: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.height(40.dp)
|
||||
.fillMaxWidth()
|
||||
.handMouseClickable {
|
||||
onDiffSelected()
|
||||
}
|
||||
.backgroundIf(
|
||||
condition = diffSelected is DiffEntryType.CommitDiff && diffSelected.diffEntry == diffEntry,
|
||||
color = MaterialTheme.colors.backgroundSelected,
|
||||
),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Spacer(modifier = Modifier.weight(2f))
|
||||
|
||||
Row {
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 8.dp)
|
||||
.size(16.dp),
|
||||
imageVector = diffEntry.icon,
|
||||
contentDescription = null,
|
||||
tint = diffEntry.iconColor,
|
||||
)
|
||||
|
||||
if (diffEntry.parentDirectoryPath.isNotEmpty()) {
|
||||
Text(
|
||||
text = diffEntry.parentDirectoryPath.removeSuffix("/"),
|
||||
modifier = Modifier.weight(1f, fill = false),
|
||||
maxLines = 1,
|
||||
softWrap = false,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.body2,
|
||||
color = MaterialTheme.colors.onBackgroundSecondary,
|
||||
)
|
||||
|
||||
Text(
|
||||
text = "/",
|
||||
maxLines = 1,
|
||||
softWrap = false,
|
||||
style = MaterialTheme.typography.body2,
|
||||
overflow = TextOverflow.Visible,
|
||||
color = MaterialTheme.colors.onBackgroundSecondary,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = diffEntry.fileName,
|
||||
maxLines = 1,
|
||||
softWrap = false,
|
||||
modifier = Modifier.padding(end = 16.dp),
|
||||
style = MaterialTheme.typography.body2,
|
||||
color = MaterialTheme.colors.onBackground,
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.weight(2f))
|
||||
}
|
||||
}
|
@ -0,0 +1,137 @@
|
||||
package com.jetpackduba.gitnuro.ui.changes
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Divider
|
||||
import androidx.compose.material.LinearProgressIndicator
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.jetpackduba.gitnuro.git.DiffEntryType
|
||||
import com.jetpackduba.gitnuro.theme.tertiarySurface
|
||||
import com.jetpackduba.gitnuro.ui.SelectedItem
|
||||
import com.jetpackduba.gitnuro.ui.components.ScrollableColumn
|
||||
import com.jetpackduba.gitnuro.ui.components.ScrollableLazyColumn
|
||||
import com.jetpackduba.gitnuro.ui.components.gitnuroViewModel
|
||||
import com.jetpackduba.gitnuro.viewmodels.CommitChanges
|
||||
import com.jetpackduba.gitnuro.viewmodels.MultiCommitChangesStatus
|
||||
import com.jetpackduba.gitnuro.viewmodels.MultiCommitChangesViewModel
|
||||
import org.eclipse.jgit.diff.DiffEntry
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
|
||||
|
||||
@Composable
|
||||
fun MultiCommitChanges(
|
||||
multiCommitChangesViewModel: MultiCommitChangesViewModel = gitnuroViewModel(),
|
||||
selectedItem: SelectedItem.MultiCommitBasedItem,
|
||||
onDiffSelected: (DiffEntry) -> Unit,
|
||||
diffSelected: DiffEntryType?,
|
||||
onBlame: (String) -> Unit,
|
||||
onHistory: (String) -> Unit,
|
||||
) {
|
||||
LaunchedEffect(selectedItem) {
|
||||
multiCommitChangesViewModel.loadChanges(selectedItem.itemList)
|
||||
}
|
||||
|
||||
val commitChangesStatusState = multiCommitChangesViewModel.commitsChangesStatus.collectAsState()
|
||||
|
||||
when (val commitChangesStatus = commitChangesStatusState.value) {
|
||||
MultiCommitChangesStatus.Loading -> {
|
||||
LinearProgressIndicator(modifier = Modifier.fillMaxWidth(), color = MaterialTheme.colors.primaryVariant)
|
||||
}
|
||||
|
||||
is MultiCommitChangesStatus.Loaded -> {
|
||||
MultiCommitChangesView(
|
||||
diffSelected = diffSelected,
|
||||
changes = commitChangesStatus.changesList,
|
||||
onDiffSelected = onDiffSelected,
|
||||
onBlame = onBlame,
|
||||
onHistory = onHistory,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MultiCommitChangesView(
|
||||
changes: List<CommitChanges>,
|
||||
onDiffSelected: (DiffEntry) -> Unit,
|
||||
diffSelected: DiffEntryType?,
|
||||
onBlame: (String) -> Unit,
|
||||
onHistory: (String) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(end = 8.dp, bottom = 8.dp)
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 4.dp)
|
||||
.fillMaxWidth()
|
||||
.weight(1f, fill = true)
|
||||
.background(MaterialTheme.colors.background)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(34.dp)
|
||||
.background(MaterialTheme.colors.tertiarySurface),
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(vertical = 8.dp, horizontal = 16.dp),
|
||||
text = "Files changed",
|
||||
fontWeight = FontWeight.Normal,
|
||||
textAlign = TextAlign.Left,
|
||||
color = MaterialTheme.colors.onBackground,
|
||||
maxLines = 1,
|
||||
style = MaterialTheme.typography.body2,
|
||||
)
|
||||
}
|
||||
|
||||
ScrollableLazyColumn(
|
||||
modifier = Modifier
|
||||
) {
|
||||
items(changes) {commitChanges ->
|
||||
CommitLogChanges(
|
||||
diffSelected = diffSelected,
|
||||
diffEntries = commitChanges.changes,
|
||||
onDiffSelected = onDiffSelected,
|
||||
onBlame = onBlame,
|
||||
onHistory = onHistory,
|
||||
)
|
||||
|
||||
Text(
|
||||
text = commitChanges.commit.fullMessage,
|
||||
style = MaterialTheme.typography.body1,
|
||||
color = MaterialTheme.colors.onBackground,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp),
|
||||
)
|
||||
|
||||
Divider(
|
||||
color = MaterialTheme.colors.onBackground,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
@file:OptIn(ExperimentalAnimationApi::class, ExperimentalComposeUiApi::class, ExperimentalFoundationApi::class)
|
||||
|
||||
package com.jetpackduba.gitnuro.ui
|
||||
package com.jetpackduba.gitnuro.ui.changes
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
@ -305,11 +305,91 @@ class LogViewModel @Inject constructor(
|
||||
NONE_MATCHING_INDEX
|
||||
}
|
||||
|
||||
fun selectLogLine(commit: GraphNode) = tabState.runOperation(
|
||||
fun selectLogLine(
|
||||
commit: GraphNode,
|
||||
multiSelect: Boolean,
|
||||
rangeSelect: Boolean
|
||||
) = tabState.runOperation(
|
||||
refreshType = RefreshType.NONE,
|
||||
) {
|
||||
tabState.newSelectedItem(SelectedItem.Commit(commit))
|
||||
when {
|
||||
multiSelect -> selectMultiLogLines(commit)
|
||||
rangeSelect -> selectRangeLogLines(commit)
|
||||
else -> selectSingleLogLine(commit)
|
||||
}
|
||||
|
||||
setLogSearchFilterByCommit(commit)
|
||||
}
|
||||
|
||||
// like with ctrl pressed
|
||||
private suspend fun selectMultiLogLines(commit: GraphNode) {
|
||||
when (val selectedItem = tabState.selectedItem.value) {
|
||||
is SelectedItem.None,
|
||||
is SelectedItem.UncommitedChanges -> selectSingleLogLine(commit)
|
||||
is SelectedItem.CommitBasedItem -> {
|
||||
if (selectedItem.revCommit == commit) {
|
||||
tabState.noneSelected()
|
||||
} else {
|
||||
val list = listOf(selectedItem.revCommit, commit)
|
||||
tabState.newSelectedItem(SelectedItem.MultiCommitBasedItem(list, selectedItem.revCommit))
|
||||
}
|
||||
}
|
||||
is SelectedItem.MultiCommitBasedItem -> {
|
||||
val revList = selectedItem.itemList
|
||||
val list = if (revList.contains(commit)) {
|
||||
revList - commit
|
||||
} else {
|
||||
revList + commit
|
||||
}
|
||||
|
||||
val item = if (list.size > 1) {
|
||||
SelectedItem.MultiCommitBasedItem(list, list.maxBy { it.commitTime })
|
||||
} else {
|
||||
SelectedItem.Commit(list.first())
|
||||
}
|
||||
|
||||
tabState.newSelectedItem(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// like with shift pressed
|
||||
private suspend fun selectRangeLogLines(commit: GraphNode) {
|
||||
when (val selectedItem = tabState.selectedItem.value) {
|
||||
is SelectedItem.None,
|
||||
is SelectedItem.UncommitedChanges -> selectSingleLogLine(commit)
|
||||
is SelectedItem.CommitBasedItem -> {
|
||||
val list = getRangeCommitsFromOneToOne(selectedItem.revCommit, commit)
|
||||
tabState.newSelectedItem(SelectedItem.MultiCommitBasedItem(list, selectedItem.revCommit))
|
||||
}
|
||||
is SelectedItem.MultiCommitBasedItem -> {
|
||||
val list = getRangeCommitsFromOneToOne(selectedItem.targetCommit, commit)
|
||||
tabState.newSelectedItem(SelectedItem.MultiCommitBasedItem(list, selectedItem.targetCommit))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getRangeCommitsFromOneToOne(from: RevCommit, to: RevCommit): List<RevCommit> {
|
||||
return if (from != to && logStatus.value is LogStatus.Loaded) {
|
||||
val commitList = (logStatus.value as LogStatus.Loaded).plotCommitList
|
||||
|
||||
val first = commitList.indexOf(from)
|
||||
val last = commitList.indexOf(to)
|
||||
val range = if (first < last) first.rangeTo(last) else last.rangeTo(first)
|
||||
|
||||
println(range)
|
||||
|
||||
commitList.slice(range)
|
||||
} else {
|
||||
listOf(from)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun selectSingleLogLine(commit: GraphNode) {
|
||||
tabState.newSelectedItem(SelectedItem.Commit(commit))
|
||||
}
|
||||
|
||||
private fun setLogSearchFilterByCommit(commit: GraphNode) {
|
||||
val searchValue = _logSearchFilterResults.value
|
||||
if (searchValue is LogSearch.SearchResults) {
|
||||
var index = searchValue.commits.indexOf(commit)
|
||||
|
@ -0,0 +1,52 @@
|
||||
package com.jetpackduba.gitnuro.viewmodels
|
||||
|
||||
import com.jetpackduba.gitnuro.extensions.delayedStateChange
|
||||
import com.jetpackduba.gitnuro.extensions.filePath
|
||||
import com.jetpackduba.gitnuro.git.RefreshType
|
||||
import com.jetpackduba.gitnuro.git.TabState
|
||||
import com.jetpackduba.gitnuro.git.diff.GetCommitDiffEntriesUseCase
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import org.eclipse.jgit.diff.DiffEntry
|
||||
import org.eclipse.jgit.revwalk.DepthWalk.Commit
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val MIN_TIME_IN_MS_TO_SHOW_LOAD = 300L
|
||||
|
||||
class MultiCommitChangesViewModel @Inject constructor(
|
||||
private val tabState: TabState,
|
||||
private val getCommitDiffEntriesUseCase: GetCommitDiffEntriesUseCase,
|
||||
) {
|
||||
private val _commitsChangesStatus = MutableStateFlow<MultiCommitChangesStatus>(MultiCommitChangesStatus.Loading)
|
||||
val commitsChangesStatus: StateFlow<MultiCommitChangesStatus> = _commitsChangesStatus
|
||||
|
||||
fun loadChanges(commits: List<RevCommit>) = tabState.runOperation(
|
||||
refreshType = RefreshType.NONE,
|
||||
) { git ->
|
||||
delayedStateChange(
|
||||
delayMs = MIN_TIME_IN_MS_TO_SHOW_LOAD,
|
||||
onDelayTriggered = { _commitsChangesStatus.value = MultiCommitChangesStatus.Loading }
|
||||
) {
|
||||
val changes = commits
|
||||
.map { commit ->
|
||||
CommitChanges(
|
||||
commit = commit,
|
||||
changes = getCommitDiffEntriesUseCase(git, commit)
|
||||
)
|
||||
}
|
||||
|
||||
_commitsChangesStatus.value = MultiCommitChangesStatus.Loaded(changes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class MultiCommitChangesStatus {
|
||||
object Loading : MultiCommitChangesStatus()
|
||||
data class Loaded(val changesList: List<CommitChanges>) : MultiCommitChangesStatus()
|
||||
}
|
||||
|
||||
data class CommitChanges(
|
||||
val commit: RevCommit,
|
||||
val changes: List<DiffEntry>,
|
||||
)
|
@ -15,6 +15,7 @@ class TabViewModelsHolder @Inject constructor(
|
||||
stashesViewModel: StashesViewModel,
|
||||
submodulesViewModel: SubmodulesViewModel,
|
||||
commitChangesViewModel: CommitChangesViewModel,
|
||||
multiCommitChangesViewModel: MultiCommitChangesViewModel,
|
||||
cloneViewModel: CloneViewModel,
|
||||
settingsViewModel: SettingsViewModel,
|
||||
// Dynamic VM
|
||||
@ -33,6 +34,7 @@ class TabViewModelsHolder @Inject constructor(
|
||||
stashesViewModel::class to stashesViewModel,
|
||||
submodulesViewModel::class to submodulesViewModel,
|
||||
commitChangesViewModel::class to commitChangesViewModel,
|
||||
multiCommitChangesViewModel::class to multiCommitChangesViewModel,
|
||||
cloneViewModel::class to cloneViewModel,
|
||||
settingsViewModel::class to settingsViewModel,
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user