Re-enabled submodules view

This commit is contained in:
Abdelilah El Aissaoui 2023-03-08 00:36:04 +01:00
parent ce78df705e
commit 0140da03d4
No known key found for this signature in database
GPG Key ID: 7587FC860F594869
5 changed files with 109 additions and 87 deletions

View File

@ -1,9 +1,6 @@
package com.jetpackduba.gitnuro.di.factories package com.jetpackduba.gitnuro.di.factories
import com.jetpackduba.gitnuro.viewmodels.sidepanel.BranchesViewModel import com.jetpackduba.gitnuro.viewmodels.sidepanel.*
import com.jetpackduba.gitnuro.viewmodels.sidepanel.RemotesViewModel
import com.jetpackduba.gitnuro.viewmodels.sidepanel.StashesViewModel
import com.jetpackduba.gitnuro.viewmodels.sidepanel.TagsViewModel
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@ -26,3 +23,8 @@ interface TagsViewModelFactory {
interface StashesViewModelFactory { interface StashesViewModelFactory {
fun create(filter: StateFlow<String>): StashesViewModel fun create(filter: StateFlow<String>): StashesViewModel
} }
@AssistedFactory
interface SubmodulesViewModelFactory {
fun create(filter: StateFlow<String>): SubmodulesViewModel
}

View File

@ -21,6 +21,7 @@ import com.jetpackduba.gitnuro.ui.dialogs.EditRemotesDialog
import com.jetpackduba.gitnuro.viewmodels.sidepanel.* import com.jetpackduba.gitnuro.viewmodels.sidepanel.*
import org.eclipse.jgit.lib.Ref import org.eclipse.jgit.lib.Ref
import org.eclipse.jgit.revwalk.RevCommit import org.eclipse.jgit.revwalk.RevCommit
import org.eclipse.jgit.submodule.SubmoduleStatus
@Composable @Composable
fun SidePanel( fun SidePanel(
@ -29,6 +30,7 @@ fun SidePanel(
remotesViewModel: RemotesViewModel = sidePanelViewModel.remotesViewModel, remotesViewModel: RemotesViewModel = sidePanelViewModel.remotesViewModel,
tagsViewModel: TagsViewModel = sidePanelViewModel.tagsViewModel, tagsViewModel: TagsViewModel = sidePanelViewModel.tagsViewModel,
stashesViewModel: StashesViewModel = sidePanelViewModel.stashesViewModel, stashesViewModel: StashesViewModel = sidePanelViewModel.stashesViewModel,
submodulesViewModel: SubmodulesViewModel = sidePanelViewModel.submodulesViewModel,
) { ) {
var filter by remember(sidePanelViewModel) { mutableStateOf(sidePanelViewModel.filter.value) } var filter by remember(sidePanelViewModel) { mutableStateOf(sidePanelViewModel.filter.value) }
@ -36,6 +38,7 @@ fun SidePanel(
val remotesState by remotesViewModel.remoteState.collectAsState() val remotesState by remotesViewModel.remoteState.collectAsState()
val tagsState by tagsViewModel.tagsState.collectAsState() val tagsState by tagsViewModel.tagsState.collectAsState()
val stashesState by stashesViewModel.stashesState.collectAsState() val stashesState by stashesViewModel.stashesState.collectAsState()
val submodulesState by submodulesViewModel.submodules.collectAsState()
var showEditRemotesDialog by remember { mutableStateOf(false) } var showEditRemotesDialog by remember { mutableStateOf(false) }
@ -74,6 +77,11 @@ fun SidePanel(
stashesState = stashesState, stashesState = stashesState,
stashesViewModel = stashesViewModel, stashesViewModel = stashesViewModel,
) )
submodules(
submodulesState = submodulesState,
submodulesViewModel = submodulesViewModel
)
} }
} }
@ -285,6 +293,38 @@ fun LazyListScope.stashes(
} }
} }
fun LazyListScope.submodules(
submodulesState: SubmodulesState,
submodulesViewModel: SubmodulesViewModel,
) {
val isExpanded = submodulesState.isExpanded
val submodules = submodulesState.submodules
item {
ContextMenu(
items = { emptyList() }
) {
SideMenuHeader(
text = "Submodules",
icon = painterResource("topic.svg"),
itemsCount = submodules.count(),
hoverIcon = null,
isExpanded = isExpanded,
onExpand = { submodulesViewModel.onExpand() }
)
}
}
if (isExpanded) {
items(submodules, key = { it.first }) { submodule ->
Submodule(
submodule,
onInitializeModule = { submodulesViewModel.initializeSubmodule(submodule.first) }
)
}
}
}
@Composable @Composable
private fun Branch( private fun Branch(
branch: Ref, branch: Ref,
@ -417,3 +457,33 @@ private fun Stash(
) )
} }
} }
@Composable
private fun Submodule(
submodulePair: Pair<String, SubmoduleStatus>,
onInitializeModule: () -> Unit,
) {
ContextMenu(
items = {
submoduleContextMenuItems(
submodulePair.second,
onInitializeModule = onInitializeModule
)
}
) {
SideMenuSubentry(
text = submodulePair.first,
iconResourcePath = "topic.svg",
) {
val stateName = submodulePair.second.type.toString()
Tooltip(stateName) {
Text(
text = stateName.first().toString(),
color = MaterialTheme.colors.onBackgroundSecondary,
style = MaterialTheme.typography.body2,
modifier = Modifier.padding(horizontal = 16.dp),
)
}
}
}
}

View File

@ -1,72 +0,0 @@
package com.jetpackduba.gitnuro.ui
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 com.jetpackduba.gitnuro.theme.onBackgroundSecondary
import com.jetpackduba.gitnuro.ui.components.SideMenuPanel
import com.jetpackduba.gitnuro.ui.components.SideMenuSubentry
import com.jetpackduba.gitnuro.ui.components.Tooltip
import com.jetpackduba.gitnuro.ui.components.gitnuroViewModel
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenu
import com.jetpackduba.gitnuro.ui.context_menu.submoduleContextMenuItems
import com.jetpackduba.gitnuro.viewmodels.sidepanel.SubmodulesViewModel
import org.eclipse.jgit.submodule.SubmoduleStatus
@Composable
fun Submodules(
submodulesViewModel: SubmodulesViewModel = gitnuroViewModel(),
) {
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,
onInitializeModule = { submodulesViewModel.initializeSubmodule(submodule.first) }
)
}
)
}
@Composable
private fun SubmoduleLineEntry(
submodulePair: Pair<String, SubmoduleStatus>,
onInitializeModule: () -> Unit,
) {
ContextMenu(
items = {
submoduleContextMenuItems(
submodulePair.second,
onInitializeModule = onInitializeModule
)
}
) {
SideMenuSubentry(
text = submodulePair.first,
iconResourcePath = "topic.svg",
) {
val stateName = submodulePair.second.type.toString()
Tooltip(stateName) {
Text(
text = stateName.first().toString(),
color = MaterialTheme.colors.onBackgroundSecondary,
style = MaterialTheme.typography.body2,
modifier = Modifier.padding(horizontal = 16.dp),
)
}
}
}
}

View File

@ -1,9 +1,6 @@
package com.jetpackduba.gitnuro.viewmodels.sidepanel package com.jetpackduba.gitnuro.viewmodels.sidepanel
import com.jetpackduba.gitnuro.di.factories.BranchesViewModelFactory import com.jetpackduba.gitnuro.di.factories.*
import com.jetpackduba.gitnuro.di.factories.RemotesViewModelFactory
import com.jetpackduba.gitnuro.di.factories.StashesViewModelFactory
import com.jetpackduba.gitnuro.di.factories.TagsViewModelFactory
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject import javax.inject.Inject
@ -13,6 +10,7 @@ class SidePanelViewModel @Inject constructor(
remotesViewModelFactory: RemotesViewModelFactory, remotesViewModelFactory: RemotesViewModelFactory,
tagsViewModelFactory: TagsViewModelFactory, tagsViewModelFactory: TagsViewModelFactory,
stashesViewModelFactory: StashesViewModelFactory, stashesViewModelFactory: StashesViewModelFactory,
submodulesViewModelFactory: SubmodulesViewModelFactory,
) { ) {
private val _filter = MutableStateFlow("") private val _filter = MutableStateFlow("")
val filter: StateFlow<String> = _filter val filter: StateFlow<String> = _filter
@ -21,6 +19,7 @@ class SidePanelViewModel @Inject constructor(
val remotesViewModel: RemotesViewModel = remotesViewModelFactory.create(filter) val remotesViewModel: RemotesViewModel = remotesViewModelFactory.create(filter)
val tagsViewModel: TagsViewModel = tagsViewModelFactory.create(filter) val tagsViewModel: TagsViewModel = tagsViewModelFactory.create(filter)
val stashesViewModel: StashesViewModel = stashesViewModelFactory.create(filter) val stashesViewModel: StashesViewModel = stashesViewModelFactory.create(filter)
val submodulesViewModel: SubmodulesViewModel = submodulesViewModelFactory.create(filter)
fun newFilter(newValue: String) { fun newFilter(newValue: String) {
_filter.value = newValue _filter.value = newValue

View File

@ -1,28 +1,49 @@
package com.jetpackduba.gitnuro.viewmodels.sidepanel package com.jetpackduba.gitnuro.viewmodels.sidepanel
import com.jetpackduba.gitnuro.extensions.lowercaseContains
import com.jetpackduba.gitnuro.git.RefreshType import com.jetpackduba.gitnuro.git.RefreshType
import com.jetpackduba.gitnuro.git.TabState import com.jetpackduba.gitnuro.git.TabState
import com.jetpackduba.gitnuro.git.submodules.GetSubmodulesUseCase import com.jetpackduba.gitnuro.git.submodules.GetSubmodulesUseCase
import com.jetpackduba.gitnuro.git.submodules.InitializeSubmoduleUseCase import com.jetpackduba.gitnuro.git.submodules.InitializeSubmoduleUseCase
import com.jetpackduba.gitnuro.git.submodules.UpdateSubmoduleUseCase import com.jetpackduba.gitnuro.git.submodules.UpdateSubmoduleUseCase
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
import org.eclipse.jgit.submodule.SubmoduleStatus import org.eclipse.jgit.submodule.SubmoduleStatus
import javax.inject.Inject
class SubmodulesViewModel @Inject constructor( class SubmodulesViewModel @AssistedInject constructor(
private val tabState: TabState, private val tabState: TabState,
private val getSubmodulesUseCase: GetSubmodulesUseCase, private val getSubmodulesUseCase: GetSubmodulesUseCase,
private val initializeSubmoduleUseCase: InitializeSubmoduleUseCase, private val initializeSubmoduleUseCase: InitializeSubmoduleUseCase,
private val updateSubmoduleUseCase: UpdateSubmoduleUseCase, private val updateSubmoduleUseCase: UpdateSubmoduleUseCase,
private val tabScope: CoroutineScope, private val tabScope: CoroutineScope,
@Assisted
private val filter: StateFlow<String>,
) : SidePanelChildViewModel(true) { ) : SidePanelChildViewModel(true) {
private val _submodules = MutableStateFlow<List<Pair<String, SubmoduleStatus>>>(listOf()) private val _submodules = MutableStateFlow<List<Pair<String, SubmoduleStatus>>>(listOf())
val submodules: StateFlow<List<Pair<String, SubmoduleStatus>>> val submodules: StateFlow<SubmodulesState> = _submodules.combine(isExpanded) { submodules, isExpanded ->
get() = _submodules SubmodulesState(submodules, isExpanded)
}.stateIn(
scope = tabScope,
started = SharingStarted.Eagerly,
initialValue = SubmodulesState(emptyList(), isExpanded.value)
)
val submodulesState: StateFlow<SubmodulesState> =
combine(_submodules, isExpanded, filter) { submodules, isExpanded, filter ->
SubmodulesState(
submodules = submodules.filter { it.first.lowercaseContains(filter) },
isExpanded
)
}.stateIn(
tabScope,
SharingStarted.Eagerly,
SubmodulesState(emptyList(), isExpanded.value)
)
init { init {
tabScope.launch { tabScope.launch {
@ -49,3 +70,5 @@ class SubmodulesViewModel @Inject constructor(
loadSubmodules(git) loadSubmodules(git)
} }
} }
data class SubmodulesState(val submodules: List<Pair<String, SubmoduleStatus>>, val isExpanded: Boolean)