From a3386552d5e4195b5807742216b3a6ee30722510 Mon Sep 17 00:00:00 2001 From: Zane Schepke Date: Mon, 25 Dec 2023 23:12:06 -0500 Subject: [PATCH] refactor state --- .../1.json | 0 .../2.json | 0 .../3.json | 0 .../4.json | 0 .../wireguardautotunnel/MigrationTest.kt | 2 +- .../wireguardautotunnel/Extensions.kt | 1 + .../WireGuardAutoTunnel.kt | 8 +- .../{repository => data}/AppDatabase.kt | 8 +- .../DatabaseListConverters.kt | 2 +- .../SettingsDoa.kt => data/SettingsDao.kt} | 6 +- .../{repository => data}/TunnelConfigDao.kt | 4 +- .../datastore/DataStoreManager.kt | 2 +- .../{repository => data}/model/Settings.kt | 2 +- .../model/TunnelConfig.kt | 2 +- .../data/repository/SettingsRepository.kt | 11 + .../data/repository/SettingsRepositoryImpl.kt | 20 ++ .../data/repository/TunnelConfigRepository.kt | 5 + .../repository/TunnelConfigRepositoryImpl.kt | 7 + .../module/DatabaseModule.kt | 2 +- .../module/RepositoryModule.kt | 28 +- .../module/TunnelModule.kt | 4 +- .../receiver/BootReceiver.kt | 4 +- .../receiver/NotificationActionReceiver.kt | 4 +- .../WireGuardConnectivityWatcherService.kt | 6 +- .../foreground/WireGuardTunnelService.kt | 6 +- .../service/shortcut/ShortcutsActivity.kt | 10 +- .../service/tile/TunnelControlTile.kt | 8 +- .../service/tunnel/VpnService.kt | 2 +- .../service/tunnel/WireGuardTunnel.kt | 6 +- .../ui/ActivityViewModel.kt | 8 +- .../ui/screens/config/ConfigViewModel.kt | 8 +- .../ui/screens/main/MainScreen.kt | 3 +- .../ui/screens/main/MainViewModel.kt | 29 +- .../ui/screens/settings/SettingsScreen.kt | 118 ++++---- .../ui/screens/settings/SettingsUiState.kt | 13 + .../ui/screens/settings/SettingsViewModel.kt | 103 +++---- .../ui/screens/support/SupportScreen.kt | 252 ++++++++---------- .../ui/screens/support/SupportViewModel.kt | 11 +- 38 files changed, 364 insertions(+), 341 deletions(-) rename app/schemas/{com.zaneschepke.wireguardautotunnel.repository.AppDatabase => com.zaneschepke.wireguardautotunnel.data.AppDatabase}/1.json (100%) rename app/schemas/{com.zaneschepke.wireguardautotunnel.repository.AppDatabase => com.zaneschepke.wireguardautotunnel.data.AppDatabase}/2.json (100%) rename app/schemas/{com.zaneschepke.wireguardautotunnel.repository.AppDatabase => com.zaneschepke.wireguardautotunnel.data.AppDatabase}/3.json (100%) rename app/schemas/{com.zaneschepke.wireguardautotunnel.repository.AppDatabase => com.zaneschepke.wireguardautotunnel.data.AppDatabase}/4.json (100%) rename app/src/main/java/com/zaneschepke/wireguardautotunnel/{repository => data}/AppDatabase.kt (70%) rename app/src/main/java/com/zaneschepke/wireguardautotunnel/{repository => data}/DatabaseListConverters.kt (92%) rename app/src/main/java/com/zaneschepke/wireguardautotunnel/{repository/SettingsDoa.kt => data/SettingsDao.kt} (85%) rename app/src/main/java/com/zaneschepke/wireguardautotunnel/{repository => data}/TunnelConfigDao.kt (86%) rename app/src/main/java/com/zaneschepke/wireguardautotunnel/{repository => data}/datastore/DataStoreManager.kt (95%) rename app/src/main/java/com/zaneschepke/wireguardautotunnel/{repository => data}/model/Settings.kt (96%) rename app/src/main/java/com/zaneschepke/wireguardautotunnel/{repository => data}/model/TunnelConfig.kt (94%) create mode 100644 app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/SettingsRepository.kt create mode 100644 app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/SettingsRepositoryImpl.kt create mode 100644 app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/TunnelConfigRepository.kt create mode 100644 app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/TunnelConfigRepositoryImpl.kt create mode 100644 app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsUiState.kt diff --git a/app/schemas/com.zaneschepke.wireguardautotunnel.repository.AppDatabase/1.json b/app/schemas/com.zaneschepke.wireguardautotunnel.data.AppDatabase/1.json similarity index 100% rename from app/schemas/com.zaneschepke.wireguardautotunnel.repository.AppDatabase/1.json rename to app/schemas/com.zaneschepke.wireguardautotunnel.data.AppDatabase/1.json diff --git a/app/schemas/com.zaneschepke.wireguardautotunnel.repository.AppDatabase/2.json b/app/schemas/com.zaneschepke.wireguardautotunnel.data.AppDatabase/2.json similarity index 100% rename from app/schemas/com.zaneschepke.wireguardautotunnel.repository.AppDatabase/2.json rename to app/schemas/com.zaneschepke.wireguardautotunnel.data.AppDatabase/2.json diff --git a/app/schemas/com.zaneschepke.wireguardautotunnel.repository.AppDatabase/3.json b/app/schemas/com.zaneschepke.wireguardautotunnel.data.AppDatabase/3.json similarity index 100% rename from app/schemas/com.zaneschepke.wireguardautotunnel.repository.AppDatabase/3.json rename to app/schemas/com.zaneschepke.wireguardautotunnel.data.AppDatabase/3.json diff --git a/app/schemas/com.zaneschepke.wireguardautotunnel.repository.AppDatabase/4.json b/app/schemas/com.zaneschepke.wireguardautotunnel.data.AppDatabase/4.json similarity index 100% rename from app/schemas/com.zaneschepke.wireguardautotunnel.repository.AppDatabase/4.json rename to app/schemas/com.zaneschepke.wireguardautotunnel.data.AppDatabase/4.json diff --git a/app/src/androidTest/java/com/zaneschepke/wireguardautotunnel/MigrationTest.kt b/app/src/androidTest/java/com/zaneschepke/wireguardautotunnel/MigrationTest.kt index cfc4772..faaf970 100644 --- a/app/src/androidTest/java/com/zaneschepke/wireguardautotunnel/MigrationTest.kt +++ b/app/src/androidTest/java/com/zaneschepke/wireguardautotunnel/MigrationTest.kt @@ -3,7 +3,7 @@ package com.zaneschepke.wireguardautotunnel import androidx.room.testing.MigrationTestHelper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry -import com.zaneschepke.wireguardautotunnel.repository.AppDatabase +import com.zaneschepke.wireguardautotunnel.data.AppDatabase import java.io.IOException import org.junit.Rule import org.junit.Test diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/Extensions.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/Extensions.kt index 0236bfb..540c2a7 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/Extensions.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/Extensions.kt @@ -29,3 +29,4 @@ fun BigDecimal.toThreeDecimalPlaceString(): String { val df = DecimalFormat("#.###") return df.format(this) } + diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt index 8f21a59..ec43917 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt @@ -5,9 +5,9 @@ import android.content.Context import android.content.pm.PackageManager import androidx.lifecycle.ProcessLifecycleOwner import androidx.lifecycle.lifecycleScope -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa -import com.zaneschepke.wireguardautotunnel.repository.datastore.DataStoreManager -import com.zaneschepke.wireguardautotunnel.repository.model.Settings +import com.zaneschepke.wireguardautotunnel.data.SettingsDao +import com.zaneschepke.wireguardautotunnel.data.datastore.DataStoreManager +import com.zaneschepke.wireguardautotunnel.data.model.Settings import dagger.hilt.android.HiltAndroidApp import java.io.IOException import javax.inject.Inject @@ -17,7 +17,7 @@ import timber.log.Timber @HiltAndroidApp class WireGuardAutoTunnel : Application() { @Inject - lateinit var settingsRepo: SettingsDoa + lateinit var settingsRepo: SettingsDao @Inject lateinit var dataStoreManager: DataStoreManager diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/AppDatabase.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/AppDatabase.kt similarity index 70% rename from app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/AppDatabase.kt rename to app/src/main/java/com/zaneschepke/wireguardautotunnel/data/AppDatabase.kt index 7b83086..9467179 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/AppDatabase.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/AppDatabase.kt @@ -1,11 +1,11 @@ -package com.zaneschepke.wireguardautotunnel.repository +package com.zaneschepke.wireguardautotunnel.data import androidx.room.AutoMigration import androidx.room.Database import androidx.room.RoomDatabase import androidx.room.TypeConverters -import com.zaneschepke.wireguardautotunnel.repository.model.Settings -import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig +import com.zaneschepke.wireguardautotunnel.data.model.Settings +import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig @Database( entities = [Settings::class, TunnelConfig::class], @@ -20,7 +20,7 @@ import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig ) @TypeConverters(DatabaseListConverters::class) abstract class AppDatabase : RoomDatabase() { - abstract fun settingDao(): SettingsDoa + abstract fun settingDao(): SettingsDao abstract fun tunnelConfigDoa(): TunnelConfigDao } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/DatabaseListConverters.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/DatabaseListConverters.kt similarity index 92% rename from app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/DatabaseListConverters.kt rename to app/src/main/java/com/zaneschepke/wireguardautotunnel/data/DatabaseListConverters.kt index d6c2af9..dc44129 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/DatabaseListConverters.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/DatabaseListConverters.kt @@ -1,4 +1,4 @@ -package com.zaneschepke.wireguardautotunnel.repository +package com.zaneschepke.wireguardautotunnel.data import androidx.room.TypeConverter import kotlinx.serialization.encodeToString diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/SettingsDoa.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/SettingsDao.kt similarity index 85% rename from app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/SettingsDoa.kt rename to app/src/main/java/com/zaneschepke/wireguardautotunnel/data/SettingsDao.kt index 46c89ae..ffd1574 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/SettingsDoa.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/SettingsDao.kt @@ -1,15 +1,15 @@ -package com.zaneschepke.wireguardautotunnel.repository +package com.zaneschepke.wireguardautotunnel.data import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query -import com.zaneschepke.wireguardautotunnel.repository.model.Settings +import com.zaneschepke.wireguardautotunnel.data.model.Settings import kotlinx.coroutines.flow.Flow @Dao -interface SettingsDoa { +interface SettingsDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun save(t: Settings) diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/TunnelConfigDao.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/TunnelConfigDao.kt similarity index 86% rename from app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/TunnelConfigDao.kt rename to app/src/main/java/com/zaneschepke/wireguardautotunnel/data/TunnelConfigDao.kt index 9040fca..8460ace 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/TunnelConfigDao.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/TunnelConfigDao.kt @@ -1,11 +1,11 @@ -package com.zaneschepke.wireguardautotunnel.repository +package com.zaneschepke.wireguardautotunnel.data import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query -import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig +import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig import kotlinx.coroutines.flow.Flow @Dao diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/datastore/DataStoreManager.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/datastore/DataStoreManager.kt similarity index 95% rename from app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/datastore/DataStoreManager.kt rename to app/src/main/java/com/zaneschepke/wireguardautotunnel/data/datastore/DataStoreManager.kt index e99c2f2..6d9c67c 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/datastore/DataStoreManager.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/datastore/DataStoreManager.kt @@ -1,4 +1,4 @@ -package com.zaneschepke.wireguardautotunnel.repository.datastore +package com.zaneschepke.wireguardautotunnel.data.datastore import android.content.Context import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.booleanPreferencesKey diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/model/Settings.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/model/Settings.kt similarity index 96% rename from app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/model/Settings.kt rename to app/src/main/java/com/zaneschepke/wireguardautotunnel/data/model/Settings.kt index c44ace0..3ad4160 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/model/Settings.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/model/Settings.kt @@ -1,4 +1,4 @@ -package com.zaneschepke.wireguardautotunnel.repository.model +package com.zaneschepke.wireguardautotunnel.data.model import androidx.room.ColumnInfo import androidx.room.Entity diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/model/TunnelConfig.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/model/TunnelConfig.kt similarity index 94% rename from app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/model/TunnelConfig.kt rename to app/src/main/java/com/zaneschepke/wireguardautotunnel/data/model/TunnelConfig.kt index 2234368..3a1e04a 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/model/TunnelConfig.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/model/TunnelConfig.kt @@ -1,4 +1,4 @@ -package com.zaneschepke.wireguardautotunnel.repository.model +package com.zaneschepke.wireguardautotunnel.data.model import androidx.room.ColumnInfo import androidx.room.Entity diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/SettingsRepository.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/SettingsRepository.kt new file mode 100644 index 0000000..1619b39 --- /dev/null +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/SettingsRepository.kt @@ -0,0 +1,11 @@ +package com.zaneschepke.wireguardautotunnel.data.repository + +import com.zaneschepke.wireguardautotunnel.data.model.Settings +import kotlinx.coroutines.flow.Flow + +interface SettingsRepository { + suspend fun save(settings : Settings) + fun getSettings() : Flow + + suspend fun getAll() : List +} \ No newline at end of file diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/SettingsRepositoryImpl.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/SettingsRepositoryImpl.kt new file mode 100644 index 0000000..c9b5057 --- /dev/null +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/SettingsRepositoryImpl.kt @@ -0,0 +1,20 @@ +package com.zaneschepke.wireguardautotunnel.data.repository + +import com.zaneschepke.wireguardautotunnel.data.SettingsDao +import com.zaneschepke.wireguardautotunnel.data.model.Settings +import kotlinx.coroutines.flow.Flow + +class SettingsRepositoryImpl(private val settingsDoa: SettingsDao) : SettingsRepository { + + override suspend fun save(settings: Settings) { + settingsDoa.save(settings) + } + + override fun getSettings(): Flow { + return settingsDoa.getSettingsFlow() + } + + override suspend fun getAll(): List { + return settingsDoa.getAll() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/TunnelConfigRepository.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/TunnelConfigRepository.kt new file mode 100644 index 0000000..427753f --- /dev/null +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/TunnelConfigRepository.kt @@ -0,0 +1,5 @@ +package com.zaneschepke.wireguardautotunnel.data.repository + +interface TunnelConfigRepository { + +} \ No newline at end of file diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/TunnelConfigRepositoryImpl.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/TunnelConfigRepositoryImpl.kt new file mode 100644 index 0000000..10db72a --- /dev/null +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/data/repository/TunnelConfigRepositoryImpl.kt @@ -0,0 +1,7 @@ +package com.zaneschepke.wireguardautotunnel.data.repository + +import com.zaneschepke.wireguardautotunnel.data.TunnelConfigDao + +class TunnelConfigRepositoryImpl(private val tunnelConfigDao: TunnelConfigDao) : TunnelConfigRepository { + +} \ No newline at end of file diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/DatabaseModule.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/DatabaseModule.kt index 057b820..4634ecb 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/DatabaseModule.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/DatabaseModule.kt @@ -3,7 +3,7 @@ package com.zaneschepke.wireguardautotunnel.module import android.content.Context import androidx.room.Room import com.zaneschepke.wireguardautotunnel.R -import com.zaneschepke.wireguardautotunnel.repository.AppDatabase +import com.zaneschepke.wireguardautotunnel.data.AppDatabase import dagger.Module import dagger.Provides import dagger.hilt.InstallIn diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/RepositoryModule.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/RepositoryModule.kt index b1ecb0b..453607a 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/RepositoryModule.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/RepositoryModule.kt @@ -1,10 +1,14 @@ package com.zaneschepke.wireguardautotunnel.module import android.content.Context -import com.zaneschepke.wireguardautotunnel.repository.AppDatabase -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa -import com.zaneschepke.wireguardautotunnel.repository.TunnelConfigDao -import com.zaneschepke.wireguardautotunnel.repository.datastore.DataStoreManager +import com.zaneschepke.wireguardautotunnel.data.AppDatabase +import com.zaneschepke.wireguardautotunnel.data.SettingsDao +import com.zaneschepke.wireguardautotunnel.data.TunnelConfigDao +import com.zaneschepke.wireguardautotunnel.data.datastore.DataStoreManager +import com.zaneschepke.wireguardautotunnel.data.repository.SettingsRepository +import com.zaneschepke.wireguardautotunnel.data.repository.SettingsRepositoryImpl +import com.zaneschepke.wireguardautotunnel.data.repository.TunnelConfigRepository +import com.zaneschepke.wireguardautotunnel.data.repository.TunnelConfigRepositoryImpl import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -17,16 +21,28 @@ import javax.inject.Singleton class RepositoryModule { @Singleton @Provides - fun provideSettingsRepository(appDatabase: AppDatabase): SettingsDoa { + fun provideSettingsDoa(appDatabase: AppDatabase): SettingsDao { return appDatabase.settingDao() } @Singleton @Provides - fun provideTunnelConfigRepository(appDatabase: AppDatabase): TunnelConfigDao { + fun provideTunnelConfigDoa(appDatabase: AppDatabase): TunnelConfigDao { return appDatabase.tunnelConfigDoa() } + @Singleton + @Provides + fun provideTunnelConfigRepository(tunnelConfigDao: TunnelConfigDao): TunnelConfigRepository { + return TunnelConfigRepositoryImpl(tunnelConfigDao) + } + + @Singleton + @Provides + fun provideSettingsRepository(settingsDao: SettingsDao): SettingsRepository { + return SettingsRepositoryImpl(settingsDao) + } + @Singleton @Provides fun providePreferencesDataStore(@ApplicationContext context: Context): DataStoreManager { diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/TunnelModule.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/TunnelModule.kt index 7da9de2..a0767f8 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/TunnelModule.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/TunnelModule.kt @@ -6,7 +6,7 @@ import com.wireguard.android.backend.GoBackend import com.wireguard.android.backend.WgQuickBackend import com.wireguard.android.util.RootShell import com.wireguard.android.util.ToolsInstaller -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa +import com.zaneschepke.wireguardautotunnel.data.SettingsDao import com.zaneschepke.wireguardautotunnel.service.tunnel.VpnService import com.zaneschepke.wireguardautotunnel.service.tunnel.WireGuardTunnel import dagger.Module @@ -51,7 +51,7 @@ class TunnelModule { fun provideVpnService( @Userspace userspaceBackend: Backend, @Kernel kernelBackend: Backend, - settingsDoa: SettingsDoa + settingsDoa: SettingsDao ): VpnService { return WireGuardTunnel(userspaceBackend, kernelBackend, settingsDoa) } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt index 6e037aa..df594d9 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt @@ -4,7 +4,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import com.zaneschepke.wireguardautotunnel.goAsync -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa +import com.zaneschepke.wireguardautotunnel.data.SettingsDao import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject @@ -13,7 +13,7 @@ import kotlinx.coroutines.cancel @AndroidEntryPoint class BootReceiver : BroadcastReceiver() { @Inject - lateinit var settingsRepo: SettingsDoa + lateinit var settingsRepo: SettingsDao override fun onReceive( context: Context, diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/NotificationActionReceiver.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/NotificationActionReceiver.kt index 66adb88..ffe938e 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/NotificationActionReceiver.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/NotificationActionReceiver.kt @@ -5,7 +5,7 @@ import android.content.Context import android.content.Intent import com.zaneschepke.wireguardautotunnel.Constants import com.zaneschepke.wireguardautotunnel.goAsync -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa +import com.zaneschepke.wireguardautotunnel.data.SettingsDao import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject @@ -15,7 +15,7 @@ import kotlinx.coroutines.delay @AndroidEntryPoint class NotificationActionReceiver : BroadcastReceiver() { @Inject - lateinit var settingsRepo: SettingsDoa + lateinit var settingsRepo: SettingsDao override fun onReceive( context: Context, diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt index 3a2f7f9..c98a687 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt @@ -12,8 +12,8 @@ import androidx.lifecycle.lifecycleScope import com.wireguard.android.backend.Tunnel import com.zaneschepke.wireguardautotunnel.Constants import com.zaneschepke.wireguardautotunnel.R -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa -import com.zaneschepke.wireguardautotunnel.repository.model.Settings +import com.zaneschepke.wireguardautotunnel.data.SettingsDao +import com.zaneschepke.wireguardautotunnel.data.model.Settings import com.zaneschepke.wireguardautotunnel.service.network.EthernetService import com.zaneschepke.wireguardautotunnel.service.network.MobileDataService import com.zaneschepke.wireguardautotunnel.service.network.NetworkService @@ -44,7 +44,7 @@ class WireGuardConnectivityWatcherService : ForegroundService() { lateinit var ethernetService: NetworkService @Inject - lateinit var settingsRepo: SettingsDoa + lateinit var settingsRepo: SettingsDao @Inject lateinit var notificationService: NotificationService diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt index e53ee6a..0d5f611 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt @@ -8,8 +8,8 @@ import androidx.lifecycle.lifecycleScope import com.zaneschepke.wireguardautotunnel.Constants import com.zaneschepke.wireguardautotunnel.R import com.zaneschepke.wireguardautotunnel.receiver.NotificationActionReceiver -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa -import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig +import com.zaneschepke.wireguardautotunnel.data.SettingsDao +import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig import com.zaneschepke.wireguardautotunnel.service.notification.NotificationService import com.zaneschepke.wireguardautotunnel.service.tunnel.HandshakeStatus import com.zaneschepke.wireguardautotunnel.service.tunnel.VpnService @@ -28,7 +28,7 @@ class WireGuardTunnelService : ForegroundService() { lateinit var vpnService: VpnService @Inject - lateinit var settingsRepo: SettingsDoa + lateinit var settingsRepo: SettingsDao @Inject lateinit var notificationService: NotificationService diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsActivity.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsActivity.kt index ac48f3c..0d85acc 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsActivity.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsActivity.kt @@ -3,10 +3,10 @@ package com.zaneschepke.wireguardautotunnel.service.shortcut import android.os.Bundle import androidx.activity.ComponentActivity import androidx.lifecycle.lifecycleScope -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa -import com.zaneschepke.wireguardautotunnel.repository.TunnelConfigDao -import com.zaneschepke.wireguardautotunnel.repository.model.Settings -import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig +import com.zaneschepke.wireguardautotunnel.data.SettingsDao +import com.zaneschepke.wireguardautotunnel.data.TunnelConfigDao +import com.zaneschepke.wireguardautotunnel.data.model.Settings +import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig import com.zaneschepke.wireguardautotunnel.service.foreground.Action import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager import com.zaneschepke.wireguardautotunnel.service.foreground.WireGuardTunnelService @@ -20,7 +20,7 @@ import timber.log.Timber @AndroidEntryPoint class ShortcutsActivity : ComponentActivity() { @Inject - lateinit var settingsRepo: SettingsDoa + lateinit var settingsRepo: SettingsDao @Inject lateinit var tunnelConfigRepo: TunnelConfigDao diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt index dc4b3f7..d98069b 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt @@ -5,9 +5,9 @@ import android.service.quicksettings.Tile import android.service.quicksettings.TileService import com.wireguard.android.backend.Tunnel import com.zaneschepke.wireguardautotunnel.R -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa -import com.zaneschepke.wireguardautotunnel.repository.TunnelConfigDao -import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig +import com.zaneschepke.wireguardautotunnel.data.SettingsDao +import com.zaneschepke.wireguardautotunnel.data.TunnelConfigDao +import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager import com.zaneschepke.wireguardautotunnel.service.tunnel.VpnService import dagger.hilt.android.AndroidEntryPoint @@ -22,7 +22,7 @@ import timber.log.Timber @AndroidEntryPoint class TunnelControlTile : TileService() { @Inject - lateinit var settingsRepo: SettingsDoa + lateinit var settingsRepo: SettingsDao @Inject lateinit var configRepo: TunnelConfigDao diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/VpnService.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/VpnService.kt index 600fb2c..0f6aaa7 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/VpnService.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/VpnService.kt @@ -3,7 +3,7 @@ package com.zaneschepke.wireguardautotunnel.service.tunnel import com.wireguard.android.backend.Statistics import com.wireguard.android.backend.Tunnel import com.wireguard.crypto.Key -import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig +import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig import kotlinx.coroutines.flow.SharedFlow interface VpnService : Tunnel { diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/WireGuardTunnel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/WireGuardTunnel.kt index ac05c49..1c6e045 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/WireGuardTunnel.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/WireGuardTunnel.kt @@ -9,8 +9,8 @@ import com.wireguard.crypto.Key import com.zaneschepke.wireguardautotunnel.Constants import com.zaneschepke.wireguardautotunnel.module.Kernel import com.zaneschepke.wireguardautotunnel.module.Userspace -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa -import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig +import com.zaneschepke.wireguardautotunnel.data.SettingsDao +import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig import com.zaneschepke.wireguardautotunnel.util.NumberUtils import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -31,7 +31,7 @@ class WireGuardTunnel constructor( @Userspace private val userspaceBackend: Backend, @Kernel private val kernelBackend: Backend, - private val settingsRepo: SettingsDoa + private val settingsRepo: SettingsDao ) : VpnService { private val _tunnelName = MutableStateFlow("") override val tunnelName get() = _tunnelName.asStateFlow() diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/ActivityViewModel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/ActivityViewModel.kt index 25f8820..2f6d764 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/ActivityViewModel.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/ActivityViewModel.kt @@ -1,17 +1,13 @@ package com.zaneschepke.wireguardautotunnel.ui import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa -import com.zaneschepke.wireguardautotunnel.repository.model.Settings +import com.zaneschepke.wireguardautotunnel.data.SettingsDao import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.stateIn import javax.inject.Inject @HiltViewModel class ActivityViewModel @Inject constructor( - private val settingsRepo: SettingsDoa, + private val settingsRepo: SettingsDao, ) : ViewModel() { // val settings = settingsRepo.getSettingsFlow().stateIn(viewModelScope, // SharingStarted.WhileSubscribed(5000L), Settings() diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigViewModel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigViewModel.kt index 95481e1..7f2e103 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigViewModel.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigViewModel.kt @@ -15,9 +15,9 @@ import com.wireguard.config.Peer import com.wireguard.crypto.Key import com.wireguard.crypto.KeyPair import com.zaneschepke.wireguardautotunnel.Constants -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa -import com.zaneschepke.wireguardautotunnel.repository.TunnelConfigDao -import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig +import com.zaneschepke.wireguardautotunnel.data.SettingsDao +import com.zaneschepke.wireguardautotunnel.data.TunnelConfigDao +import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig import com.zaneschepke.wireguardautotunnel.ui.models.InterfaceProxy import com.zaneschepke.wireguardautotunnel.ui.models.PeerProxy import com.zaneschepke.wireguardautotunnel.util.NumberUtils @@ -35,7 +35,7 @@ class ConfigViewModel constructor( private val application: Application, private val tunnelRepo: TunnelConfigDao, - private val settingsRepo: SettingsDoa + private val settingsRepo: SettingsDao ) : ViewModel() { private val _tunnel = MutableStateFlow(null) private val _tunnelName = MutableStateFlow("") diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt index 53458fe..7ed0adf 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt @@ -84,9 +84,8 @@ import com.wireguard.android.backend.Tunnel import com.zaneschepke.wireguardautotunnel.Constants import com.zaneschepke.wireguardautotunnel.R import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel -import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig +import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig import com.zaneschepke.wireguardautotunnel.service.tunnel.HandshakeStatus -import com.zaneschepke.wireguardautotunnel.ui.ActivityViewModel import com.zaneschepke.wireguardautotunnel.ui.CaptureActivityPortrait import com.zaneschepke.wireguardautotunnel.ui.Routes import com.zaneschepke.wireguardautotunnel.ui.common.RowListItem diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt index b0454a9..a9f3c01 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt @@ -10,10 +10,11 @@ import androidx.lifecycle.viewModelScope import com.wireguard.config.Config import com.zaneschepke.wireguardautotunnel.Constants import com.zaneschepke.wireguardautotunnel.R -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa -import com.zaneschepke.wireguardautotunnel.repository.TunnelConfigDao -import com.zaneschepke.wireguardautotunnel.repository.model.Settings -import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig +import com.zaneschepke.wireguardautotunnel.data.SettingsDao +import com.zaneschepke.wireguardautotunnel.data.TunnelConfigDao +import com.zaneschepke.wireguardautotunnel.data.model.Settings +import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig +import com.zaneschepke.wireguardautotunnel.data.repository.SettingsRepository import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceState import com.zaneschepke.wireguardautotunnel.service.foreground.WireGuardConnectivityWatcherService @@ -39,7 +40,7 @@ class MainViewModel constructor( private val application: Application, private val tunnelRepo: TunnelConfigDao, - private val settingsRepo: SettingsDoa, + private val settingsRepository: SettingsRepository, private val vpnService: VpnService ) : ViewModel() { val tunnels get() = tunnelRepo.getAllFlow() @@ -53,10 +54,9 @@ constructor( init { viewModelScope.launch(Dispatchers.IO) { - settingsRepo.getAllFlow().filter { it.isNotEmpty() }.collect { - val settings = it.first() - validateWatcherServiceState(settings) - _settings.emit(settings) + settingsRepository.getSettings().collect { + validateWatcherServiceState(it) + _settings.emit(it) } } } @@ -79,13 +79,13 @@ constructor( viewModelScope.launch { if (tunnelRepo.count() == 1L) { ServiceManager.stopWatcherService(application.applicationContext) - val settings = settingsRepo.getAll() + val settings = settingsRepository.getAll() if (settings.isNotEmpty()) { val setting = settings[0] setting.defaultTunnel = null setting.isAutoTunnelEnabled = false setting.isAlwaysOnVpnEnabled = false - settingsRepo.save(setting) + saveSettings(setting) } } tunnelRepo.delete(tunnel) @@ -237,6 +237,11 @@ constructor( } } + private suspend fun saveSettings(settings: Settings) { + //TODO handle error if fails + settingsRepository.save(settings) + } + private fun getFileName( context: Context, uri: Uri @@ -268,7 +273,7 @@ constructor( defaultTunnel = selectedTunnel.toString() ) ) - settingsRepo.save(_settings.value) + settingsRepository.save(_settings.value) } } } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt index 8413ce1..8ff4823 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt @@ -4,7 +4,7 @@ import android.Manifest import android.content.Intent import android.net.Uri import android.os.Build -import android.provider.Settings +import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource @@ -38,13 +38,11 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi @@ -72,17 +70,15 @@ import com.wireguard.android.backend.Tunnel import com.wireguard.android.backend.WgQuickBackend import com.zaneschepke.wireguardautotunnel.R import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel -import com.zaneschepke.wireguardautotunnel.repository.datastore.DataStoreManager -import com.zaneschepke.wireguardautotunnel.ui.ActivityViewModel import com.zaneschepke.wireguardautotunnel.ui.common.ClickableIconButton import com.zaneschepke.wireguardautotunnel.ui.common.config.ConfigurationToggle import com.zaneschepke.wireguardautotunnel.ui.common.prompt.AuthorizationPrompt import com.zaneschepke.wireguardautotunnel.ui.common.text.SectionTitle import com.zaneschepke.wireguardautotunnel.util.FileUtils -import com.zaneschepke.wireguardautotunnel.util.WgTunnelException import java.io.File import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch + @OptIn( ExperimentalPermissionsApi::class, ExperimentalLayoutApi::class, @@ -102,33 +98,26 @@ fun SettingsScreen( val keyboardController = LocalSoftwareKeyboardController.current val interactionSource = remember { MutableInteractionSource() } - val settings by viewModel.settings.collectAsStateWithLifecycle() - val tunnels by viewModel.tunnels.collectAsStateWithLifecycle() - val vpnState = viewModel.vpnState.collectAsStateWithLifecycle() + val uiState by viewModel.uiState.collectAsStateWithLifecycle() val fineLocationState = rememberPermissionState(Manifest.permission.ACCESS_FINE_LOCATION) var currentText by remember { mutableStateOf("") } var isBackgroundLocationGranted by remember { mutableStateOf(true) } var didExportFiles by remember { mutableStateOf(false) } var showAuthPrompt by remember { mutableStateOf(false) } - var isLocationDisclosureShown by rememberSaveable { - mutableStateOf(false) - } val screenPadding = 5.dp val fillMaxWidth = .85f - LaunchedEffect(Unit) { - isLocationDisclosureShown = viewModel.isLocationDisclosureShown() - } + //TODO add error collecting and displaying for WGTunnelErrors fun exportAllConfigs() { try { - val files = tunnels.map { File(context.cacheDir, "${it.name}.conf") } + val files = uiState.tunnels.map { File(context.cacheDir, "${it.name}.conf") } files.forEachIndexed { index, file -> file.outputStream().use { - it.write(tunnels[index].wgQuick.toByteArray()) + it.write(uiState.tunnels[index].wgQuick.toByteArray()) } } FileUtils.saveFilesToZip(context, files) @@ -163,20 +152,31 @@ fun SettingsScreen( fun openSettings() { scope.launch { val intentSettings = - Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) + Intent(ACTION_APPLICATION_DETAILS_SETTINGS) intentSettings.data = Uri.fromParts("package", context.packageName, null) context.startActivity(intentSettings) } } + fun checkFineLocationGranted() { + isBackgroundLocationGranted = if (!fineLocationState.status.isGranted) { + false + } else { + scope.launch { + viewModel.setLocationDisclosureShown() + } + true + } + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { val backgroundLocationState = rememberPermissionState(Manifest.permission.ACCESS_BACKGROUND_LOCATION) isBackgroundLocationGranted = if (!backgroundLocationState.status.isGranted) { false } else { - if(!isLocationDisclosureShown) { + SideEffect { viewModel.setLocationDisclosureShown() } true @@ -194,7 +194,7 @@ fun SettingsScreen( } } - AnimatedVisibility(!isLocationDisclosureShown) { + AnimatedVisibility(!uiState.isLocationDisclosureShown) { Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Top, @@ -270,7 +270,7 @@ fun SettingsScreen( ) } - if (tunnels.isEmpty()) { + if (uiState.tunnels.isEmpty()) { Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, @@ -330,17 +330,15 @@ fun SettingsScreen( ) ConfigurationToggle( stringResource(id = R.string.tunnel_on_wifi), - enabled = !(settings.isAutoTunnelEnabled || settings.isAlwaysOnVpnEnabled), - checked = settings.isTunnelOnWifiEnabled, + enabled = !(uiState.settings.isAutoTunnelEnabled || uiState.settings.isAlwaysOnVpnEnabled), + checked = uiState.settings.isTunnelOnWifiEnabled, padding = screenPadding, onCheckChanged = { - scope.launch { - viewModel.onToggleTunnelOnWifi() - } + viewModel.onToggleTunnelOnWifi() }, modifier = Modifier.focusRequester(focusRequester) ) - AnimatedVisibility(visible = settings.isTunnelOnWifiEnabled) { + AnimatedVisibility(visible = uiState.settings.isTunnelOnWifiEnabled) { Column { FlowRow( modifier = Modifier @@ -348,19 +346,17 @@ fun SettingsScreen( .fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(5.dp) ) { - settings.trustedNetworkSSIDs.forEach { ssid -> + uiState.settings.trustedNetworkSSIDs.forEach { ssid -> ClickableIconButton( onIconClick = { - scope.launch { - viewModel.onDeleteTrustedSSID(ssid) - } + viewModel.onDeleteTrustedSSID(ssid) }, text = ssid, icon = Icons.Filled.Close, - enabled = !(settings.isAutoTunnelEnabled || settings.isAlwaysOnVpnEnabled) + enabled = !(uiState.settings.isAutoTunnelEnabled || uiState.settings.isAlwaysOnVpnEnabled) ) } - if (settings.trustedNetworkSSIDs.isEmpty()) { + if (uiState.settings.trustedNetworkSSIDs.isEmpty()) { Text( stringResource(R.string.none), fontStyle = FontStyle.Italic, @@ -369,7 +365,7 @@ fun SettingsScreen( } } OutlinedTextField( - enabled = !(settings.isAutoTunnelEnabled || settings.isAlwaysOnVpnEnabled), + enabled = !(uiState.settings.isAutoTunnelEnabled || uiState.settings.isAlwaysOnVpnEnabled), value = currentText, onValueChange = { currentText = it }, label = { Text(stringResource(R.string.add_trusted_ssid)) }, @@ -418,35 +414,29 @@ fun SettingsScreen( } ConfigurationToggle( stringResource(R.string.tunnel_mobile_data), - enabled = !(settings.isAutoTunnelEnabled || settings.isAlwaysOnVpnEnabled), - checked = settings.isTunnelOnMobileDataEnabled, + enabled = !(uiState.settings.isAutoTunnelEnabled || uiState.settings.isAlwaysOnVpnEnabled), + checked = uiState.settings.isTunnelOnMobileDataEnabled, padding = screenPadding, onCheckChanged = { - scope.launch { - viewModel.onToggleTunnelOnMobileData() - } + viewModel.onToggleTunnelOnMobileData() } ) ConfigurationToggle( stringResource(id = R.string.tunnel_on_ethernet), - enabled = !(settings.isAutoTunnelEnabled || settings.isAlwaysOnVpnEnabled), - checked = settings.isTunnelOnEthernetEnabled, + enabled = !(uiState.settings.isAutoTunnelEnabled || uiState.settings.isAlwaysOnVpnEnabled), + checked = uiState.settings.isTunnelOnEthernetEnabled, padding = screenPadding, onCheckChanged = { - scope.launch { - viewModel.onToggleTunnelOnEthernet() - } + viewModel.onToggleTunnelOnEthernet() } ) ConfigurationToggle( stringResource(R.string.battery_saver), - enabled = !(settings.isAutoTunnelEnabled || settings.isAlwaysOnVpnEnabled), - checked = settings.isBatterySaverEnabled, + enabled = !(uiState.settings.isAutoTunnelEnabled || uiState.settings.isAlwaysOnVpnEnabled), + checked = uiState.settings.isBatterySaverEnabled, padding = screenPadding, onCheckChanged = { - scope.launch { - viewModel.onToggleBatterySaver() - } + viewModel.onToggleBatterySaver() } ) Row( @@ -458,9 +448,9 @@ fun SettingsScreen( horizontalArrangement = Arrangement.Center ) { TextButton( - enabled = !settings.isAlwaysOnVpnEnabled, + enabled = !uiState.settings.isAlwaysOnVpnEnabled, onClick = { - if (!isAllAutoTunnelPermissionsEnabled() && settings.isTunnelOnWifiEnabled) { + if (!isAllAutoTunnelPermissionsEnabled() && uiState.settings.isTunnelOnWifiEnabled) { val message = if (!isBackgroundLocationGranted) { context.getString(R.string.background_location_required) @@ -471,14 +461,12 @@ fun SettingsScreen( } showSnackbarMessage(message) } else { - scope.launch { - viewModel.toggleAutoTunnel() - } + viewModel.toggleAutoTunnel() } } ) { val autoTunnelButtonText = - if (settings.isAutoTunnelEnabled) { + if (uiState.settings.isAutoTunnelEnabled) { stringResource(R.string.disable_auto_tunnel) } else { stringResource(id = R.string.enable_auto_tunnel) @@ -510,19 +498,13 @@ fun SettingsScreen( ConfigurationToggle( stringResource(R.string.use_kernel), enabled = !( - settings.isAutoTunnelEnabled || settings.isAlwaysOnVpnEnabled || - (vpnState.value == Tunnel.State.UP) + uiState.settings.isAutoTunnelEnabled || uiState.settings.isAlwaysOnVpnEnabled || + (uiState.tunnelState == Tunnel.State.UP) ), - checked = settings.isKernelEnabled, + checked = uiState.settings.isKernelEnabled, padding = screenPadding, onCheckChanged = { - scope.launch { - try { - viewModel.onToggleKernelMode() - } catch (e: WgTunnelException) { - showSnackbarMessage(e.message) - } - } + viewModel.onToggleKernelMode() } ) } @@ -550,8 +532,8 @@ fun SettingsScreen( ) ConfigurationToggle( stringResource(R.string.always_on_vpn_support), - enabled = !settings.isAutoTunnelEnabled, - checked = settings.isAlwaysOnVpnEnabled, + enabled = !uiState.settings.isAutoTunnelEnabled, + checked = uiState.settings.isAlwaysOnVpnEnabled, padding = screenPadding, onCheckChanged = { scope.launch { @@ -562,7 +544,7 @@ fun SettingsScreen( ConfigurationToggle( stringResource(R.string.enabled_app_shortcuts), enabled = true, - checked = settings.isShortcutsEnabled, + checked = uiState.settings.isShortcutsEnabled, padding = screenPadding, onCheckChanged = { scope.launch { diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsUiState.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsUiState.kt new file mode 100644 index 0000000..9a40f73 --- /dev/null +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsUiState.kt @@ -0,0 +1,13 @@ +package com.zaneschepke.wireguardautotunnel.ui.screens.settings + +import com.wireguard.android.backend.Tunnel +import com.zaneschepke.wireguardautotunnel.data.model.Settings +import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig + +data class SettingsUiState( + val settings : Settings = Settings(), + val tunnels : List = emptyList(), + val tunnelState : Tunnel.State = Tunnel.State.DOWN, + val isLocationDisclosureShown : Boolean = true, + val loading : Boolean = true, +) diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsViewModel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsViewModel.kt index 3cb6025..08a3b1e 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsViewModel.kt @@ -6,18 +6,18 @@ import android.location.LocationManager import android.os.Build import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.wireguard.android.backend.Tunnel import com.wireguard.android.util.RootShell -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa -import com.zaneschepke.wireguardautotunnel.repository.TunnelConfigDao -import com.zaneschepke.wireguardautotunnel.repository.datastore.DataStoreManager -import com.zaneschepke.wireguardautotunnel.repository.model.Settings +import com.zaneschepke.wireguardautotunnel.data.TunnelConfigDao +import com.zaneschepke.wireguardautotunnel.data.datastore.DataStoreManager +import com.zaneschepke.wireguardautotunnel.data.model.Settings +import com.zaneschepke.wireguardautotunnel.data.repository.SettingsRepository import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager import com.zaneschepke.wireguardautotunnel.service.tunnel.VpnService import com.zaneschepke.wireguardautotunnel.util.WgTunnelException import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import timber.log.Timber @@ -28,24 +28,27 @@ class SettingsViewModel constructor( private val application: Application, private val tunnelRepo: TunnelConfigDao, - private val settingsRepo: SettingsDoa, + private val settingsRepository: SettingsRepository, private val dataStoreManager: DataStoreManager, private val rootShell: RootShell, private val vpnService: VpnService ) : ViewModel() { - val settings = settingsRepo.getSettingsFlow().stateIn(viewModelScope, - SharingStarted.WhileSubscribed(5_000L), Settings()) - val tunnels = tunnelRepo.getAllFlow().stateIn(viewModelScope, - SharingStarted.WhileSubscribed(5_000L), emptyList()) - val vpnState get() = vpnService.state.stateIn(viewModelScope, - SharingStarted.WhileSubscribed(5_000L), Tunnel.State.DOWN) + val uiState = combine( + settingsRepository.getSettings(), + tunnelRepo.getAllFlow(), + vpnService.state, + dataStoreManager.locationDisclosureFlow, + ){ settings, tunnels, tunnelState, locationDisclosure -> + SettingsUiState(settings, tunnels, tunnelState, locationDisclosure ?: false, false) + }.stateIn(viewModelScope, + SharingStarted.WhileSubscribed(5_000L), SettingsUiState()) - suspend fun onSaveTrustedSSID(ssid: String) { + fun onSaveTrustedSSID(ssid: String) { val trimmed = ssid.trim() - if (!settings.value.trustedNetworkSSIDs.contains(trimmed)) { - settings.value.trustedNetworkSSIDs.add(trimmed) - settingsRepo.save(settings.value) + if (!uiState.value.settings.trustedNetworkSSIDs.contains(trimmed)) { + uiState.value.settings.trustedNetworkSSIDs.add(trimmed) + saveSettings(uiState.value.settings) } else { throw WgTunnelException("SSID already exists.") } @@ -55,39 +58,37 @@ constructor( return dataStoreManager.getFromStore(DataStoreManager.LOCATION_DISCLOSURE_SHOWN) ?: false } - fun setLocationDisclosureShown() { - viewModelScope.launch { + fun setLocationDisclosureShown() = viewModelScope.launch { dataStoreManager.saveToDataStore(DataStoreManager.LOCATION_DISCLOSURE_SHOWN, true) - } } - suspend fun onToggleTunnelOnMobileData() { - settingsRepo.save( - settings.value.copy( - isTunnelOnMobileDataEnabled = !settings.value.isTunnelOnMobileDataEnabled + fun onToggleTunnelOnMobileData() { + saveSettings( + uiState.value.settings.copy( + isTunnelOnMobileDataEnabled = !uiState.value.settings.isTunnelOnMobileDataEnabled ) ) } - suspend fun onDeleteTrustedSSID(ssid: String) { - settings.value.trustedNetworkSSIDs.remove(ssid) - settingsRepo.save(settings.value) + fun onDeleteTrustedSSID(ssid: String) { + uiState.value.settings.trustedNetworkSSIDs.remove(ssid) + saveSettings(uiState.value.settings) } private suspend fun getDefaultTunnelOrFirst() : String { - return settings.value.defaultTunnel ?: tunnelRepo.getAll().first().wgQuick + return uiState.value.settings.defaultTunnel ?: tunnelRepo.getAll().first().wgQuick } - suspend fun toggleAutoTunnel() { + fun toggleAutoTunnel() = viewModelScope.launch { val defaultTunnel = getDefaultTunnelOrFirst() - if (settings.value.isAutoTunnelEnabled) { + if (uiState.value.settings.isAutoTunnelEnabled) { ServiceManager.stopWatcherService(application) } else { ServiceManager.startWatcherService(application, defaultTunnel) } saveSettings( - settings.value.copy( - isAutoTunnelEnabled = settings.value.isAutoTunnelEnabled, + uiState.value.settings.copy( + isAutoTunnelEnabled = uiState.value.settings.isAutoTunnelEnabled, defaultTunnel = defaultTunnel ) ) @@ -95,20 +96,20 @@ constructor( suspend fun onToggleAlwaysOnVPN() { val updatedSettings = - settings.value.copy( - isAlwaysOnVpnEnabled = !settings.value.isAlwaysOnVpnEnabled, + uiState.value.settings.copy( + isAlwaysOnVpnEnabled = !uiState.value.settings.isAlwaysOnVpnEnabled, defaultTunnel = getDefaultTunnelOrFirst() ) saveSettings(updatedSettings) } - private suspend fun saveSettings(settings: Settings) { - settingsRepo.save(settings) + private fun saveSettings(settings: Settings) = viewModelScope.launch { + settingsRepository.save(settings) } - suspend fun onToggleTunnelOnEthernet() { - saveSettings(settings.value.copy( - isTunnelOnEthernetEnabled = !settings.value.isTunnelOnEthernetEnabled + fun onToggleTunnelOnEthernet() { + saveSettings(uiState.value.settings.copy( + isTunnelOnEthernetEnabled = !uiState.value.settings.isTunnelOnEthernetEnabled )) } @@ -122,40 +123,40 @@ constructor( return (!isLocationServicesEnabled() && Build.VERSION.SDK_INT > Build.VERSION_CODES.P) } - suspend fun onToggleShortcutsEnabled() { + fun onToggleShortcutsEnabled() { saveSettings( - settings.value.copy( - isShortcutsEnabled = !settings.value.isShortcutsEnabled + uiState.value.settings.copy( + isShortcutsEnabled = !uiState.value.settings.isShortcutsEnabled ) ) } - suspend fun onToggleBatterySaver() { + fun onToggleBatterySaver() { saveSettings( - settings.value.copy( - isBatterySaverEnabled = !settings.value.isBatterySaverEnabled + uiState.value.settings.copy( + isBatterySaverEnabled = !uiState.value.settings.isBatterySaverEnabled ) ) } - private suspend fun saveKernelMode(on: Boolean) { + private fun saveKernelMode(on: Boolean) { saveSettings( - settings.value.copy( + uiState.value.settings.copy( isKernelEnabled = on ) ) } - suspend fun onToggleTunnelOnWifi() { + fun onToggleTunnelOnWifi() { saveSettings( - settings.value.copy( - isTunnelOnWifiEnabled = !settings.value.isTunnelOnWifiEnabled + uiState.value.settings.copy( + isTunnelOnWifiEnabled = !uiState.value.settings.isTunnelOnWifiEnabled ) ) } - suspend fun onToggleKernelMode() { - if (!settings.value.isKernelEnabled) { + fun onToggleKernelMode() = viewModelScope.launch { + if (!uiState.value.settings.isKernelEnabled) { try { rootShell.start() Timber.d("Root shell accepted!") diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/SupportScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/SupportScreen.kt index 9ac9c64..b55eb07 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/SupportScreen.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/SupportScreen.kt @@ -51,194 +51,160 @@ import com.zaneschepke.wireguardautotunnel.BuildConfig import com.zaneschepke.wireguardautotunnel.Constants import com.zaneschepke.wireguardautotunnel.R import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel -import com.zaneschepke.wireguardautotunnel.ui.screens.settings.SettingsViewModel @Composable fun SupportScreen( - viewModel: SettingsViewModel = hiltViewModel(), + viewModel: SupportViewModel = hiltViewModel(), padding: PaddingValues, focusRequester: FocusRequester ) { - val context = LocalContext.current - val fillMaxWidth = .85f + val context = LocalContext.current + val fillMaxWidth = .85f - val settings by viewModel.settings.collectAsStateWithLifecycle() + val settings by viewModel.settings.collectAsStateWithLifecycle() - fun openWebPage(url: String) { - val webpage: Uri = Uri.parse(url) - val intent = Intent(Intent.ACTION_VIEW, webpage) - context.startActivity(intent) - } + fun openWebPage(url: String) { + val webpage: Uri = Uri.parse(url) + val intent = Intent(Intent.ACTION_VIEW, webpage) + context.startActivity(intent) + } - fun launchEmail() { - val intent = - Intent(Intent.ACTION_SEND).apply { - type = Constants.EMAIL_MIME_TYPE - putExtra(Intent.EXTRA_EMAIL, context.getString(R.string.my_email)) - putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.email_subject)) - } - startActivity( - context, - createChooser(intent, context.getString(R.string.email_chooser)), - null - ) - } + fun launchEmail() { + val intent = + Intent(Intent.ACTION_SEND).apply { + type = Constants.EMAIL_MIME_TYPE + putExtra(Intent.EXTRA_EMAIL, context.getString(R.string.my_email)) + putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.email_subject)) + } + startActivity(context, createChooser(intent, context.getString(R.string.email_chooser)), null) + } - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Top, - modifier = - Modifier - .fillMaxSize() - .verticalScroll(rememberScrollState()) - .focusable() - .padding(padding) - ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Top, + modifier = + Modifier.fillMaxSize() + .verticalScroll(rememberScrollState()) + .focusable() + .padding(padding)) { Surface( tonalElevation = 2.dp, shadowElevation = 2.dp, shape = RoundedCornerShape(12.dp), color = MaterialTheme.colorScheme.surface, modifier = - ( - if (WireGuardAutoTunnel.isRunningOnAndroidTv(context)) { - Modifier - .height(IntrinsicSize.Min) - .fillMaxWidth(fillMaxWidth) - .padding(top = 10.dp) + (if (WireGuardAutoTunnel.isRunningOnAndroidTv(context)) { + Modifier.height(IntrinsicSize.Min) + .fillMaxWidth(fillMaxWidth) + .padding(top = 10.dp) } else { - Modifier - .fillMaxWidth(fillMaxWidth) - .padding(top = 20.dp) - } - ).padding(bottom = 25.dp) - ) { - Column(modifier = Modifier.padding(20.dp)) { + Modifier.fillMaxWidth(fillMaxWidth).padding(top = 20.dp) + }) + .padding(bottom = 25.dp)) { + Column(modifier = Modifier.padding(20.dp)) { Text( stringResource(R.string.thank_you), textAlign = TextAlign.Start, modifier = Modifier.padding(bottom = 20.dp), - fontSize = 16.sp - ) + fontSize = 16.sp) Text( stringResource(id = R.string.support_help_text), textAlign = TextAlign.Start, fontSize = 16.sp, - modifier = Modifier.padding(bottom = 20.dp) - ) - TextButton(onClick = { - openWebPage(context.resources.getString(R.string.docs_url)) - }, modifier = Modifier.padding(vertical = 5.dp).focusRequester(focusRequester)) { - Row( - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth() - ) { - Row { - Icon(Icons.Rounded.Book, stringResource(id = R.string.docs)) - Text( - stringResource(id = R.string.docs_description), - textAlign = TextAlign.Justify, - modifier = Modifier.padding(start = 10.dp) - ) - } - Icon(Icons.Rounded.ArrowForward, stringResource(id = R.string.go)) + modifier = Modifier.padding(bottom = 20.dp)) + TextButton( + onClick = { openWebPage(context.resources.getString(R.string.docs_url)) }, + modifier = Modifier.padding(vertical = 5.dp).focusRequester(focusRequester)) { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth()) { + Row { + Icon(Icons.Rounded.Book, stringResource(id = R.string.docs)) + Text( + stringResource(id = R.string.docs_description), + textAlign = TextAlign.Justify, + modifier = Modifier.padding(start = 10.dp)) + } + Icon(Icons.Rounded.ArrowForward, stringResource(id = R.string.go)) + } } - } Divider(color = MaterialTheme.colorScheme.onBackground, thickness = 0.5.dp) TextButton( onClick = { openWebPage(context.resources.getString(R.string.discord_url)) }, - modifier = Modifier.padding(vertical = 5.dp) - ) { - Row( - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth() - ) { - Row { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.discord), - stringResource( - id = R.string.discord - ), - Modifier.size(25.dp) - ) - Text( - stringResource(id = R.string.discord_description), - textAlign = TextAlign.Justify, - modifier = Modifier.padding(start = 10.dp) - ) - } - Icon(Icons.Rounded.ArrowForward, stringResource(id = R.string.go)) + modifier = Modifier.padding(vertical = 5.dp)) { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth()) { + Row { + Icon( + imageVector = ImageVector.vectorResource(R.drawable.discord), + stringResource(id = R.string.discord), + Modifier.size(25.dp)) + Text( + stringResource(id = R.string.discord_description), + textAlign = TextAlign.Justify, + modifier = Modifier.padding(start = 10.dp)) + } + Icon(Icons.Rounded.ArrowForward, stringResource(id = R.string.go)) + } } - } Divider(color = MaterialTheme.colorScheme.onBackground, thickness = 0.5.dp) TextButton( onClick = { openWebPage(context.resources.getString(R.string.github_url)) }, - modifier = Modifier.padding(vertical = 5.dp) - ) { - Row( - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth() - ) { - Row { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.github), - stringResource( - id = R.string.github - ), - Modifier.size(25.dp) - ) - Text( - "Open an issue", - textAlign = TextAlign.Justify, - modifier = Modifier.padding(start = 10.dp) - ) - } - Icon(Icons.Rounded.ArrowForward, stringResource(id = R.string.go)) + modifier = Modifier.padding(vertical = 5.dp)) { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth()) { + Row { + Icon( + imageVector = ImageVector.vectorResource(R.drawable.github), + stringResource(id = R.string.github), + Modifier.size(25.dp)) + Text( + "Open an issue", + textAlign = TextAlign.Justify, + modifier = Modifier.padding(start = 10.dp)) + } + Icon(Icons.Rounded.ArrowForward, stringResource(id = R.string.go)) + } } - } Divider(color = MaterialTheme.colorScheme.onBackground, thickness = 0.5.dp) TextButton( - onClick = { launchEmail() }, - modifier = Modifier.padding(vertical = 5.dp) - ) { - Row( - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth() - ) { - Row { - Icon(Icons.Rounded.Mail, stringResource(id = R.string.email)) - Text( - stringResource(id = R.string.email_description), - textAlign = TextAlign.Justify, - modifier = Modifier.padding(start = 10.dp) - ) - } - Icon(Icons.Rounded.ArrowForward, stringResource(id = R.string.go)) + onClick = { launchEmail() }, modifier = Modifier.padding(vertical = 5.dp)) { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth()) { + Row { + Icon(Icons.Rounded.Mail, stringResource(id = R.string.email)) + Text( + stringResource(id = R.string.email_description), + textAlign = TextAlign.Justify, + modifier = Modifier.padding(start = 10.dp)) + } + Icon(Icons.Rounded.ArrowForward, stringResource(id = R.string.go)) + } } - } + } } - } Spacer(modifier = Modifier.weight(1f)) Text( stringResource(id = R.string.privacy_policy), style = TextStyle(textDecoration = TextDecoration.Underline), fontSize = 16.sp, modifier = - Modifier.clickable { - openWebPage(context.resources.getString(R.string.privacy_policy_url)) - } - ) + Modifier.clickable { + openWebPage(context.resources.getString(R.string.privacy_policy_url)) + }) Row( horizontalArrangement = Arrangement.spacedBy(25.dp), verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.padding(25.dp) - ) { - Text("Version: ${BuildConfig.VERSION_NAME}") - Text("Mode: ${if (settings.isKernelEnabled) "Kernel" else "Userspace" }") - } - } + modifier = Modifier.padding(25.dp)) { + Text("Version: ${BuildConfig.VERSION_NAME}") + Text("Mode: ${if (settings.isKernelEnabled) "Kernel" else "Userspace" }") + } + } } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/SupportViewModel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/SupportViewModel.kt index b58ac11..96035fd 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/SupportViewModel.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/SupportViewModel.kt @@ -2,8 +2,9 @@ package com.zaneschepke.wireguardautotunnel.ui.screens.support import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa -import com.zaneschepke.wireguardautotunnel.repository.model.Settings +import com.zaneschepke.wireguardautotunnel.data.SettingsDao +import com.zaneschepke.wireguardautotunnel.data.model.Settings +import com.zaneschepke.wireguardautotunnel.data.repository.SettingsRepository import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.Dispatchers @@ -13,13 +14,13 @@ import kotlinx.coroutines.launch @HiltViewModel class SupportViewModel @Inject constructor( - private val settingsRepo: SettingsDoa + private val settingsRepository: SettingsRepository ) : ViewModel() { private val _settings = MutableStateFlow(Settings()) - val settings get() = _settings.asStateFlow() + val settings = _settings.asStateFlow() init { viewModelScope.launch(Dispatchers.IO) { - _settings.value = settingsRepo.getAll().first() + _settings.value = settingsRepository.getAll().first() } } }