diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/AppTab.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/AppTab.kt index 8d13f51..038f014 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/AppTab.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/AppTab.kt @@ -34,6 +34,17 @@ fun AppTab( val repositorySelectionStatusValue = repositorySelectionStatus.value val processingState = tabViewModel.processing.collectAsState().value + LaunchedEffect(tabViewModel) { + // Init the tab content when the tab is selected and also remove the "initialPath" to avoid opening the + // repository everytime the user changes between tabs + val initialPath = tabViewModel.initialPath + tabViewModel.initialPath = null + + if (initialPath != null) { + tabViewModel.openRepository(initialPath) + } + } + Box { Column( modifier = Modifier diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt index b83da48..6ff1537 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt @@ -20,6 +20,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.* import com.jetpackduba.gitnuro.AppConstants +import com.jetpackduba.gitnuro.LocalTabScope import com.jetpackduba.gitnuro.extensions.handMouseClickable import com.jetpackduba.gitnuro.git.DiffEntryType import com.jetpackduba.gitnuro.keybindings.KeybindingOption @@ -137,6 +138,7 @@ fun RepositoryOpenPage( onCancelRebaseInteractive = { tabViewModel.cancelRebaseInteractive() } ) } else { + val currentTabInformation = LocalTabScope.current Column(modifier = Modifier.weight(1f)) { Menu( modifier = Modifier @@ -150,7 +152,7 @@ fun RepositoryOpenPage( val repo = tabViewModel.openDirectoryPicker() if (repo != null) { - tabViewModel.openRepository(repo) + tabViewModel.openAnotherRepository(repo, currentTabInformation) } }, onQuickActions = { showQuickActionsDialog = true }, diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/TabsManager.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/TabsManager.kt index 3ffa825..d9cbc6d 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/TabsManager.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/TabsManager.kt @@ -42,16 +42,23 @@ class TabsManager @Inject constructor( _currentTab.value = _tabsFlow.value.first() } - fun addNewTabFromPath(path: String, selectTab: Boolean) { + fun addNewTabFromPath(path: String, selectTab: Boolean, tabToBeReplaced: TabInformation? = null) { val newTab = newAppTab( tabName = mutableStateOf(""), path = path, ) _tabsFlow.update { - it.toMutableList().apply { - add(newTab) + val newTabsList = it.toMutableList() + + if (tabToBeReplaced != null) { + val index = newTabsList.indexOf(tabToBeReplaced) + newTabsList[index] = newTab + } else { + newTabsList.add(newTab) } + + newTabsList } if (selectTab) { @@ -116,7 +123,7 @@ class TabsManager @Inject constructor( } private fun newAppTab( - tabName: MutableState = mutableStateOf("New tab"), + tabName: MutableState = mutableStateOf(TabInformation.DEFAULT_NAME), path: String? = null, ): TabInformation { return TabInformation( diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/components/RepositoriesTabPanel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/components/RepositoriesTabPanel.kt index 4e61814..8e55204 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/components/RepositoriesTabPanel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/components/RepositoriesTabPanel.kt @@ -242,20 +242,34 @@ class TabInformation( init { tabComponent.inject(this) - tabViewModel.onRepositoryChanged = { path -> - this.path = path + if (initialPath != null) { + tabName.value = Path(initialPath).name + } + + tabViewModel.onRepositoryChanged = { newPath -> + this.path = newPath + + if (newPath == null) { + tabName.value = TabInformation.DEFAULT_NAME + } else { + tabName.value = Path(newPath).name + appStateManager.repositoryTabChanged(newPath) + } - tabName.value = Path(path).name - appStateManager.repositoryTabChanged(path) onTabPathChanged() } - if (initialPath != null) - tabViewModel.openRepository(initialPath) + + // Set the path that should be loaded when the tab is selected for the first time + tabViewModel.initialPath = initialPath } fun dispose() { tabViewModel.dispose() } + + companion object { + const val DEFAULT_NAME = "New tab" + } } fun emptyTabInformation() = TabInformation(mutableStateOf(""), "", {}, null) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt index e9b4151..27aecff 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt @@ -22,6 +22,8 @@ import com.jetpackduba.gitnuro.system.OpenFilePickerUseCase import com.jetpackduba.gitnuro.system.OpenUrlInBrowserUseCase import com.jetpackduba.gitnuro.system.PickerType import com.jetpackduba.gitnuro.ui.SelectedItem +import com.jetpackduba.gitnuro.ui.TabsManager +import com.jetpackduba.gitnuro.ui.components.TabInformation import com.jetpackduba.gitnuro.updates.Update import com.jetpackduba.gitnuro.updates.UpdatesRepository import kotlinx.coroutines.* @@ -66,8 +68,10 @@ class TabViewModel @Inject constructor( private val abortRebaseUseCase: AbortRebaseUseCase, private val openFilePickerUseCase: OpenFilePickerUseCase, private val openUrlInBrowserUseCase: OpenUrlInBrowserUseCase, + private val tabsManager: TabsManager, private val tabScope: CoroutineScope, ) { + var initialPath: String? = null // Stores the path that should be opened when the tab is selected val errorsManager: ErrorsManager = tabState.errorsManager val selectedItem: StateFlow = tabState.selectedItem var diffViewModel: DiffViewModel? = null @@ -163,6 +167,15 @@ class TabViewModel @Inject constructor( rebaseInteractiveViewModel?.startRebaseInteractive(taskEvent.revCommit) } + /** + * To make sure the tab opens the new repository with a clean state, + * instead of opening the repo in the same ViewModel we simply create a new tab with a new TabViewModel + * replacing the current tab + */ + fun openAnotherRepository(directory: String, current: TabInformation) { + tabsManager.addNewTabFromPath(directory, true, current) + } + fun openRepository(directory: String) { openRepository(File(directory)) } @@ -197,6 +210,7 @@ class TabViewModel @Inject constructor( watchRepositoryChanges(git) } catch (ex: Exception) { + onRepositoryChanged(null) ex.printStackTrace() errorsManager.addError(newErrorNow(ex, ex.localizedMessage)) _repositorySelectionStatus.value = RepositorySelectionStatus.None @@ -324,7 +338,7 @@ class TabViewModel @Inject constructor( credentialsStateManager.updateState(CredentialsAccepted.SshCredentialsAccepted(password)) } - var onRepositoryChanged: (path: String) -> Unit = {} + var onRepositoryChanged: (path: String?) -> Unit = {} fun dispose() { tabScope.cancel()