Width of triple vertical split pane columns is now persisted

Fixes #176
This commit is contained in:
Abdelilah El Aissaoui 2024-07-20 01:18:39 +02:00
parent b9db9a8d57
commit f5ee173453
No known key found for this signature in database
GPG Key ID: 7587FC860F594869
6 changed files with 129 additions and 17 deletions

View File

@ -13,6 +13,7 @@ import com.jetpackduba.gitnuro.managers.TempFilesManager
import com.jetpackduba.gitnuro.repositories.AppSettingsRepository
import com.jetpackduba.gitnuro.terminal.ITerminalProvider
import com.jetpackduba.gitnuro.ui.TabsManager
import com.jetpackduba.gitnuro.ui.VerticalSplitPaneConfig
import com.jetpackduba.gitnuro.updates.UpdatesRepository
import com.jetpackduba.gitnuro.viewmodels.SettingsViewModel
import dagger.Component
@ -34,6 +35,8 @@ interface AppComponent {
fun appPreferences(): AppSettingsRepository
fun verticalSplitPaneConfig(): VerticalSplitPaneConfig
fun appEnvInfo(): AppEnvInfo
fun tabsManager(): TabsManager

View File

@ -43,6 +43,8 @@ private const val PREF_PROXY_USE_AUTH = "proxyUseAuth"
private const val PREF_PROXY_USER = "proxyHostUser"
private const val PREF_PROXY_PASSWORD = "proxyHostPassword"
private const val PREF_CACHE_CREDENTIALS_IN_MEMORY = "credentialsInMemory"
private const val PREF_FIRST_PANE_WIDTH = "firstPaneWidth"
private const val PREF_THIRD_PANE_WIDTH = "thirdPaneWidth"
private const val PREF_GIT_FF_MERGE = "gitFFMerge"
@ -57,6 +59,8 @@ private const val DEFAULT_SWAP_UNCOMMITTED_CHANGES = false
private const val DEFAULT_SHOW_CHANGES_AS_TREE = false
private const val DEFAULT_CACHE_CREDENTIALS_IN_MEMORY = true
private const val DEFAULT_VERIFY_SSL = true
private const val DEFAULT_FIRST_PANE_WIDTH = 220f
private const val DEFAULT_THIRD_PANE_WIDTH = 330f
const val DEFAULT_UI_SCALE = -1f
@Singleton
@ -209,6 +213,22 @@ class AppSettingsRepository @Inject constructor() {
_cacheCredentialsInMemoryFlow.value = value
}
var firstPaneWidth: Float
get() {
return preferences.getFloat(PREF_FIRST_PANE_WIDTH, DEFAULT_FIRST_PANE_WIDTH)
}
set(value) {
preferences.putFloat(PREF_FIRST_PANE_WIDTH, value)
}
var thirdPaneWidth: Float
get() {
return preferences.getFloat(PREF_THIRD_PANE_WIDTH, DEFAULT_THIRD_PANE_WIDTH)
}
set(value) {
preferences.putFloat(PREF_THIRD_PANE_WIDTH, value)
}
var verifySsl: Boolean
get() {
return preferences.getBoolean(PREF_VERIFY_SSL, DEFAULT_VERIFY_SSL)

View File

@ -30,6 +30,8 @@ import com.jetpackduba.gitnuro.ui.log.Log
import com.jetpackduba.gitnuro.updates.Update
import com.jetpackduba.gitnuro.viewmodels.BlameState
import com.jetpackduba.gitnuro.viewmodels.TabViewModel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.eclipse.jgit.lib.RepositoryState
import org.eclipse.jgit.revwalk.RevCommit
import org.jetbrains.compose.splitpane.ExperimentalSplitPaneApi
@ -264,9 +266,19 @@ fun MainContentView(
) {
val rebaseInteractiveState by tabViewModel.rebaseInteractiveState.collectAsState()
val density = LocalDensity.current.density
val scope = rememberCoroutineScope()
var firstWidth by remember(tabViewModel) { mutableStateOf(tabViewModel.firstPaneWidth) }
var thirdWidth by remember(tabViewModel) { mutableStateOf(tabViewModel.thirdPaneWidth) }
// We create 2 mutableStates here because using directly the flow makes compose lose some drag events for some reason
var firstWidth by remember(tabViewModel) { mutableStateOf(tabViewModel.firstPaneWidth.value) }
var thirdWidth by remember(tabViewModel) { mutableStateOf(tabViewModel.thirdPaneWidth.value) }
LaunchedEffect(Unit) {
// Update the pane widths if they have been changed in a different tab
tabViewModel.onPanelsWidthPersisted.collectLatest {
firstWidth = tabViewModel.firstPaneWidth.value
thirdWidth = tabViewModel.thirdPaneWidth.value
}
}
TripleVerticalSplitPanel(
modifier = Modifier.fillMaxSize(),
@ -391,7 +403,12 @@ fun MainContentView(
if (newWidth > 150 && rebaseInteractiveState !is RebaseInteractiveState.AwaitingInteraction) {
firstWidth = newWidth
tabViewModel.firstPaneWidth = firstWidth
tabViewModel.setFirstPaneWidth(newWidth)
}
},
onFirstSizeDragStopped = {
scope.launch {
tabViewModel.persistFirstPaneWidth()
}
},
onThirdSizeDrag = {
@ -399,7 +416,12 @@ fun MainContentView(
if (newWidth > 150) {
thirdWidth = newWidth
tabViewModel.thirdPaneWidth = thirdWidth
tabViewModel.setThirdPaneWidth(newWidth)
}
},
onThirdSizeDragStopped = {
scope.launch {
tabViewModel.persistThirdPaneWidth()
}
},
)

View File

@ -0,0 +1,51 @@
package com.jetpackduba.gitnuro.ui
import com.jetpackduba.gitnuro.repositories.AppSettingsRepository
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject
import javax.inject.Singleton
interface IVerticalSplitPaneConfig {
val firstPaneWidth: StateFlow<Float>
val onPanelsWidthPersisted: SharedFlow<Unit>
val thirdPaneWidth: StateFlow<Float>
fun setFirstPaneWidth(firstPaneWidth: Float)
fun setThirdPaneWidth(thirdPaneWidth: Float)
suspend fun persistFirstPaneWidth()
suspend fun persistThirdPaneWidth()
}
@Singleton
class VerticalSplitPaneConfig @Inject constructor(
private val appSettingsRepository: AppSettingsRepository,
) : IVerticalSplitPaneConfig {
private val _firstPaneWidth = MutableStateFlow<Float>(appSettingsRepository.firstPaneWidth)
override val firstPaneWidth: StateFlow<Float> = _firstPaneWidth
private val _thirdPaneWidth = MutableStateFlow<Float>(appSettingsRepository.thirdPaneWidth)
override val thirdPaneWidth: StateFlow<Float> = _thirdPaneWidth
private val _onPanelsWidthPersisted = MutableSharedFlow<Unit>()
override val onPanelsWidthPersisted: SharedFlow<Unit> = _onPanelsWidthPersisted
override fun setFirstPaneWidth(firstPaneWidth: Float) {
this._firstPaneWidth.value = firstPaneWidth
}
override fun setThirdPaneWidth(thirdPaneWidth: Float) {
this._thirdPaneWidth.value = thirdPaneWidth
}
override suspend fun persistFirstPaneWidth() {
appSettingsRepository.firstPaneWidth = _firstPaneWidth.value
_onPanelsWidthPersisted.emit(Unit)
}
override suspend fun persistThirdPaneWidth() {
appSettingsRepository.thirdPaneWidth = _thirdPaneWidth.value
_onPanelsWidthPersisted.emit(Unit)
}
}

View File

@ -3,10 +3,7 @@ package com.jetpackduba.gitnuro.ui.components
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.draggable
import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.pointerHoverIcon
@ -22,13 +19,18 @@ fun TripleVerticalSplitPanel(
firstWidth: Float,
thirdWidth: Float,
onFirstSizeDrag: (Float) -> Unit,
onFirstSizeDragStopped: (Float) -> Unit,
onThirdSizeDrag: (Float) -> Unit,
onThirdSizeDragStopped: (Float) -> Unit,
) {
Row(
modifier = modifier
) {
if (firstWidth > 0) {
Box(modifier = Modifier.width(firstWidth.dp)) {
Box(
modifier = Modifier
.width(firstWidth.dp)
) {
first()
}
Box(
@ -39,13 +41,19 @@ fun TripleVerticalSplitPanel(
state = rememberDraggableState {
onFirstSizeDrag(it)
},
orientation = Orientation.Horizontal
orientation = Orientation.Horizontal,
onDragStopped = {
onFirstSizeDragStopped(it)
},
)
.pointerHoverIcon(resizePointerIconEast)
)
}
Box(Modifier.weight(1f, true)) {
Box(
Modifier
.weight(1f, true)
) {
second()
}
@ -54,14 +62,21 @@ fun TripleVerticalSplitPanel(
.fillMaxHeight()
.width(8.dp)
.draggable(
rememberDraggableState {
state = rememberDraggableState {
onThirdSizeDrag(it)
}, Orientation.Horizontal
},
orientation = Orientation.Horizontal,
onDragStopped = {
onThirdSizeDragStopped(it)
},
)
.pointerHoverIcon(resizePointerIconEast)
)
Box(modifier = Modifier.width(thirdWidth.dp)) {
Box(
modifier = Modifier
.width(thirdWidth.dp)
) {
third()
}
}

View File

@ -22,8 +22,10 @@ import com.jetpackduba.gitnuro.models.AuthorInfoSimple
import com.jetpackduba.gitnuro.system.OpenFilePickerUseCase
import com.jetpackduba.gitnuro.system.OpenUrlInBrowserUseCase
import com.jetpackduba.gitnuro.system.PickerType
import com.jetpackduba.gitnuro.ui.IVerticalSplitPaneConfig
import com.jetpackduba.gitnuro.ui.SelectedItem
import com.jetpackduba.gitnuro.ui.TabsManager
import com.jetpackduba.gitnuro.ui.VerticalSplitPaneConfig
import com.jetpackduba.gitnuro.updates.Update
import com.jetpackduba.gitnuro.updates.UpdatesRepository
import kotlinx.coroutines.*
@ -69,10 +71,9 @@ class TabViewModel @Inject constructor(
private val sharedRepositoryStateManager: SharedRepositoryStateManager,
private val tabsManager: TabsManager,
private val tabScope: CoroutineScope,
private val verticalSplitPaneConfig: VerticalSplitPaneConfig,
val tabViewModelsProvider: TabViewModelsProvider,
) {
var firstPaneWidth = 220f
var thirdPaneWidth = 360f
) : IVerticalSplitPaneConfig by verticalSplitPaneConfig {
var initialPath: String? = null // Stores the path that should be opened when the tab is selected
val errorsManager: ErrorsManager = tabState.errorsManager
val selectedItem: StateFlow<SelectedItem> = tabState.selectedItem