diff --git a/src/main/kotlin/app/App.kt b/src/main/kotlin/app/App.kt index c0ac860..11199b2 100644 --- a/src/main/kotlin/app/App.kt +++ b/src/main/kotlin/app/App.kt @@ -10,7 +10,6 @@ import androidx.compose.material.Icon import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.runtime.* -import androidx.compose.runtime.snapshots.SnapshotStateMap import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier @@ -28,9 +27,11 @@ import app.theme.AppTheme import app.ui.components.RepositoriesTabPanel import app.ui.components.TabInformation import app.ui.dialogs.SettingsDialog +import kotlinx.coroutines.* +import kotlinx.coroutines.flow.MutableStateFlow import javax.inject.Inject -class Main { +class App { private val appComponent = DaggerAppComponent.create() @Inject @@ -39,84 +40,91 @@ class Main { @Inject lateinit var appPreferences: AppPreferences + private val appScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) + init { appComponent.inject(this) println("AppStateManagerReference $appStateManager") - appStateManager.loadRepositoriesTabs() } - fun start() = application { - var isOpen by remember { mutableStateOf(true) } - val theme by appPreferences.themeState.collectAsState() - if (isOpen) { - Window( - title = "Gitnuro", - onCloseRequest = { - isOpen = false - }, - state = rememberWindowState( - placement = WindowPlacement.Maximized, - size = DpSize(1280.dp, 720.dp) - ), - icon = painterResource("logo.svg"), - ) { - var showSettingsDialog by remember { mutableStateOf(false) } - val tabs = mutableStateMapOf() + private val tabsFlow = MutableStateFlow>(emptyList()) - AppTheme(theme = theme) { - Box(modifier = Modifier.background(MaterialTheme.colors.background)) { - AppTabs( - tabs = tabs, - onOpenSettings = { - showSettingsDialog = true - } - ) - } + fun start(){ + appStateManager.loadRepositoriesTabs() + loadTabs() - if (showSettingsDialog) { - SettingsDialog( - appPreferences = appPreferences, - onDismiss = { showSettingsDialog = false } - ) + application { + var isOpen by remember { mutableStateOf(true) } + val theme by appPreferences.themeState.collectAsState() + + if (isOpen) { + Window( + title = "Gitnuro", + onCloseRequest = { + isOpen = false + }, + state = rememberWindowState( + placement = WindowPlacement.Maximized, + size = DpSize(1280.dp, 720.dp) + ), + icon = painterResource("logo.svg"), + ) { + var showSettingsDialog by remember { mutableStateOf(false) } + + AppTheme(theme = theme) { + Box(modifier = Modifier.background(MaterialTheme.colors.background)) { + AppTabs( + onOpenSettings = { + showSettingsDialog = true + } + ) + } + + if (showSettingsDialog) { + SettingsDialog( + appPreferences = appPreferences, + onDismiss = { showSettingsDialog = false } + ) + } } } + } else { + appScope.cancel("Closing app") + this.exitApplication() } } } + private fun loadTabs() { + val repositoriesSavedTabs = appStateManager.openRepositoriesPathsTabs + var repoTabs = repositoriesSavedTabs.map { repositoryTab -> + newAppTab( + key = repositoryTab.key, + path = repositoryTab.value + ) + } + + if (repoTabs.isEmpty()) { + repoTabs = listOf( + newAppTab() + ) + } + + tabsFlow.value = repoTabs + + println("After reading prefs, got ${tabsFlow.value.count()} tabs") + } + @Composable fun AppTabs( - tabs: SnapshotStateMap, onOpenSettings: () -> Unit, ) { - - val tabsInformationList = tabs.map { it.value }.sortedBy { it.key } + val tabs by tabsFlow.collectAsState() + val tabsInformationList = tabs.sortedBy { it.key } println("Tabs count ${tabs.count()}") - LaunchedEffect(Unit) { - val repositoriesSavedTabs = appStateManager.openRepositoriesPathsTabs - var repoTabs = repositoriesSavedTabs.map { repositoryTab -> - newAppTab( - key = repositoryTab.key, - path = repositoryTab.value - ) - } - - if (repoTabs.isEmpty()) { - repoTabs = listOf( - newAppTab() - ) - } - - repoTabs.forEach { - tabs[it.key] = it - } // Store list of tabs in the map - - println("After reading prefs, got ${tabs.count()} tabs") - } - val selectedTabKey = remember { mutableStateOf(0) } println("Selected tab key: ${selectedTabKey.value}") @@ -125,22 +133,36 @@ class Main { modifier = Modifier.background(MaterialTheme.colors.background) ) { Tabs( - tabs = tabs, tabsInformationList = tabsInformationList, selectedTabKey = selectedTabKey, - onOpenSettings = onOpenSettings + onOpenSettings = onOpenSettings, + onAddedTab = { tabInfo -> + addTab(tabs, tabInfo) + }, + onRemoveTab = { key -> + removeTab(tabs, key) + } ) TabsContent(tabsInformationList, selectedTabKey.value) } } + private fun removeTab(tabs: List, key: Int) = appScope.launch(Dispatchers.IO) { + tabsFlow.value = tabs.filter { tab -> tab.key != key } + } + + fun addTab(tabsList: List, tabInformation: TabInformation) = appScope.launch(Dispatchers.IO) { + tabsFlow.value = tabsList.toMutableList().apply { add(tabInformation) } + } + @Composable fun Tabs( - tabs: SnapshotStateMap, selectedTabKey: MutableState, onOpenSettings: () -> Unit, tabsInformationList: List, + onAddedTab: (TabInformation) -> Unit, + onRemoveTab: (Int) -> Unit, ) { Row( modifier = Modifier @@ -162,13 +184,12 @@ class Main { key = key ) - tabs[key] = newAppTab - + onAddedTab(newAppTab) newAppTab }, onTabClosed = { key -> appStateManager.repositoryTabRemoved(key) - tabs.remove(key) + onRemoveTab(key) } ) IconButton( diff --git a/src/main/kotlin/app/AppStateManager.kt b/src/main/kotlin/app/AppStateManager.kt index 0f141c6..1246267 100644 --- a/src/main/kotlin/app/AppStateManager.kt +++ b/src/main/kotlin/app/AppStateManager.kt @@ -57,7 +57,7 @@ class AppStateManager @Inject constructor( appPreferences.latestOpenedRepositoriesPath = Json.encodeToString(_latestOpenedRepositoriesPaths) } - fun loadRepositoriesTabs() = appStateScope.launch(Dispatchers.IO) { + fun loadRepositoriesTabs() { val repositoriesSaved = appPreferences.latestTabsOpened if (repositoriesSaved.isNotEmpty()) { diff --git a/src/main/kotlin/app/di/AppComponent.kt b/src/main/kotlin/app/di/AppComponent.kt index 19b6a2c..78eed0b 100644 --- a/src/main/kotlin/app/di/AppComponent.kt +++ b/src/main/kotlin/app/di/AppComponent.kt @@ -1,13 +1,13 @@ package app.di import app.AppStateManager -import app.Main +import app.App import dagger.Component import javax.inject.Singleton @Singleton @Component interface AppComponent { - fun inject(main: Main) + fun inject(main: App) fun appStateManager(): AppStateManager } \ No newline at end of file diff --git a/src/main/kotlin/app/ui/components/RepositoriesTabPanel.kt b/src/main/kotlin/app/ui/components/RepositoriesTabPanel.kt index b9d5733..ee1de86 100644 --- a/src/main/kotlin/app/ui/components/RepositoriesTabPanel.kt +++ b/src/main/kotlin/app/ui/components/RepositoriesTabPanel.kt @@ -179,6 +179,7 @@ class TabInformation( .build() tabComponent.inject(this) + //TODO: This shouldn't be here, should be in the parent method gitManager.onRepositoryChanged = { path -> if (path == null) { appStateManager.repositoryTabRemoved(key) diff --git a/src/main/kotlin/main.kt b/src/main/kotlin/main.kt index f7537dc..f346ada 100644 --- a/src/main/kotlin/main.kt +++ b/src/main/kotlin/main.kt @@ -1,8 +1,8 @@ import androidx.compose.ui.ExperimentalComposeUiApi -import app.Main +import app.App @OptIn(ExperimentalComposeUiApi::class) fun main() { - val main = Main() + val main = App() main.start() } \ No newline at end of file