mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
feat/decoupling (#4685)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
40244f8337
commit
2c49db8041
254 changed files with 5132 additions and 2666 deletions
|
|
@ -40,7 +40,7 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.administration
|
||||
import org.meshtastic.core.resources.preserve_favorites
|
||||
|
|
|
|||
|
|
@ -32,11 +32,6 @@ import kotlinx.coroutines.flow.update
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.meshtastic.core.common.BuildConfigProvider
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.data.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.database.DatabaseManager
|
||||
import org.meshtastic.core.database.entity.MyNodeEntity
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.domain.usecase.settings.ExportDataUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.IsOtaCapableUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.MeshLocationUseCase
|
||||
|
|
@ -45,9 +40,14 @@ import org.meshtastic.core.domain.usecase.settings.SetDatabaseCacheLimitUseCase
|
|||
import org.meshtastic.core.domain.usecase.settings.SetMeshLogSettingsUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.SetProvideLocationUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.SetThemeUseCase
|
||||
import org.meshtastic.core.model.MyNodeInfo
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.prefs.meshlog.MeshLogPrefs
|
||||
import org.meshtastic.core.prefs.ui.UiPrefs
|
||||
import org.meshtastic.core.repository.DatabaseManager
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed
|
||||
import org.meshtastic.proto.LocalConfig
|
||||
import java.io.BufferedWriter
|
||||
|
|
@ -77,7 +77,7 @@ constructor(
|
|||
private val exportDataUseCase: ExportDataUseCase,
|
||||
private val isOtaCapableUseCase: IsOtaCapableUseCase,
|
||||
) : ViewModel() {
|
||||
val myNodeInfo: StateFlow<MyNodeEntity?> = nodeRepository.myNodeInfo
|
||||
val myNodeInfo: StateFlow<MyNodeInfo?> = nodeRepository.myNodeInfo
|
||||
|
||||
val myNodeNum
|
||||
get() = myNodeInfo.value?.myNodeNum
|
||||
|
|
@ -170,7 +170,7 @@ constructor(
|
|||
*/
|
||||
@Suppress("detekt:CyclomaticComplexMethod", "detekt:LongMethod")
|
||||
fun saveDataCsv(uri: Uri, filterPortnum: Int? = null) {
|
||||
viewModelScope.launch(Dispatchers.Main) {
|
||||
viewModelScope.launch {
|
||||
val myNodeNum = myNodeNum ?: return@launch
|
||||
writeToUri(uri) { writer -> exportDataUseCase(writer, myNodeNum, filterPortnum) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,13 +37,13 @@ import org.meshtastic.core.common.util.nowInstant
|
|||
import org.meshtastic.core.common.util.toDate
|
||||
import org.meshtastic.core.common.util.toInstant
|
||||
import org.meshtastic.core.data.repository.MeshLogRepository
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.database.entity.MeshLog
|
||||
import org.meshtastic.core.database.entity.Packet
|
||||
import org.meshtastic.core.model.getTracerouteResponse
|
||||
import org.meshtastic.core.model.util.decodeOrNull
|
||||
import org.meshtastic.core.model.util.toReadableString
|
||||
import org.meshtastic.core.prefs.meshlog.MeshLogPrefs
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.debug_clear
|
||||
import org.meshtastic.core.resources.debug_clear_logs_confirm
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import org.meshtastic.core.prefs.filter.FilterPrefs
|
||||
import org.meshtastic.core.service.filter.MessageFilterService
|
||||
import org.meshtastic.core.repository.MessageFilter
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
|
|
@ -30,7 +30,7 @@ class FilterSettingsViewModel
|
|||
@Inject
|
||||
constructor(
|
||||
private val filterPrefs: FilterPrefs,
|
||||
private val messageFilterService: MessageFilterService,
|
||||
private val messageFilter: MessageFilter,
|
||||
) : ViewModel() {
|
||||
|
||||
private val _filterEnabled = MutableStateFlow(filterPrefs.filterEnabled)
|
||||
|
|
@ -51,7 +51,7 @@ constructor(
|
|||
if (current.add(trimmed)) {
|
||||
filterPrefs.filterWords = current
|
||||
_filterWords.value = current.toList().sorted()
|
||||
messageFilterService.rebuildPatterns()
|
||||
messageFilter.rebuildPatterns()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ constructor(
|
|||
if (current.remove(word)) {
|
||||
filterPrefs.filterWords = current
|
||||
_filterWords.value = current.toList().sorted()
|
||||
messageFilterService.rebuildPatterns()
|
||||
messageFilter.rebuildPatterns()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.clean_node_database_description
|
||||
import org.meshtastic.core.resources.clean_node_database_title
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ import kotlinx.coroutines.flow.asStateFlow
|
|||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.compose.resources.getString
|
||||
import org.meshtastic.core.common.util.nowSeconds
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.domain.usecase.settings.CleanNodeDatabaseUseCase
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.are_you_sure
|
||||
import org.meshtastic.core.resources.clean_node_database_confirmation
|
||||
|
|
|
|||
|
|
@ -43,11 +43,6 @@ import kotlinx.coroutines.launch
|
|||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.meshtastic.core.data.repository.LocationRepository
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.data.repository.PacketRepository
|
||||
import org.meshtastic.core.data.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.database.entity.MyNodeEntity
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.domain.usecase.settings.AdminActionsUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.ExportProfileUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.ExportSecurityConfigUseCase
|
||||
|
|
@ -59,15 +54,20 @@ import org.meshtastic.core.domain.usecase.settings.RadioResponseResult
|
|||
import org.meshtastic.core.domain.usecase.settings.ToggleAnalyticsUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.ToggleHomoglyphEncodingUseCase
|
||||
import org.meshtastic.core.model.ConnectionState
|
||||
import org.meshtastic.core.model.MyNodeInfo
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.model.Position
|
||||
import org.meshtastic.core.navigation.SettingsRoutes
|
||||
import org.meshtastic.core.prefs.analytics.AnalyticsPrefs
|
||||
import org.meshtastic.core.prefs.homoglyph.HomoglyphPrefs
|
||||
import org.meshtastic.core.prefs.map.MapConsentPrefs
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.repository.PacketRepository
|
||||
import org.meshtastic.core.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.repository.ServiceRepository
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.UiText
|
||||
import org.meshtastic.core.resources.cant_shutdown
|
||||
import org.meshtastic.core.service.ServiceRepository
|
||||
import org.meshtastic.core.ui.util.getChannelList
|
||||
import org.meshtastic.feature.settings.navigation.ConfigRoute
|
||||
import org.meshtastic.feature.settings.navigation.ModuleRoute
|
||||
|
|
@ -217,7 +217,7 @@ constructor(
|
|||
Logger.d { "RadioConfigViewModel created" }
|
||||
}
|
||||
|
||||
private val myNodeInfo: StateFlow<MyNodeEntity?>
|
||||
private val myNodeInfo: StateFlow<MyNodeInfo?>
|
||||
get() = nodeRepository.myNodeInfo
|
||||
|
||||
val myNodeNum
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.cancel
|
||||
import org.meshtastic.core.resources.send
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ import androidx.compose.ui.graphics.Color
|
|||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.database.model.getColorFrom
|
||||
import org.meshtastic.core.database.model.getStringResFrom
|
||||
import org.meshtastic.core.model.getColorFrom
|
||||
import org.meshtastic.core.model.getStringResFrom
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.tak
|
||||
import org.meshtastic.core.resources.tak_config
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ import androidx.compose.ui.text.input.KeyboardType
|
|||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.database.model.isUnmessageableRole
|
||||
import org.meshtastic.core.model.Capabilities
|
||||
import org.meshtastic.core.model.isUnmessageableRole
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.hardware_model
|
||||
import org.meshtastic.core.resources.licensed_amateur_radio
|
||||
|
|
|
|||
|
|
@ -30,9 +30,6 @@ import org.junit.After
|
|||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.meshtastic.core.common.BuildConfigProvider
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.data.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.database.DatabaseManager
|
||||
import org.meshtastic.core.domain.usecase.settings.ExportDataUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.IsOtaCapableUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.MeshLocationUseCase
|
||||
|
|
@ -44,8 +41,13 @@ import org.meshtastic.core.domain.usecase.settings.SetThemeUseCase
|
|||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.prefs.meshlog.MeshLogPrefs
|
||||
import org.meshtastic.core.prefs.ui.UiPrefs
|
||||
import org.meshtastic.core.repository.DatabaseManager
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.repository.RadioConfigRepository
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Config(sdk = [34])
|
||||
class SettingsViewModelTest {
|
||||
|
||||
private val testDispatcher = StandardTestDispatcher()
|
||||
|
|
@ -58,14 +60,14 @@ class SettingsViewModelTest {
|
|||
private val databaseManager: DatabaseManager = mockk(relaxed = true)
|
||||
private val meshLogPrefs: MeshLogPrefs = mockk(relaxed = true)
|
||||
|
||||
private val setThemeUseCase: SetThemeUseCase = mockk(relaxed = true)
|
||||
private val setAppIntroCompletedUseCase: SetAppIntroCompletedUseCase = mockk(relaxed = true)
|
||||
private val setProvideLocationUseCase: SetProvideLocationUseCase = mockk(relaxed = true)
|
||||
private val setDatabaseCacheLimitUseCase: SetDatabaseCacheLimitUseCase = mockk(relaxed = true)
|
||||
private val setMeshLogSettingsUseCase: SetMeshLogSettingsUseCase = mockk(relaxed = true)
|
||||
private val meshLocationUseCase: MeshLocationUseCase = mockk(relaxed = true)
|
||||
private val exportDataUseCase: ExportDataUseCase = mockk(relaxed = true)
|
||||
private val isOtaCapableUseCase: IsOtaCapableUseCase = mockk(relaxed = true)
|
||||
private lateinit var setThemeUseCase: SetThemeUseCase
|
||||
private lateinit var setAppIntroCompletedUseCase: SetAppIntroCompletedUseCase
|
||||
private lateinit var setProvideLocationUseCase: SetProvideLocationUseCase
|
||||
private lateinit var setDatabaseCacheLimitUseCase: SetDatabaseCacheLimitUseCase
|
||||
private lateinit var setMeshLogSettingsUseCase: SetMeshLogSettingsUseCase
|
||||
private lateinit var meshLocationUseCase: MeshLocationUseCase
|
||||
private lateinit var exportDataUseCase: ExportDataUseCase
|
||||
private lateinit var isOtaCapableUseCase: IsOtaCapableUseCase
|
||||
|
||||
private lateinit var viewModel: SettingsViewModel
|
||||
|
||||
|
|
@ -73,6 +75,15 @@ class SettingsViewModelTest {
|
|||
fun setUp() {
|
||||
Dispatchers.setMain(testDispatcher)
|
||||
|
||||
setThemeUseCase = mockk(relaxed = true)
|
||||
setAppIntroCompletedUseCase = mockk(relaxed = true)
|
||||
setProvideLocationUseCase = mockk(relaxed = true)
|
||||
setDatabaseCacheLimitUseCase = mockk(relaxed = true)
|
||||
setMeshLogSettingsUseCase = mockk(relaxed = true)
|
||||
meshLocationUseCase = mockk(relaxed = true)
|
||||
exportDataUseCase = mockk(relaxed = true)
|
||||
isOtaCapableUseCase = mockk(relaxed = true)
|
||||
|
||||
// Return real StateFlows to avoid ClassCastException
|
||||
every { databaseManager.cacheLimit } returns MutableStateFlow(100)
|
||||
every { nodeRepository.myNodeInfo } returns MutableStateFlow(null)
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ import org.junit.Assert.assertEquals
|
|||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.meshtastic.core.data.repository.MeshLogRepository
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.prefs.meshlog.MeshLogPrefs
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.ui.util.AlertManager
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
|
|
|
|||
|
|
@ -23,12 +23,12 @@ import org.junit.Assert.assertEquals
|
|||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.meshtastic.core.prefs.filter.FilterPrefs
|
||||
import org.meshtastic.core.service.filter.MessageFilterService
|
||||
import org.meshtastic.core.repository.MessageFilter
|
||||
|
||||
class FilterSettingsViewModelTest {
|
||||
|
||||
private val filterPrefs: FilterPrefs = mockk(relaxed = true)
|
||||
private val messageFilterService: MessageFilterService = mockk(relaxed = true)
|
||||
private val messageFilter: MessageFilter = mockk(relaxed = true)
|
||||
|
||||
private lateinit var viewModel: FilterSettingsViewModel
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ class FilterSettingsViewModelTest {
|
|||
every { filterPrefs.filterEnabled } returns true
|
||||
every { filterPrefs.filterWords } returns setOf("apple", "banana")
|
||||
|
||||
viewModel = FilterSettingsViewModel(filterPrefs = filterPrefs, messageFilterService = messageFilterService)
|
||||
viewModel = FilterSettingsViewModel(filterPrefs = filterPrefs, messageFilter = messageFilter)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -52,7 +52,7 @@ class FilterSettingsViewModelTest {
|
|||
viewModel.addFilterWord("cherry")
|
||||
|
||||
verify { filterPrefs.filterWords = any() }
|
||||
verify { messageFilterService.rebuildPatterns() }
|
||||
verify { messageFilter.rebuildPatterns() }
|
||||
assertEquals(listOf("apple", "banana", "cherry"), viewModel.filterWords.value)
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ class FilterSettingsViewModelTest {
|
|||
viewModel.removeFilterWord("apple")
|
||||
|
||||
verify { filterPrefs.filterWords = any() }
|
||||
verify { messageFilterService.rebuildPatterns() }
|
||||
verify { messageFilter.rebuildPatterns() }
|
||||
assertEquals(listOf("banana"), viewModel.filterWords.value)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ import org.junit.After
|
|||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.domain.usecase.settings.CleanNodeDatabaseUseCase
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.ui.util.AlertManager
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
|
|
|
|||
|
|
@ -34,10 +34,6 @@ import org.junit.Assert.assertEquals
|
|||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.meshtastic.core.data.repository.LocationRepository
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.data.repository.PacketRepository
|
||||
import org.meshtastic.core.data.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.domain.usecase.settings.AdminActionsUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.ExportProfileUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.ExportSecurityConfigUseCase
|
||||
|
|
@ -48,10 +44,14 @@ import org.meshtastic.core.domain.usecase.settings.RadioConfigUseCase
|
|||
import org.meshtastic.core.domain.usecase.settings.RadioResponseResult
|
||||
import org.meshtastic.core.domain.usecase.settings.ToggleAnalyticsUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.ToggleHomoglyphEncodingUseCase
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.prefs.analytics.AnalyticsPrefs
|
||||
import org.meshtastic.core.prefs.homoglyph.HomoglyphPrefs
|
||||
import org.meshtastic.core.prefs.map.MapConsentPrefs
|
||||
import org.meshtastic.core.service.ServiceRepository
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.repository.PacketRepository
|
||||
import org.meshtastic.core.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.repository.ServiceRepository
|
||||
import org.meshtastic.proto.ChannelSet
|
||||
import org.meshtastic.proto.ChannelSettings
|
||||
import org.meshtastic.proto.Config
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue