diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/App.kt b/src/main/kotlin/com/jetpackduba/gitnuro/App.kt index 188436d..ea4a23f 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/App.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/App.kt @@ -14,8 +14,6 @@ import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.input.key.Key -import androidx.compose.ui.input.key.KeyShortcut import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.Density @@ -37,12 +35,10 @@ import com.jetpackduba.gitnuro.ui.AppTab import com.jetpackduba.gitnuro.ui.components.RepositoriesTabPanel import com.jetpackduba.gitnuro.ui.components.TabInformation import com.jetpackduba.gitnuro.ui.components.emptyTabInformation -import com.jetpackduba.gitnuro.ui.context_menu.Separator import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch import javax.inject.Inject -import androidx.compose.ui.window.MenuBar private const val TAG = "App" @@ -171,7 +167,7 @@ class App { } } - private fun removeTab(key: Int) = appStateManager.appStateScope.launch(Dispatchers.IO) { + private fun removeTab(key: Int) = appStateManager.appScope.launch(Dispatchers.IO) { // Stop any running jobs val tabs = tabsFlow.value val tabToRemove = tabs.firstOrNull { it.key == key } ?: return@launch @@ -184,7 +180,7 @@ class App { tabsFlow.value = tabsFlow.value.filter { tab -> tab.key != key } } - fun addTab(tabInformation: TabInformation) = appStateManager.appStateScope.launch(Dispatchers.IO) { + fun addTab(tabInformation: TabInformation) = appStateManager.appScope.launch(Dispatchers.IO) { tabsFlow.value = tabsFlow.value.toMutableList().apply { add(tabInformation) } } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/AppStateManager.kt b/src/main/kotlin/com/jetpackduba/gitnuro/AppStateManager.kt index 07088fb..7bde386 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/AppStateManager.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/AppStateManager.kt @@ -1,5 +1,6 @@ package com.jetpackduba.gitnuro +import com.jetpackduba.gitnuro.di.qualifiers.AppCoroutineScope import com.jetpackduba.gitnuro.preferences.AppSettings import kotlinx.coroutines.* import kotlinx.coroutines.sync.Mutex @@ -12,6 +13,7 @@ import javax.inject.Singleton @Singleton class AppStateManager @Inject constructor( private val appSettings: AppSettings, + @AppCoroutineScope val appScope: CoroutineScope, ) { private val mutex = Mutex() @@ -23,12 +25,10 @@ class AppStateManager @Inject constructor( val latestOpenedRepositoriesPaths: List get() = _latestOpenedRepositoriesPaths - val appStateScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) - val latestOpenedRepositoryPath: String get() = _latestOpenedRepositoriesPaths.firstOrNull() ?: "" - fun repositoryTabChanged(key: Int, path: String) = appStateScope.launch(Dispatchers.IO) { + fun repositoryTabChanged(key: Int, path: String) = appScope.launch(Dispatchers.IO) { mutex.lock() try { // Do not save already saved repos @@ -51,7 +51,7 @@ class AppStateManager @Inject constructor( } } - fun repositoryTabRemoved(key: Int) = appStateScope.launch(Dispatchers.IO) { + fun repositoryTabRemoved(key: Int) = appScope.launch(Dispatchers.IO) { _openRepositoriesPaths.remove(key) updateSavedRepositoryTabs() @@ -85,6 +85,6 @@ class AppStateManager @Inject constructor( } fun cancelCoroutines() { - appStateScope.cancel("Closing com.jetpackduba.gitnuro.app") + appScope.cancel("Closing com.jetpackduba.gitnuro.app") } } \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/di/AppComponent.kt b/src/main/kotlin/com/jetpackduba/gitnuro/di/AppComponent.kt index 794ac9b..874ecd1 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/di/AppComponent.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/di/AppComponent.kt @@ -3,13 +3,20 @@ package com.jetpackduba.gitnuro.di import com.jetpackduba.gitnuro.App import com.jetpackduba.gitnuro.AppStateManager import com.jetpackduba.gitnuro.credentials.CredentialsStateManager +import com.jetpackduba.gitnuro.di.modules.AppModule +import com.jetpackduba.gitnuro.di.modules.NetworkModule +import com.jetpackduba.gitnuro.di.modules.TabModule import com.jetpackduba.gitnuro.preferences.AppSettings import com.jetpackduba.gitnuro.viewmodels.SettingsViewModel import dagger.Component import javax.inject.Singleton @Singleton -@Component +@Component( + modules = [ + AppModule::class + ] +) interface AppComponent { fun inject(main: App) fun appStateManager(): AppStateManager diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/di/modules/AppModule.kt b/src/main/kotlin/com/jetpackduba/gitnuro/di/modules/AppModule.kt new file mode 100644 index 0000000..47facdf --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/di/modules/AppModule.kt @@ -0,0 +1,15 @@ +package com.jetpackduba.gitnuro.di.modules + +import com.jetpackduba.gitnuro.di.qualifiers.AppCoroutineScope +import dagger.Module +import dagger.Provides +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob + +@Module +class AppModule { + @Provides + @AppCoroutineScope + fun provideAppScope(): CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) +} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/di/qualifiers/AppCoroutineScope.kt b/src/main/kotlin/com/jetpackduba/gitnuro/di/qualifiers/AppCoroutineScope.kt new file mode 100644 index 0000000..eea04ef --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/di/qualifiers/AppCoroutineScope.kt @@ -0,0 +1,7 @@ +package com.jetpackduba.gitnuro.di.qualifiers + +import javax.inject.Qualifier + +@Qualifier +@Retention(AnnotationRetention.RUNTIME) +annotation class AppCoroutineScope \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/preferences/AppSettings.kt b/src/main/kotlin/com/jetpackduba/gitnuro/preferences/AppSettings.kt index 3f3f848..037bb74 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/preferences/AppSettings.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/preferences/AppSettings.kt @@ -117,14 +117,15 @@ class AppSettings @Inject constructor() { _ffMergeFlow.value = value } - var commitsLimit: Int + val commitsLimit: Int get() { return preferences.getInt(PREF_COMMITS_LIMIT, DEFAULT_COMMITS_LIMIT) } - set(value) { - preferences.putInt(PREF_COMMITS_LIMIT, value) - _commitsLimitFlow.tryEmit(value) - } + + suspend fun setCommitsLimit(value: Int) { + preferences.putInt(PREF_COMMITS_LIMIT, value) + _commitsLimitFlow.emit(value) + } var windowPlacement: WindowsPlacementPreference get() { diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/LogViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/LogViewModel.kt index 8be0b74..8edb0ae 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/LogViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/LogViewModel.kt @@ -101,12 +101,12 @@ class LogViewModel @Inject constructor( init { tabScope.launch { - appSettings.commitsLimitEnabledFlow.drop(1).collect { + appSettings.commitsLimitEnabledFlow.drop(1).collectLatest { tabState.refreshData(RefreshType.ONLY_LOG) } } tabScope.launch { - appSettings.commitsLimitFlow.collect { + appSettings.commitsLimitFlow.collectLatest { tabState.refreshData(RefreshType.ONLY_LOG) } } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt index 34c2a83..3a73c43 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt @@ -1,19 +1,22 @@ package com.jetpackduba.gitnuro.viewmodels +import com.jetpackduba.gitnuro.di.qualifiers.AppCoroutineScope import com.jetpackduba.gitnuro.preferences.AppSettings import com.jetpackduba.gitnuro.theme.Theme +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch import javax.inject.Inject import javax.inject.Singleton @Singleton class SettingsViewModel @Inject constructor( - val appSettings: AppSettings, + private val appSettings: AppSettings, + @AppCoroutineScope private val appScope: CoroutineScope, ) { // Temporary values to detect changed variables var commitsLimit: Int = -1 val themeState = appSettings.themeState - val customThemeFlow = appSettings.customThemeFlow val ffMergeFlow = appSettings.ffMergeFlow val commitsLimitEnabledFlow = appSettings.commitsLimitEnabledFlow @@ -50,11 +53,11 @@ class SettingsViewModel @Inject constructor( commitsLimit = appSettings.commitsLimit } - fun savePendingChanges() { - val commitsLimit = this.commitsLimit + fun savePendingChanges() = appScope.launch { + val commitsLimit = this@SettingsViewModel.commitsLimit if (appSettings.commitsLimit != commitsLimit) { - appSettings.commitsLimit = commitsLimit + appSettings.setCommitsLimit(commitsLimit) } } } \ No newline at end of file