From c7954af9ad1db8e20822dc143edbbca65db132aa Mon Sep 17 00:00:00 2001 From: Abdelilah El Aissaoui Date: Wed, 8 Dec 2021 18:30:41 +0100 Subject: [PATCH] Added remotes to side panel --- src/main/kotlin/app/git/BranchesManager.kt | 7 +++ src/main/kotlin/app/git/GitManager.kt | 4 ++ src/main/kotlin/app/git/RemotesManager.kt | 32 ++++++++++ src/main/kotlin/app/ui/Branches.kt | 2 +- src/main/kotlin/app/ui/Remotes.kt | 62 +++++++++++++++++++ src/main/kotlin/app/ui/RepositoryOpen.kt | 1 + .../app/ui/components/SideMenuSubentry.kt | 5 +- src/main/resources/cloud.svg | 1 + 8 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/app/git/RemotesManager.kt create mode 100644 src/main/kotlin/app/ui/Remotes.kt create mode 100644 src/main/resources/cloud.svg diff --git a/src/main/kotlin/app/git/BranchesManager.kt b/src/main/kotlin/app/git/BranchesManager.kt index df2e4bd..d730995 100644 --- a/src/main/kotlin/app/git/BranchesManager.kt +++ b/src/main/kotlin/app/git/BranchesManager.kt @@ -85,4 +85,11 @@ class BranchesManager @Inject constructor() { .setForce(true) // TODO Should it be forced? .call() } + + suspend fun remoteBranches(git: Git) = withContext(Dispatchers.IO) { + git + .branchList() + .setListMode(ListBranchCommand.ListMode.REMOTE) + .call() + } } \ No newline at end of file diff --git a/src/main/kotlin/app/git/GitManager.kt b/src/main/kotlin/app/git/GitManager.kt index 31889bf..925510f 100644 --- a/src/main/kotlin/app/git/GitManager.kt +++ b/src/main/kotlin/app/git/GitManager.kt @@ -15,6 +15,7 @@ import app.AppStateManager import app.app.ErrorsManager import app.app.newErrorNow import kotlinx.coroutines.flow.collect +import org.eclipse.jgit.transport.RemoteConfig import java.io.File import javax.inject.Inject @@ -27,6 +28,7 @@ class GitManager @Inject constructor( private val stashManager: StashManager, private val diffManager: DiffManager, private val tagsManager: TagsManager, + private val remotesManager: RemotesManager, val errorsManager: ErrorsManager, val appStateManager: AppStateManager, private val fileChangesWatcher: FileChangesWatcher, @@ -58,6 +60,7 @@ class GitManager @Inject constructor( val stashStatus: StateFlow = stashManager.stashStatus val credentialsState: StateFlow = credentialsStateManager.credentialsState val cloneStatus: StateFlow = remoteOperationsManager.cloneStatus + val remotes: StateFlow> = remotesManager.remotes private var git: Git? = null @@ -194,6 +197,7 @@ class GitManager @Inject constructor( private suspend fun refreshRepositoryInfo() { statusManager.loadHasUncommitedChanges(safeGit) branchesManager.loadBranches(safeGit) + remotesManager.loadRemotes(safeGit, branchesManager.remoteBranches(safeGit)) tagsManager.loadTags(safeGit) stashManager.loadStashList(safeGit) coLoadLog() diff --git a/src/main/kotlin/app/git/RemotesManager.kt b/src/main/kotlin/app/git/RemotesManager.kt new file mode 100644 index 0000000..fc6ef8a --- /dev/null +++ b/src/main/kotlin/app/git/RemotesManager.kt @@ -0,0 +1,32 @@ +package app.git + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.withContext +import org.eclipse.jgit.api.Git +import org.eclipse.jgit.lib.Ref +import org.eclipse.jgit.transport.RemoteConfig +import javax.inject.Inject + +class RemotesManager @Inject constructor() { + private val _remotes = MutableStateFlow>(listOf()) + val remotes: StateFlow> + get() = _remotes + + suspend fun loadRemotes(git: Git, allRemoteBranches: List) = withContext(Dispatchers.IO) { + val remotes = git.remoteList() + .call() + + val remoteInfoList = remotes.map { remoteConfig -> + val remoteBranches = allRemoteBranches.filter { branch -> + branch.name.startsWith("refs/remotes/${remoteConfig.name}") + } + RemoteInfo(remoteConfig, remoteBranches) + } + + _remotes.value = remoteInfoList + } +} + +data class RemoteInfo(val remoteConfig: RemoteConfig, val branchesList: List) \ No newline at end of file diff --git a/src/main/kotlin/app/ui/Branches.kt b/src/main/kotlin/app/ui/Branches.kt index 7d80339..7c8c7e1 100644 --- a/src/main/kotlin/app/ui/Branches.kt +++ b/src/main/kotlin/app/ui/Branches.kt @@ -33,7 +33,7 @@ fun Branches(gitManager: GitManager) { val currentBranch by gitManager.currentBranch.collectAsState() Column { - SideMenuEntry("Branches") + SideMenuEntry("Local branches") val branchesHeight = branches.count() * 40 val maxHeight = if(branchesHeight < 300) diff --git a/src/main/kotlin/app/ui/Remotes.kt b/src/main/kotlin/app/ui/Remotes.kt new file mode 100644 index 0000000..ca8aa57 --- /dev/null +++ b/src/main/kotlin/app/ui/Remotes.kt @@ -0,0 +1,62 @@ +package app.ui + +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.items +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import app.ui.components.ScrollableLazyColumn +import app.extensions.simpleVisibleName +import app.git.GitManager +import app.git.RemoteInfo +import app.ui.components.SideMenuEntry +import app.ui.components.SideMenuSubentry + +@Composable +fun Remotes(gitManager: GitManager) { + val remotes by gitManager.remotes.collectAsState() + + Column { + SideMenuEntry("Remotes") + + val allBranches = remotes.map { it.branchesList }.flatten() + val remotesHeight = (allBranches.count() + remotes.count()) * 40 + val maxHeight = if(remotesHeight < 300) + remotesHeight + else + 300 + + Box(modifier = Modifier.heightIn(max = maxHeight.dp)) { + ScrollableLazyColumn(modifier = Modifier.fillMaxWidth()) { + items(remotes) { remote -> + RemoteRow( + remote = remote, + ) + } + } + } + } +} + +@Composable +private fun RemoteRow( + remote: RemoteInfo, +) { + SideMenuSubentry( + text = remote.remoteConfig.name, + iconResourcePath = "cloud.svg", + ) + + val branches = remote.branchesList + Column { + branches.forEach { branch -> + SideMenuSubentry( + text = branch.simpleVisibleName, + extraPadding = 8.dp, + iconResourcePath = "branch.svg", + ) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/ui/RepositoryOpen.kt b/src/main/kotlin/app/ui/RepositoryOpen.kt index 1739c53..21b2a06 100644 --- a/src/main/kotlin/app/ui/RepositoryOpen.kt +++ b/src/main/kotlin/app/ui/RepositoryOpen.kt @@ -72,6 +72,7 @@ fun RepositoryOpenPage(gitManager: GitManager) { .fillMaxHeight() ) { Branches(gitManager = gitManager) + Remotes(gitManager = gitManager) Tags(gitManager = gitManager) Stashes( gitManager = gitManager, diff --git a/src/main/kotlin/app/ui/components/SideMenuSubentry.kt b/src/main/kotlin/app/ui/components/SideMenuSubentry.kt index ee1a84f..ebdc8e3 100644 --- a/src/main/kotlin/app/ui/components/SideMenuSubentry.kt +++ b/src/main/kotlin/app/ui/components/SideMenuSubentry.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import app.theme.primaryTextColor @@ -23,6 +24,7 @@ fun SideMenuSubentry( text: String, iconResourcePath: String, bold: Boolean = false, + extraPadding: Dp = 0.dp, onClick: () -> Unit = {}, additionalInfo: @Composable () -> Unit = {} ) { @@ -30,7 +32,8 @@ fun SideMenuSubentry( modifier = Modifier .height(40.dp) .fillMaxWidth() - .clickable(onClick = onClick), + .clickable(onClick = onClick) + .padding(start = extraPadding), verticalAlignment = Alignment.CenterVertically, ) { Icon( diff --git a/src/main/resources/cloud.svg b/src/main/resources/cloud.svg new file mode 100644 index 0000000..8bd8e45 --- /dev/null +++ b/src/main/resources/cloud.svg @@ -0,0 +1 @@ + \ No newline at end of file