diff --git a/src/main/composeResources/values/strings.xml b/src/main/composeResources/values/strings.xml index 74ef661c..5ffc0e1a 100644 --- a/src/main/composeResources/values/strings.xml +++ b/src/main/composeResources/values/strings.xml @@ -4,6 +4,7 @@ OK Cancel + Save as default Open a repository @@ -148,4 +149,8 @@ Checkout tag's commit Delete tag + + + Default clone directory + Directory that will be used as default when cloning a repository \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt b/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt index c4b95245..3820ae2d 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt @@ -53,6 +53,7 @@ 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_DEFAULT_CLONE_DIR = "gitDefaultCloneDir" private const val PREF_GIT_FF_MERGE = "gitFFMerge" private const val PREF_GIT_MERGE_AUTOSTASH = "mergeAutoStash" private const val PREF_GIT_PULL_REBASE = "gitPullRebase" @@ -90,6 +91,9 @@ class AppSettingsRepository @Inject constructor() { private val _verifySslFlow = MutableStateFlow(cacheCredentialsInMemory) val verifySslFlow = _verifySslFlow.asStateFlow() + private val _defaultCloneDirFlow = MutableStateFlow(defaultCloneDir) + val defaultCloneDirFlow = _defaultCloneDirFlow.asStateFlow() + private val _ffMergeFlow = MutableStateFlow(ffMerge) val ffMergeFlow = _ffMergeFlow.asStateFlow() @@ -246,6 +250,17 @@ class AppSettingsRepository @Inject constructor() { _scaleUiFlow.value = value } + /* + * Property that holds the default directory to clone a repository into. + */ + var defaultCloneDir: String + get() = preferences.get(PREF_GIT_DEFAULT_CLONE_DIR, "") + set(value) { + preferences.put(PREF_GIT_DEFAULT_CLONE_DIR, value) + + _defaultCloneDirFlow.value = value + } + /** * Property that decides if the merge should fast-forward when possible */ diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/CloneDialog.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/CloneDialog.kt index 42ab3d5c..576b7ecf 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/CloneDialog.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/CloneDialog.kt @@ -21,14 +21,18 @@ import androidx.compose.ui.unit.dp import com.jetpackduba.gitnuro.extensions.handMouseClickable import com.jetpackduba.gitnuro.extensions.handOnHover import com.jetpackduba.gitnuro.generated.resources.Res +import com.jetpackduba.gitnuro.generated.resources.generic_save_as_default +import com.jetpackduba.gitnuro.generated.resources.menu_open import com.jetpackduba.gitnuro.generated.resources.search import com.jetpackduba.gitnuro.git.CloneState import com.jetpackduba.gitnuro.theme.outlinedTextFieldColors import com.jetpackduba.gitnuro.theme.textButtonColors import com.jetpackduba.gitnuro.ui.components.AdjustableOutlinedTextField +import com.jetpackduba.gitnuro.ui.components.CheckboxText import com.jetpackduba.gitnuro.ui.components.PrimaryButton import com.jetpackduba.gitnuro.viewmodels.CloneViewModel import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource import java.io.File @Composable @@ -97,6 +101,7 @@ private fun CloneDialogView( onCloneSubmodulesChange: (Boolean) -> Unit, ) { val error by cloneViewModel.error.collectAsState() + val saveDirAsDefault by cloneViewModel.saveDirAsDefault.collectAsState() val urlFocusRequester = remember { FocusRequester() } val directoryFocusRequester = remember { FocusRequester() } @@ -181,6 +186,11 @@ private fun CloneDialogView( } } ) + CheckboxText( + value = saveDirAsDefault, + onCheckedChange = { cloneViewModel.onSaveAsDefaultChanged(!saveDirAsDefault) }, + text = stringResource(Res.string.generic_save_as_default) + ) TextInput( modifier = Modifier.padding(top = 16.dp), diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/settings/SettingsDialog.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/settings/SettingsDialog.kt index f7b35162..830ac2b1 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/settings/SettingsDialog.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/settings/SettingsDialog.kt @@ -42,6 +42,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource import java.time.Instant sealed interface SettingsEntry { @@ -61,6 +62,7 @@ val settings = listOf( SettingsEntry.Entry(Res.drawable.layout, "Layout") { Layout(it) }, SettingsEntry.Entry(Res.drawable.schedule, "Date/Time") { DateTime(it) }, SettingsEntry.Section("GIT"), + SettingsEntry.Entry(Res.drawable.folder, "Environment") { Environment(it) }, SettingsEntry.Entry(Res.drawable.branch, "Branches") { Branches(it) }, SettingsEntry.Entry(Res.drawable.cloud, "Remote actions") { RemoteActions(it) }, @@ -383,6 +385,21 @@ fun Logs(settingsViewModel: SettingsViewModel) { } +@Composable +private fun Environment(settingsViewModel: SettingsViewModel) { + var defaultCloneDir by remember { mutableStateOf(settingsViewModel.defaultCloneDir) } + + SettingTextInput( + title = stringResource(Res.string.settings_environment_default_clone_directory_title), + subtitle = stringResource(Res.string.settings_environment_default_clone_directory_description), + value = defaultCloneDir, + onValueChanged = { value -> + defaultCloneDir = value + settingsViewModel.defaultCloneDir = value + }, + ) +} + @Composable private fun Branches(settingsViewModel: SettingsViewModel) { val ffMerge by settingsViewModel.ffMergeFlow.collectAsState() diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/CloneViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/CloneViewModel.kt index 805173d9..a95fb159 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/CloneViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/CloneViewModel.kt @@ -4,6 +4,7 @@ import androidx.compose.ui.text.input.TextFieldValue import com.jetpackduba.gitnuro.git.CloneState import com.jetpackduba.gitnuro.git.TabState import com.jetpackduba.gitnuro.git.remote_operations.CloneRepositoryUseCase +import com.jetpackduba.gitnuro.repositories.AppSettingsRepository import com.jetpackduba.gitnuro.system.OpenFilePickerUseCase import com.jetpackduba.gitnuro.system.PickerType import kotlinx.coroutines.Dispatchers @@ -19,13 +20,17 @@ class CloneViewModel @Inject constructor( private val tabState: TabState, private val cloneRepositoryUseCase: CloneRepositoryUseCase, private val openFilePickerUseCase: OpenFilePickerUseCase, + private val appSettingsRepository: AppSettingsRepository, ) { private val _repositoryUrl = MutableStateFlow(TextFieldValue("")) val repositoryUrl = _repositoryUrl.asStateFlow() - private val _directoryPath = MutableStateFlow(TextFieldValue("")) + private val _directoryPath = MutableStateFlow(TextFieldValue(appSettingsRepository.defaultCloneDir)) val directoryPath = _directoryPath.asStateFlow() + private val _saveDirAsDefault = MutableStateFlow(false) + val saveDirAsDefault = _saveDirAsDefault.asStateFlow() + private val _folder = MutableStateFlow(TextFieldValue("")) val folder = _folder.asStateFlow() @@ -59,6 +64,9 @@ class CloneViewModel @Inject constructor( if (!directory.exists()) { directory.mkdirs() } + if (_saveDirAsDefault.value) { + appSettingsRepository.defaultCloneDir = directoryPath + } val repoDir = File(directory, folder) if (!repoDir.exists()) { @@ -108,6 +116,10 @@ class CloneViewModel @Inject constructor( _directoryPath.value = directory } + fun onSaveAsDefaultChanged(value: Boolean) { + _saveDirAsDefault.value = value + } + fun onRepositoryUrlChanged(repositoryUrl: TextFieldValue) { _repositoryUrl.value = repositoryUrl } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt index d876aa96..cf0da061 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt @@ -35,6 +35,7 @@ class SettingsViewModel @Inject constructor( val themeState = appSettingsRepository.themeState val linesHeightTypeState = appSettingsRepository.linesHeightTypeState + var defaultCloneDirFlow = appSettingsRepository.defaultCloneDirFlow val ffMergeFlow = appSettingsRepository.ffMergeFlow val mergeAutoStashFlow = appSettingsRepository.mergeAutoStashFlow val pullRebaseFlow = appSettingsRepository.pullRebaseFlow @@ -53,6 +54,12 @@ class SettingsViewModel @Inject constructor( appSettingsRepository.scaleUi = value } + var defaultCloneDir: String + get() = appSettingsRepository.defaultCloneDir + set(value) { + appSettingsRepository.defaultCloneDir = value + } + var swapUncommittedChanges: Boolean get() = appSettingsRepository.swapUncommittedChanges set(value) {