From fbdf5a4da85c39d37cdfb38df700ef5016a41d06 Mon Sep 17 00:00:00 2001 From: Abdelilah El Aissaoui Date: Sat, 11 Nov 2023 16:42:28 +0100 Subject: [PATCH] Selecting a branch, tag or stash in side panel highlights it --- .../com/jetpackduba/gitnuro/git/TabState.kt | 7 ++-- .../gitnuro/ui/RebaseInteractive.kt | 9 ++---- .../jetpackduba/gitnuro/ui/RepositoryOpen.kt | 3 +- .../com/jetpackduba/gitnuro/ui/SidePanel.kt | 32 +++++++++++++++---- .../gitnuro/ui/components/SideMenuSubentry.kt | 8 +++-- .../viewmodels/sidepanel/BranchesViewModel.kt | 6 ++-- .../viewmodels/sidepanel/RemotesViewModel.kt | 2 +- .../sidepanel/SidePanelViewModel.kt | 4 +++ .../viewmodels/sidepanel/TagsViewModel.kt | 2 +- 9 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/git/TabState.kt b/src/main/kotlin/com/jetpackduba/gitnuro/git/TabState.kt index 27eea22..9a9ad78 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/git/TabState.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/git/TabState.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import org.eclipse.jgit.api.Git import org.eclipse.jgit.lib.ObjectId +import org.eclipse.jgit.lib.Ref import org.eclipse.jgit.revwalk.RevCommit import javax.inject.Inject @@ -242,7 +243,7 @@ class TabState @Inject constructor( } suspend fun newSelectedStash(stash: RevCommit) { - newSelectedItem(SelectedItem.Stash(stash)) + newSelectedItem(SelectedItem.Stash(stash), true) } suspend fun noneSelected() { @@ -260,7 +261,7 @@ class TabState @Inject constructor( } } - fun newSelectedRef(objectId: ObjectId?) = runOperation( + fun newSelectedRef(ref: Ref, objectId: ObjectId?) = runOperation( refreshType = RefreshType.NONE, ) { git -> if (objectId == null) { @@ -271,7 +272,7 @@ class TabState @Inject constructor( if (commit == null) { newSelectedItem(SelectedItem.None) } else { - val newSelectedItem = SelectedItem.Ref(commit) + val newSelectedItem = SelectedItem.Ref(ref, commit) newSelectedItem(newSelectedItem) _taskEvent.emit(TaskEvent.ScrollToGraphItem(newSelectedItem)) } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/RebaseInteractive.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/RebaseInteractive.kt index 6ba4439..411b479 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/RebaseInteractive.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/RebaseInteractive.kt @@ -20,6 +20,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.jetpackduba.gitnuro.AppIcons +import com.jetpackduba.gitnuro.extensions.backgroundIf import com.jetpackduba.gitnuro.theme.backgroundSelected import com.jetpackduba.gitnuro.theme.onBackgroundSecondary import com.jetpackduba.gitnuro.ui.components.AdjustableOutlinedTextField @@ -179,13 +180,7 @@ fun RebaseCommit( .clickable { onFocusLine() } - .run { - if (isSelected) { - background(MaterialTheme.colors.backgroundSelected) - } else { - this - } - } + .backgroundIf(isSelected, MaterialTheme.colors.backgroundSelected) .padding(horizontal = 16.dp, vertical = 8.dp), verticalAlignment = Alignment.CenterVertically, ) { diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt index 7191749..326a327 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt @@ -30,6 +30,7 @@ import com.jetpackduba.gitnuro.ui.diff.Diff import com.jetpackduba.gitnuro.ui.log.Log import com.jetpackduba.gitnuro.viewmodels.BlameState import com.jetpackduba.gitnuro.viewmodels.TabViewModel +import org.eclipse.jgit.lib.Ref import org.eclipse.jgit.lib.RepositoryState import org.eclipse.jgit.revwalk.RevCommit import org.jetbrains.compose.splitpane.ExperimentalSplitPaneApi @@ -413,7 +414,7 @@ sealed class SelectedItem { object None : SelectedItem() object UncommitedChanges : SelectedItem() sealed class CommitBasedItem(val revCommit: RevCommit) : SelectedItem() - class 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 Stash(revCommit: RevCommit) : CommitBasedItem(revCommit) } \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/SidePanel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/SidePanel.kt index cf99ec1..85242d8 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/SidePanel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/SidePanel.kt @@ -37,6 +37,7 @@ fun SidePanel( submodulesViewModel: SubmodulesViewModel = sidePanelViewModel.submodulesViewModel, ) { var filter by remember(sidePanelViewModel) { mutableStateOf(sidePanelViewModel.filter.value) } + val selectedItem by sidePanelViewModel.selectedItem.collectAsState() val branchesState by branchesViewModel.branchesState.collectAsState() val remotesState by remotesViewModel.remoteState.collectAsState() @@ -66,6 +67,7 @@ fun SidePanel( ) { localBranches( branchesState = branchesState, + selectedItem = selectedItem, branchesViewModel = branchesViewModel, onChangeDefaultUpstreamBranch = { setBranchToChangeUpstream(it) } ) @@ -78,11 +80,13 @@ fun SidePanel( tags( tagsState = tagsState, + selectedItem = selectedItem, tagsViewModel = tagsViewModel, ) stashes( stashesState = stashesState, + selectedItem = selectedItem, stashesViewModel = stashesViewModel, ) @@ -165,6 +169,7 @@ fun FilterTextField(value: String, onValueChange: (String) -> Unit, modifier: Mo fun LazyListScope.localBranches( branchesState: BranchesState, + selectedItem: SelectedItem, branchesViewModel: BranchesViewModel, onChangeDefaultUpstreamBranch: (Ref) -> Unit, ) { @@ -191,18 +196,17 @@ fun LazyListScope.localBranches( items(branches, key = { it.name }) { branch -> Branch( branch = branch, + isSelectedItem = selectedItem is SelectedItem.Ref && selectedItem.ref == branch, currentBranch = currentBranch, - isCurrentBranch = currentBranch?.name == branch.name, onBranchClicked = { branchesViewModel.selectBranch(branch) }, onBranchDoubleClicked = { branchesViewModel.checkoutRef(branch) }, onCheckoutBranch = { branchesViewModel.checkoutRef(branch) }, onMergeBranch = { branchesViewModel.mergeBranch(branch) }, - onDeleteBranch = { branchesViewModel.deleteBranch(branch) }, onRebaseBranch = { branchesViewModel.rebaseBranch(branch) }, + onDeleteBranch = { branchesViewModel.deleteBranch(branch) }, onPushToRemoteBranch = { branchesViewModel.pushToRemoteBranch(branch) }, - onPullFromRemoteBranch = { branchesViewModel.pullFromRemoteBranch(branch) }, - onChangeDefaultUpstreamBranch = { onChangeDefaultUpstreamBranch(branch) } - ) + onPullFromRemoteBranch = { branchesViewModel.pullFromRemoteBranch(branch) } + ) { onChangeDefaultUpstreamBranch(branch) } } } } @@ -272,6 +276,7 @@ fun LazyListScope.remotes( fun LazyListScope.tags( tagsState: TagsState, tagsViewModel: TagsViewModel, + selectedItem: SelectedItem, ) { val isExpanded = tagsState.isExpanded val tags = tagsState.tags @@ -295,6 +300,7 @@ fun LazyListScope.tags( items(tags, key = { it.name }) { tag -> Tag( tag, + isSelected = selectedItem is SelectedItem.Ref && selectedItem.ref == tag, onTagClicked = { tagsViewModel.selectTag(tag) }, onCheckoutTag = { tagsViewModel.checkoutRef(tag) }, onDeleteTag = { tagsViewModel.deleteTag(tag) } @@ -306,6 +312,7 @@ fun LazyListScope.tags( fun LazyListScope.stashes( stashesState: StashesState, stashesViewModel: StashesViewModel, + selectedItem: SelectedItem, ) { val isExpanded = stashesState.isExpanded val stashes = stashesState.stashes @@ -329,6 +336,7 @@ fun LazyListScope.stashes( items(stashes, key = { it.name }) { stash -> Stash( stash, + isSelected = selectedItem is SelectedItem.Stash && selectedItem.revCommit == stash, onClick = { stashesViewModel.selectStash(stash) }, onApply = { stashesViewModel.applyStash(stash) }, onPop = { stashesViewModel.popStash(stash) }, @@ -396,7 +404,7 @@ fun LazyListScope.submodules( private fun Branch( branch: Ref, currentBranch: Ref?, - isCurrentBranch: Boolean, + isSelectedItem: Boolean, onBranchClicked: () -> Unit, onBranchDoubleClicked: () -> Unit, onCheckoutBranch: () -> Unit, @@ -407,6 +415,8 @@ private fun Branch( onPullFromRemoteBranch: () -> Unit, onChangeDefaultUpstreamBranch: () -> Unit, ) { + val isCurrentBranch = currentBranch?.name == branch.name + ContextMenu( items = { branchContextMenuItems( @@ -427,6 +437,7 @@ private fun Branch( SideMenuSubentry( text = branch.simpleName, iconResourcePath = AppIcons.BRANCH, + isSelected = isSelectedItem, onClick = onBranchClicked, onDoubleClick = onBranchDoubleClicked, ) { @@ -451,7 +462,8 @@ private fun Remote( SideMenuSubentry( text = remote.remoteInfo.remoteConfig.name, iconResourcePath = AppIcons.CLOUD, - onClick = onRemoteClicked + onClick = onRemoteClicked, + isSelected = false, ) } @@ -487,6 +499,7 @@ private fun RemoteBranches( SideMenuSubentry( text = remoteBranch.simpleName, extraPadding = 24.dp, + isSelected = false, iconResourcePath = AppIcons.BRANCH, onClick = onBranchClicked, onDoubleClick = onCheckoutBranch, @@ -497,6 +510,7 @@ private fun RemoteBranches( @Composable private fun Tag( tag: Ref, + isSelected: Boolean, onTagClicked: () -> Unit, onCheckoutTag: () -> Unit, onDeleteTag: () -> Unit, @@ -511,6 +525,7 @@ private fun Tag( ) { SideMenuSubentry( text = tag.simpleName, + isSelected = isSelected, iconResourcePath = AppIcons.TAG, onClick = onTagClicked, ) @@ -521,6 +536,7 @@ private fun Tag( @Composable private fun Stash( stash: RevCommit, + isSelected: Boolean, onClick: () -> Unit, onApply: () -> Unit, onPop: () -> Unit, @@ -537,6 +553,7 @@ private fun Stash( ) { SideMenuSubentry( text = stash.shortMessage, + isSelected = isSelected, iconResourcePath = AppIcons.STASH, onClick = onClick, ) @@ -569,6 +586,7 @@ private fun Submodule( SideMenuSubentry( text = submodule.first, iconResourcePath = AppIcons.TOPIC, + isSelected = false, onClick = { if (submodule.second.type.isValid()) { onOpenSubmoduleInTab() diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/components/SideMenuSubentry.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/components/SideMenuSubentry.kt index 2b30b03..33b7867 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/components/SideMenuSubentry.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/components/SideMenuSubentry.kt @@ -3,6 +3,7 @@ package com.jetpackduba.gitnuro.ui.components import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.background import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.* import androidx.compose.material.Icon @@ -15,6 +16,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import com.jetpackduba.gitnuro.extensions.backgroundIf +import com.jetpackduba.gitnuro.theme.backgroundSelected const val ENTRY_HEIGHT = 36 @@ -24,6 +27,7 @@ const val ENTRY_HEIGHT = 36 fun SideMenuSubentry( text: String, iconResourcePath: String, + isSelected: Boolean, extraPadding: Dp = 0.dp, onClick: (() -> Unit)? = null, onDoubleClick: (() -> Unit)? = null, @@ -39,8 +43,8 @@ fun SideMenuSubentry( else this } - .padding(start = extraPadding), -// .background(background), + .padding(start = extraPadding) + .backgroundIf(isSelected, MaterialTheme.colors.backgroundSelected), verticalAlignment = Alignment.CenterVertically, ) { Icon( diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/BranchesViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/BranchesViewModel.kt index 5ad58d9..c49959c 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/BranchesViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/BranchesViewModel.kt @@ -9,6 +9,7 @@ import com.jetpackduba.gitnuro.git.rebase.RebaseBranchUseCase import com.jetpackduba.gitnuro.git.remote_operations.PullFromSpecificBranchUseCase import com.jetpackduba.gitnuro.git.remote_operations.PushToSpecificBranchUseCase import com.jetpackduba.gitnuro.preferences.AppSettings +import com.jetpackduba.gitnuro.ui.SelectedItem import dagger.assisted.Assisted import dagger.assisted.AssistedInject import kotlinx.coroutines.CoroutineScope @@ -53,8 +54,7 @@ class BranchesViewModel @AssistedInject constructor( init { tabScope.launch { - tabState.refreshFlowFiltered(RefreshType.ALL_DATA) - { + tabState.refreshFlowFiltered(RefreshType.ALL_DATA) { refresh(tabState.git) } } @@ -105,7 +105,7 @@ class BranchesViewModel @AssistedInject constructor( } fun selectBranch(ref: Ref) { - tabState.newSelectedRef(ref.objectId) + tabState.newSelectedRef(ref, ref.objectId) } fun pushToRemoteBranch(branch: Ref) = tabState.safeProcessing( diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/RemotesViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/RemotesViewModel.kt index 29ec12d..b9053ef 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/RemotesViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/RemotesViewModel.kt @@ -120,7 +120,7 @@ class RemotesViewModel @AssistedInject constructor( } fun selectBranch(ref: Ref) { - tabState.newSelectedRef(ref.objectId) + tabState.newSelectedRef(ref, ref.objectId) } fun deleteRemote(remoteName: String, isNew: Boolean) = tabState.safeProcessing( diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/SidePanelViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/SidePanelViewModel.kt index 9aa3dd3..79849d6 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/SidePanelViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/SidePanelViewModel.kt @@ -1,6 +1,8 @@ package com.jetpackduba.gitnuro.viewmodels.sidepanel import com.jetpackduba.gitnuro.di.factories.* +import com.jetpackduba.gitnuro.git.TabState +import com.jetpackduba.gitnuro.ui.SelectedItem import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import javax.inject.Inject @@ -11,9 +13,11 @@ class SidePanelViewModel @Inject constructor( tagsViewModelFactory: TagsViewModelFactory, stashesViewModelFactory: StashesViewModelFactory, submodulesViewModelFactory: SubmodulesViewModelFactory, + tabState: TabState, ) { private val _filter = MutableStateFlow("") val filter: StateFlow = _filter + val selectedItem: StateFlow = tabState.selectedItem val branchesViewModel: BranchesViewModel = branchesViewModelFactory.create(filter) val remotesViewModel: RemotesViewModel = remotesViewModelFactory.create(filter) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/TagsViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/TagsViewModel.kt index 8a493d6..3cf46cb 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/TagsViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/TagsViewModel.kt @@ -67,7 +67,7 @@ class TagsViewModel @AssistedInject constructor( } fun selectTag(tag: Ref) { - tabState.newSelectedRef(tag.objectId) + tabState.newSelectedRef(tag, tag.objectId) } suspend fun refresh(git: Git) {