diff --git a/src/main/kotlin/app/git/TabState.kt b/src/main/kotlin/app/git/TabState.kt index 44f8de6..77cf3b9 100644 --- a/src/main/kotlin/app/git/TabState.kt +++ b/src/main/kotlin/app/git/TabState.kt @@ -217,6 +217,7 @@ enum class RefreshType { REPO_STATE, ONLY_LOG, STASHES, + SUBMODULES, UNCOMMITED_CHANGES, UNCOMMITED_CHANGES_AND_LOG, REMOTES, diff --git a/src/main/kotlin/app/git/submodules/GetSubmodulesUseCase.kt b/src/main/kotlin/app/git/submodules/GetSubmodulesUseCase.kt new file mode 100644 index 0000000..627f822 --- /dev/null +++ b/src/main/kotlin/app/git/submodules/GetSubmodulesUseCase.kt @@ -0,0 +1,15 @@ +package app.git.submodules + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.eclipse.jgit.api.Git +import org.eclipse.jgit.submodule.SubmoduleStatus +import javax.inject.Inject + +class GetSubmodulesUseCase @Inject constructor() { + suspend operator fun invoke(git: Git): Map = withContext(Dispatchers.IO) { + return@withContext git + .submoduleStatus() + .call() + } +} \ 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 e0d74ba..55e9273 100644 --- a/src/main/kotlin/app/ui/RepositoryOpen.kt +++ b/src/main/kotlin/app/ui/RepositoryOpen.kt @@ -209,6 +209,9 @@ fun MainContentView( Stashes( stashesViewModel = tabViewModel.stashesViewModel, ) + Submodules( + submodulesViewModel = tabViewModel.submodulesViewModel, + ) } } diff --git a/src/main/kotlin/app/ui/Submodules.kt b/src/main/kotlin/app/ui/Submodules.kt new file mode 100644 index 0000000..97463eb --- /dev/null +++ b/src/main/kotlin/app/ui/Submodules.kt @@ -0,0 +1,62 @@ +package app.ui + +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.layout.padding +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import app.theme.secondaryTextColor +import app.ui.components.SideMenuPanel +import app.ui.components.SideMenuSubentry +import app.ui.components.Tooltip +import app.viewmodels.SubmodulesViewModel +import org.eclipse.jgit.submodule.SubmoduleStatus + +@OptIn(ExperimentalFoundationApi::class) +@Composable +fun Submodules( + submodulesViewModel: SubmodulesViewModel, +) { + val submodules by submodulesViewModel.submodules.collectAsState() + val isExpanded by submodulesViewModel.isExpanded.collectAsState() + + SideMenuPanel( + title = "Submodules", + icon = painterResource("topic.svg"), + items = submodules, + isExpanded = isExpanded, + onExpand = { submodulesViewModel.onExpand() }, + itemContent = { submodule -> + SubmoduleLineEntry( + submodulePair = submodule, + ) + } + ) +} + +@OptIn(ExperimentalFoundationApi::class) +@Composable +private fun SubmoduleLineEntry( + submodulePair: Pair, +) { + submodulePair.second.type + SideMenuSubentry( + text = submodulePair.first, + iconResourcePath = "topic.svg", + ) { + val stateName = submodulePair.second.type.toString() + Tooltip(stateName) { + Text( + text = stateName.first().toString(), + color = MaterialTheme.colors.secondaryTextColor, + style = MaterialTheme.typography.body2, + modifier = Modifier.padding(horizontal = 16.dp), + ) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/viewmodels/SubmodulesViewModel.kt b/src/main/kotlin/app/viewmodels/SubmodulesViewModel.kt new file mode 100644 index 0000000..4d5595b --- /dev/null +++ b/src/main/kotlin/app/viewmodels/SubmodulesViewModel.kt @@ -0,0 +1,25 @@ +package app.viewmodels + +import app.git.submodules.GetSubmodulesUseCase +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import org.eclipse.jgit.api.Git +import org.eclipse.jgit.lib.Ref +import org.eclipse.jgit.submodule.SubmoduleStatus +import javax.inject.Inject + +class SubmodulesViewModel @Inject constructor( + private val getSubmodulesUseCase: GetSubmodulesUseCase +): ExpandableViewModel() { + private val _submodules = MutableStateFlow>>(listOf()) + val submodules: StateFlow>> + get() = _submodules + + private suspend fun loadSubmodules(git: Git) { + _submodules.value = getSubmodulesUseCase(git).toList() + } + + suspend fun refresh(git: Git) { + loadSubmodules(git) + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/viewmodels/TabViewModel.kt b/src/main/kotlin/app/viewmodels/TabViewModel.kt index cfd02ff..21783fb 100644 --- a/src/main/kotlin/app/viewmodels/TabViewModel.kt +++ b/src/main/kotlin/app/viewmodels/TabViewModel.kt @@ -44,6 +44,7 @@ class TabViewModel @Inject constructor( val statusViewModel: StatusViewModel, val menuViewModel: MenuViewModel, val stashesViewModel: StashesViewModel, + val submodulesViewModel: SubmodulesViewModel, val commitChangesViewModel: CommitChangesViewModel, val cloneViewModel: CloneViewModel, private val getRepositoryStateUseCase: GetRepositoryStateUseCase, @@ -118,6 +119,7 @@ class TabViewModel @Inject constructor( RefreshType.REPO_STATE -> refreshRepositoryState() RefreshType.ONLY_LOG -> refreshLog() RefreshType.STASHES -> refreshStashes() + RefreshType.SUBMODULES -> refreshSubmodules() RefreshType.UNCOMMITED_CHANGES -> checkUncommitedChanges() RefreshType.UNCOMMITED_CHANGES_AND_LOG -> checkUncommitedChanges(true) RefreshType.REMOTES -> refreshRemotes() @@ -157,6 +159,12 @@ class TabViewModel @Inject constructor( stashesViewModel.refresh(git) } + private fun refreshSubmodules() = tabState.runOperation( + refreshType = RefreshType.NONE + ) { git -> + submodulesViewModel.refresh(git) + } + private fun refreshLog() = tabState.runOperation( refreshType = RefreshType.NONE, ) { git -> @@ -328,6 +336,7 @@ class TabViewModel @Inject constructor( tagsViewModel.refresh(git) statusViewModel.refresh(git) stashesViewModel.refresh(git) + submodulesViewModel.refresh(git) } fun credentialsDenied() { diff --git a/src/main/resources/topic.svg b/src/main/resources/topic.svg new file mode 100644 index 0000000..160eae0 --- /dev/null +++ b/src/main/resources/topic.svg @@ -0,0 +1 @@ + \ No newline at end of file