Now opened tabs will be saved

This commit is contained in:
Abdelilah El Aissaoui 2021-10-15 02:34:26 +02:00
parent 5f1f015be6
commit fda901c0f2
8 changed files with 142 additions and 47 deletions

View file

@ -6,6 +6,7 @@ plugins {
// __KOTLIN_COMPOSE_VERSION__
kotlin("jvm") version "1.5.21"
kotlin("kapt") version "1.5.21"
kotlin("plugin.serialization") version "1.5.21"
// __LATEST_COMPOSE_RELEASE_VERSION__
id("org.jetbrains.compose") version "1.0.0-alpha3"
}
@ -27,6 +28,7 @@ dependencies {
implementation("org.apache.sshd:sshd-core:2.7.0")
implementation("com.google.dagger:dagger:2.39.1")
implementation("org.jetbrains.kotlin:kotlin-reflect:1.5.21")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.0")
kapt("com.google.dagger:dagger-compiler:2.39.1")
}

View file

@ -29,13 +29,18 @@ class Main {
@Inject
lateinit var gitManagerProvider: Provider<GitManager>
@Inject
lateinit var appStateManager: AppStateManager
init {
appComponent.inject(this)
appStateManager.loadRepositoriesTabs()
}
fun start() = application {
var isOpen by remember { mutableStateOf(true) }
if (isOpen) {
Window(
title = "Gitnuro",
@ -49,15 +54,19 @@ class Main {
) {
AppTheme {
val tabs = remember {
val tabName = mutableStateOf("New tab")
mutableStateOf(
listOf(
TabInformation(tabName, key = 0) {
val gitManager = remember { gitManagerProvider.get() }
Gitnuro(gitManager, false, tabName)
},
val repositoriesSavedTabs = appStateManager.openRepositoriesPathsTabs
var repoTabs = repositoriesSavedTabs.map { repositoryTab ->
newAppTab(key = repositoryTab.key, path = repositoryTab.value)
}
if (repoTabs.isEmpty()) {
repoTabs = listOf(
newAppTab()
)
)
}
mutableStateOf(repoTabs)
}
var selectedTabKey by remember { mutableStateOf(0) }
@ -74,12 +83,14 @@ class Main {
onTabSelected = { newSelectedTabKey ->
selectedTabKey = newSelectedTabKey
},
newTabContent = { tabName ->
val gitManager = remember { gitManagerProvider.get() }
Gitnuro(gitManager, true, tabName)
newTabContent = { key ->
newAppTab(key)
},
onTabsUpdated = { tabInformationList ->
tabs.value = tabInformationList
},
onTabClosed = { key ->
appStateManager.repositoryTabRemoved(key)
}
)
@ -111,13 +122,35 @@ class Main {
}
}
}
private fun newAppTab(
key: Int = 0,
tabName: MutableState<String> = mutableStateOf("New tab"),
path: String? = null,
): TabInformation {
return TabInformation(
title = tabName,
key = key
) {
val gitManager = remember { gitManagerProvider.get() }
gitManager.onRepositoryChanged = { path ->
if (path == null) {
appStateManager.repositoryTabRemoved(key)
} else
appStateManager.repositoryTabChanged(key, path)
}
Gitnuro(gitManager, path, tabName)
}
}
}
@Composable
fun Gitnuro(gitManager: GitManager, isNewTab: Boolean, tabName: MutableState<String>) {
fun Gitnuro(gitManager: GitManager, repositoryPath: String?, tabName: MutableState<String>) {
LaunchedEffect(gitManager) {
if (!isNewTab)
gitManager.loadLatestOpenedRepository()
if (repositoryPath != null)
gitManager.openRepository(repositoryPath)
}

View file

@ -2,14 +2,23 @@ package app
import java.util.prefs.Preferences
import javax.inject.Inject
import javax.inject.Singleton
private const val PREFERENCES_NAME = "GitnuroConfig"
private const val PREF_LATEST_REPOSITORIES_OPENED = "latestRepositoriesOpened"
private const val PREF_LAST_OPENED_REPOSITORY_PATH = "lastOpenedRepositoryPath"
class GPreferences @Inject constructor() {
@Singleton
class AppPreferences @Inject constructor() {
private val preferences: Preferences = Preferences.userRoot().node(PREFERENCES_NAME)
var latestTabsOpened: String
get() = preferences.get(PREF_LATEST_REPOSITORIES_OPENED, "")
set(value) {
preferences.put(PREF_LATEST_REPOSITORIES_OPENED, value)
}
var latestOpenedRepositoryPath: String
get() = preferences.get(PREF_LAST_OPENED_REPOSITORY_PATH, "")
set(value) {

View file

@ -0,0 +1,56 @@
package app
import kotlinx.coroutines.*
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class AppStateManager @Inject constructor(
private val appPreferences: AppPreferences,
) {
private val _openRepositoriesPaths = mutableMapOf<Int, String>()
val openRepositoriesPathsTabs: Map<Int, String>
get() = _openRepositoriesPaths
private val appStateScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) // TODO Stop this when closing the app
var latestOpenedRepositoryPath: String
get() = appPreferences.latestOpenedRepositoryPath
set(value) {
appPreferences.latestOpenedRepositoryPath = value
}
fun repositoryTabChanged(key: Int, path: String) {
_openRepositoriesPaths[key] = path
updateSavedRepositoryTabs()
}
fun repositoryTabRemoved(key: Int) {
_openRepositoriesPaths.remove(key)
updateSavedRepositoryTabs()
}
private fun updateSavedRepositoryTabs() = appStateScope.launch(Dispatchers.IO) {
val tabsList = _openRepositoriesPaths.map { it.value }
appPreferences.latestTabsOpened = Json.encodeToString(tabsList)
}
fun loadRepositoriesTabs() = appStateScope.launch(Dispatchers.IO) {
val repositoriesSaved = appPreferences.latestTabsOpened
if (repositoriesSaved.isNotEmpty()) {
val repositoriesList = Json.decodeFromString<List<String>>(repositoriesSaved)
repositoriesList.forEachIndexed { index, repository ->
_openRepositoriesPaths[index] = repository
}
}
}
}

View file

@ -2,7 +2,9 @@ package app.di
import app.Main
import dagger.Component
import javax.inject.Singleton
@Singleton
@Component
interface AppComponent {
fun inject(main: Main)

View file

@ -11,19 +11,20 @@ import org.eclipse.jgit.lib.Ref
import org.eclipse.jgit.lib.Repository
import org.eclipse.jgit.revwalk.RevCommit
import org.eclipse.jgit.storage.file.FileRepositoryBuilder
import app.GPreferences
import app.AppPreferences
import app.AppStateManager
import java.io.File
import javax.inject.Inject
class GitManager @Inject constructor(
private val preferences: GPreferences,
private val statusManager: StatusManager,
private val logManager: LogManager,
private val remoteOperationsManager: RemoteOperationsManager,
private val branchesManager: BranchesManager,
private val stashManager: StashManager,
private val diffManager: DiffManager,
private val appStateManager: AppStateManager,
) {
val repositoryName: String
get() = safeGit.repository.directory.parentFile.name
@ -59,12 +60,12 @@ class GitManager @Inject constructor(
val stashStatus: StateFlow<StashStatus>
get() = stashManager.stashStatus
val latestDirectoryOpened: File?
get() = File(preferences.latestOpenedRepositoryPath).parentFile
val credentialsState: StateFlow<CredentialsState>
get() = credentialsStateManager.credentialsState
val latestOpenedRepositoryPath: String
get() = appStateManager.latestOpenedRepositoryPath
private var git: Git? = null
val safeGit: Git
@ -77,12 +78,8 @@ class GitManager @Inject constructor(
return git
}
suspend fun loadLatestOpenedRepository() = withContext(Dispatchers.IO) {
val latestOpenedRepositoryPath = preferences.latestOpenedRepositoryPath
if (latestOpenedRepositoryPath.isNotEmpty()) {
openRepository(File(latestOpenedRepositoryPath))
}
fun openRepository(directory: String) {
openRepository(File(directory))
}
fun openRepository(directory: File) {
@ -107,13 +104,16 @@ class GitManager @Inject constructor(
try {
repository.workTree // test if repository is valid
preferences.latestOpenedRepositoryPath = gitDirectory.path
_repositorySelectionStatus.value = RepositorySelectionStatus.Open(repository)
git = Git(repository)
onRepositoryChanged(repository.directory.parent)
appStateManager.latestOpenedRepositoryPath = directory.absolutePath
refreshRepositoryInfo()
} catch (ex: Exception) {
ex.printStackTrace()
onRepositoryChanged(null)
}
}
@ -213,6 +213,8 @@ class GitManager @Inject constructor(
fun stageAll() = managerScope.launch {
statusManager.stageAll(safeGit)
}
var onRepositoryChanged: (path: String?) -> Unit = {}
}

View file

@ -2,16 +2,16 @@ import app.git.GitManager
import javax.swing.JFileChooser
fun openRepositoryDialog(gitManager: GitManager) {
val latestDirectoryOpened = gitManager.latestDirectoryOpened
val latestDirectoryOpened = gitManager.latestOpenedRepositoryPath
val f = if (latestDirectoryOpened == null)
val fileChooser = if (latestDirectoryOpened.isEmpty())
JFileChooser()
else
JFileChooser(latestDirectoryOpened)
f.fileSelectionMode = JFileChooser.DIRECTORIES_ONLY
f.showSaveDialog(null)
fileChooser.fileSelectionMode = JFileChooser.DIRECTORIES_ONLY
fileChooser.showSaveDialog(null)
if (f.selectedFile != null)
gitManager.openRepository(f.selectedFile)
if (fileChooser.selectedFile != null)
gitManager.openRepository(fileChooser.selectedFile)
}

View file

@ -14,8 +14,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import app.theme.primaryLight
import app.theme.primaryTextColor
import app.theme.tabColorActive
import app.theme.tabColorInactive
@ -27,7 +25,8 @@ fun RepositoriesTabPanel(
selectedTabKey: Int,
onTabSelected: (Int) -> Unit,
onTabsUpdated: (List<TabInformation>) -> Unit,
newTabContent: @Composable (tabTitle: MutableState<String>) -> Unit,
onTabClosed: (Int) -> Unit,
newTabContent: (key: Int) -> TabInformation,
) {
var tabsIdentifier by remember {
mutableStateOf(tabs.count())
@ -40,13 +39,7 @@ fun RepositoriesTabPanel(
tabsIdentifier++
val tabName = mutableStateOf("New tab")
tabsCopy.add(
TabInformation(tabName, key = tabsIdentifier) {
newTabContent(tabName)
}
)
tabsCopy.add(newTabContent(tabsIdentifier))
onTabSelected(tabsIdentifier)
onTabsUpdated(tabsCopy)
@ -83,17 +76,15 @@ fun RepositoriesTabPanel(
} else {
tabsIdentifier++
val tabName = mutableStateOf("New tab")
tabsCopy.add(
TabInformation(tabName, key = tabsIdentifier) {
newTabContent(tabName)
}
newTabContent(tabsIdentifier)
)
onTabSelected(tabsIdentifier)
}
}
onTabClosed(tab.key)
onTabsUpdated(tabsCopy)
}
)