Clicking on a remote now colpases it

Removed animations from expandable to improve performance in big lists
This commit is contained in:
Abdelilah El Aissaoui 2022-02-05 01:28:48 +01:00
parent 9350d80f74
commit cc787064b6
4 changed files with 55 additions and 20 deletions

View File

@ -10,11 +10,11 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import app.extensions.simpleVisibleName import app.extensions.simpleVisibleName
import app.git.RemoteInfo
import app.ui.components.SideMenuPanel import app.ui.components.SideMenuPanel
import app.ui.components.SideMenuSubentry import app.ui.components.SideMenuSubentry
import app.ui.components.VerticalExpandable import app.ui.components.VerticalExpandable
import app.ui.context_menu.remoteBranchesContextMenu import app.ui.context_menu.remoteBranchesContextMenu
import app.viewmodels.RemoteView
import app.viewmodels.RemotesViewModel import app.viewmodels.RemotesViewModel
import org.eclipse.jgit.lib.Ref import org.eclipse.jgit.lib.Ref
@ -26,7 +26,12 @@ fun Remotes(
val remotes by remotesViewModel.remotes.collectAsState() val remotes by remotesViewModel.remotes.collectAsState()
val itemsCount = remember(remotes) { val itemsCount = remember(remotes) {
val allBranches = remotes.map { it.branchesList }.flatten() val allBranches = remotes.filter { remoteView ->
remoteView.isExpanded // Only include in the branches count the nodes expanded
}.map { remoteView ->
remoteView.remoteInfo.branchesList
}.flatten()
allBranches.count() + remotes.count() allBranches.count() + remotes.count()
} }
@ -39,7 +44,8 @@ fun Remotes(
RemoteRow( RemoteRow(
remote = remoteInfo, remote = remoteInfo,
onBranchClicked = { branch -> onBranchClicked(branch) }, onBranchClicked = { branch -> onBranchClicked(branch) },
onDeleteBranch = { branch -> remotesViewModel.deleteBranch(branch) } onDeleteBranch = { branch -> remotesViewModel.deleteBranch(branch) },
onRemoteClicked = { remotesViewModel.onRemoteClicked(remoteInfo) }
) )
} }
) )
@ -48,19 +54,22 @@ fun Remotes(
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
private fun RemoteRow( private fun RemoteRow(
remote: RemoteInfo, remote: RemoteView,
onRemoteClicked: () -> Unit,
onBranchClicked: (Ref) -> Unit, onBranchClicked: (Ref) -> Unit,
onDeleteBranch: (Ref) -> Unit, onDeleteBranch: (Ref) -> Unit,
) { ) {
VerticalExpandable( VerticalExpandable(
isExpanded = remote.isExpanded,
onExpand = onRemoteClicked,
header = { header = {
SideMenuSubentry( SideMenuSubentry(
text = remote.remoteConfig.name, text = remote.remoteInfo.remoteConfig.name,
iconResourcePath = "cloud.svg", iconResourcePath = "cloud.svg",
) )
} }
) { ) {
val branches = remote.branchesList val branches = remote.remoteInfo.branchesList
Column { Column {
branches.forEach { branch -> branches.forEach { branch ->
ContextMenuArea( ContextMenuArea(

View File

@ -11,25 +11,37 @@ import androidx.compose.ui.Modifier
@OptIn(ExperimentalAnimationApi::class) @OptIn(ExperimentalAnimationApi::class)
@Composable @Composable
fun VerticalExpandable( fun VerticalExpandable(
isExpanded: MutableState<Boolean> = remember { mutableStateOf(true) },
header: @Composable () -> Unit,
child: @Composable () -> Unit,
) {
VerticalExpandable(
isExpanded = isExpanded.value,
onExpand = { isExpanded.value = !isExpanded.value },
header = header,
child = child,
)
}
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun VerticalExpandable(
isExpanded: Boolean,
onExpand: () -> Unit,
header: @Composable () -> Unit, header: @Composable () -> Unit,
child: @Composable () -> Unit, child: @Composable () -> Unit,
) { ) {
var isExpanded by remember {
mutableStateOf(true)
}
Column { Column {
Box( Box(
modifier = Modifier.clickable { modifier = Modifier.clickable {
isExpanded = !isExpanded onExpand()
} }
) { ) {
header() header()
} }
AnimatedVisibility(visible = isExpanded) { if(isExpanded) {
child() child()
} }
} }
} }

View File

@ -15,8 +15,8 @@ class RemotesViewModel @Inject constructor(
private val branchesManager: BranchesManager, private val branchesManager: BranchesManager,
private val tabState: TabState, private val tabState: TabState,
) { ) {
private val _remotes = MutableStateFlow<List<RemoteInfo>>(listOf()) private val _remotes = MutableStateFlow<List<RemoteView>>(listOf())
val remotes: StateFlow<List<RemoteInfo>> val remotes: StateFlow<List<RemoteView>>
get() = _remotes get() = _remotes
suspend fun loadRemotes(git: Git) = withContext(Dispatchers.IO) { suspend fun loadRemotes(git: Git) = withContext(Dispatchers.IO) {
@ -32,7 +32,11 @@ class RemotesViewModel @Inject constructor(
RemoteInfo(remoteConfig, remoteBranches) RemoteInfo(remoteConfig, remoteBranches)
} }
_remotes.value = remoteInfoList val remoteViewList = remoteInfoList.map { remoteInfo ->
RemoteView(remoteInfo, true)
}
_remotes.value = remoteViewList
} }
fun deleteBranch(ref: Ref) = tabState.safeProcessing { git -> fun deleteBranch(ref: Ref) = tabState.safeProcessing { git ->
@ -44,5 +48,16 @@ class RemotesViewModel @Inject constructor(
suspend fun refresh(git: Git) = withContext(Dispatchers.IO) { suspend fun refresh(git: Git) = withContext(Dispatchers.IO) {
loadRemotes(git) loadRemotes(git)
} }
fun onRemoteClicked(remoteInfo: RemoteView) {
val remotes = _remotes.value
val newRemoteInfo = remoteInfo.copy(isExpanded = !remoteInfo.isExpanded)
val newRemotesList = remotes.toMutableList()
val indexToReplace = newRemotesList.indexOf(remoteInfo)
newRemotesList[indexToReplace] = newRemoteInfo
_remotes.value = newRemotesList
}
} }
data class RemoteView(val remoteInfo: RemoteInfo, val isExpanded: Boolean)

View File

@ -217,12 +217,11 @@ class TabViewModel @Inject constructor(
fun newSelectedRef(objectId: ObjectId?) = tabState.runOperation { git -> fun newSelectedRef(objectId: ObjectId?) = tabState.runOperation { git ->
if (objectId == null) { if (objectId == null) {
newSelectedItem(SelectedItem.None) newSelectedItem(SelectedItem.None)
return@runOperation RefreshType.NONE } else {
val commit = findCommit(git, objectId)
newSelectedItem(SelectedItem.Ref(commit))
} }
val commit = findCommit(git, objectId)
newSelectedItem(SelectedItem.Ref(commit))
return@runOperation RefreshType.NONE return@runOperation RefreshType.NONE
} }