mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-11 23:39:15 +01:00
Compare commits
3
Commits
b2c66bf03e
...
fcfc5561ae
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcfc5561ae | ||
|
|
a562e4b316 | ||
|
|
538cb4177a |
@@ -174,6 +174,14 @@ class UserPreferences(
|
|||||||
|
|
||||||
private val replayGainPreampKey = floatPreferencesKey("replay_gain_preamp_db")
|
private val replayGainPreampKey = floatPreferencesKey("replay_gain_preamp_db")
|
||||||
|
|
||||||
|
fun keepScreenOn(): Flow<Boolean> = store.data.map { prefs -> prefs[keepScreenOnKey] ?: false }
|
||||||
|
|
||||||
|
suspend fun setKeepScreenOn(enabled: Boolean) {
|
||||||
|
store.edit { prefs -> prefs[keepScreenOnKey] = enabled }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val keepScreenOnKey = booleanPreferencesKey("keep_screen_on")
|
||||||
|
|
||||||
fun offlineMode(): Flow<Boolean> = store.data.map { prefs -> prefs[offlineModeKey] ?: false }
|
fun offlineMode(): Flow<Boolean> = store.data.map { prefs -> prefs[offlineModeKey] ?: false }
|
||||||
|
|
||||||
suspend fun setOfflineMode(enabled: Boolean) {
|
suspend fun setOfflineMode(enabled: Boolean) {
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
|
import androidx.compose.ui.keepScreenOn
|
||||||
import androidx.compose.ui.layout.onSizeChanged
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
@@ -76,6 +77,7 @@ import com.subtracks.R
|
|||||||
import com.subtracks.data.model.CoverArtRef
|
import com.subtracks.data.model.CoverArtRef
|
||||||
import com.subtracks.data.model.QueueKind
|
import com.subtracks.data.model.QueueKind
|
||||||
import com.subtracks.data.model.Song
|
import com.subtracks.data.model.Song
|
||||||
|
import com.subtracks.data.prefs.UserPreferences
|
||||||
import com.subtracks.data.repo.DownloadRepository
|
import com.subtracks.data.repo.DownloadRepository
|
||||||
import com.subtracks.data.repo.LibraryRepository
|
import com.subtracks.data.repo.LibraryRepository
|
||||||
import com.subtracks.data.source.StarType
|
import com.subtracks.data.source.StarType
|
||||||
@@ -191,8 +193,10 @@ fun NowPlayingRoute(
|
|||||||
controller: PlaybackController = koinInject(),
|
controller: PlaybackController = koinInject(),
|
||||||
libraryRepository: LibraryRepository = koinInject(),
|
libraryRepository: LibraryRepository = koinInject(),
|
||||||
downloadRepository: DownloadRepository = koinInject(),
|
downloadRepository: DownloadRepository = koinInject(),
|
||||||
|
userPreferences: UserPreferences = koinInject(),
|
||||||
) {
|
) {
|
||||||
val state by controller.state.collectAsStateWithLifecycle()
|
val state by controller.state.collectAsStateWithLifecycle()
|
||||||
|
val keepScreenOn by remember { userPreferences.keepScreenOn() }.collectAsStateWithLifecycle(initialValue = false)
|
||||||
val positionMs by controller.positionMs.collectAsStateWithLifecycle()
|
val positionMs by controller.positionMs.collectAsStateWithLifecycle()
|
||||||
val sourceId = state.context?.sourceId
|
val sourceId = state.context?.sourceId
|
||||||
val songId = state.item?.id
|
val songId = state.item?.id
|
||||||
@@ -272,6 +276,7 @@ fun NowPlayingRoute(
|
|||||||
starred = song?.starred != null,
|
starred = song?.starred != null,
|
||||||
onToggleStar = song?.let { s -> { setStar(StarType.Song, s.id, s.starred == null) } },
|
onToggleStar = song?.let { s -> { setStar(StarType.Song, s.id, s.starred == null) } },
|
||||||
onSeek = controller::seekTo,
|
onSeek = controller::seekTo,
|
||||||
|
keepScreenOn = keepScreenOn,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -290,6 +295,7 @@ fun NowPlayingScreen(
|
|||||||
onNext: () -> Unit,
|
onNext: () -> Unit,
|
||||||
onPrevious: () -> Unit,
|
onPrevious: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
keepScreenOn: Boolean = false,
|
||||||
onSkipPrevious: () -> Unit = onPrevious,
|
onSkipPrevious: () -> Unit = onPrevious,
|
||||||
onShuffle: () -> Unit = {},
|
onShuffle: () -> Unit = {},
|
||||||
onRepeat: () -> Unit = {},
|
onRepeat: () -> Unit = {},
|
||||||
@@ -366,7 +372,12 @@ fun NowPlayingScreen(
|
|||||||
|
|
||||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
|
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
|
||||||
ArtworkTheme(artwork) {
|
ArtworkTheme(artwork) {
|
||||||
Box(modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)) {
|
Box(
|
||||||
|
modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(MaterialTheme.colorScheme.background)
|
||||||
|
.then(if (keepScreenOn) Modifier.keepScreenOn() else Modifier),
|
||||||
|
) {
|
||||||
HeroGradient(
|
HeroGradient(
|
||||||
colors = artwork,
|
colors = artwork,
|
||||||
scrollPx = { 0f },
|
scrollPx = { 0f },
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ fun SettingsRoute(
|
|||||||
val downloadQuality by viewModel.downloadQuality.collectAsStateWithLifecycle()
|
val downloadQuality by viewModel.downloadQuality.collectAsStateWithLifecycle()
|
||||||
val downloadOverMetered by viewModel.downloadOverMetered.collectAsStateWithLifecycle()
|
val downloadOverMetered by viewModel.downloadOverMetered.collectAsStateWithLifecycle()
|
||||||
val scrobbling by viewModel.scrobbling.collectAsStateWithLifecycle()
|
val scrobbling by viewModel.scrobbling.collectAsStateWithLifecycle()
|
||||||
|
val keepScreenOn by viewModel.keepScreenOn.collectAsStateWithLifecycle()
|
||||||
val offline by viewModel.offline.collectAsStateWithLifecycle()
|
val offline by viewModel.offline.collectAsStateWithLifecycle()
|
||||||
val verboseLogging by viewModel.verboseLogging.collectAsStateWithLifecycle()
|
val verboseLogging by viewModel.verboseLogging.collectAsStateWithLifecycle()
|
||||||
val replayGainMode by viewModel.replayGainMode.collectAsStateWithLifecycle()
|
val replayGainMode by viewModel.replayGainMode.collectAsStateWithLifecycle()
|
||||||
@@ -142,6 +143,7 @@ fun SettingsRoute(
|
|||||||
scrobbling = scrobbling,
|
scrobbling = scrobbling,
|
||||||
replayGainMode = replayGainMode,
|
replayGainMode = replayGainMode,
|
||||||
replayGainPreamp = replayGainPreamp,
|
replayGainPreamp = replayGainPreamp,
|
||||||
|
keepScreenOn = keepScreenOn,
|
||||||
offline = offline,
|
offline = offline,
|
||||||
verboseLogging = verboseLogging,
|
verboseLogging = verboseLogging,
|
||||||
onSelectSource = viewModel::selectSource,
|
onSelectSource = viewModel::selectSource,
|
||||||
@@ -156,6 +158,7 @@ fun SettingsRoute(
|
|||||||
onScrobblingChange = viewModel::setScrobbling,
|
onScrobblingChange = viewModel::setScrobbling,
|
||||||
onReplayGainModeChange = viewModel::setReplayGainMode,
|
onReplayGainModeChange = viewModel::setReplayGainMode,
|
||||||
onReplayGainPreampChange = viewModel::setReplayGainPreamp,
|
onReplayGainPreampChange = viewModel::setReplayGainPreamp,
|
||||||
|
onKeepScreenOnChange = viewModel::setKeepScreenOn,
|
||||||
onOfflineChange = viewModel::setOfflineMode,
|
onOfflineChange = viewModel::setOfflineMode,
|
||||||
onVerboseLoggingChange = viewModel::setVerboseLogging,
|
onVerboseLoggingChange = viewModel::setVerboseLogging,
|
||||||
onAddServer = onAddServer,
|
onAddServer = onAddServer,
|
||||||
@@ -195,6 +198,7 @@ fun SettingsScreen(
|
|||||||
downloadOverMetered: Boolean,
|
downloadOverMetered: Boolean,
|
||||||
scrobbling: Boolean,
|
scrobbling: Boolean,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
keepScreenOn: Boolean = false,
|
||||||
offline: Boolean = false,
|
offline: Boolean = false,
|
||||||
verboseLogging: Boolean = false,
|
verboseLogging: Boolean = false,
|
||||||
syncMode: SyncMode = SyncMode.WifiOnly,
|
syncMode: SyncMode = SyncMode.WifiOnly,
|
||||||
@@ -213,6 +217,7 @@ fun SettingsScreen(
|
|||||||
onScrobblingChange: (Boolean) -> Unit,
|
onScrobblingChange: (Boolean) -> Unit,
|
||||||
onReplayGainModeChange: (ReplayGainMode) -> Unit = {},
|
onReplayGainModeChange: (ReplayGainMode) -> Unit = {},
|
||||||
onReplayGainPreampChange: (Float) -> Unit = {},
|
onReplayGainPreampChange: (Float) -> Unit = {},
|
||||||
|
onKeepScreenOnChange: (Boolean) -> Unit = {},
|
||||||
onOfflineChange: (Boolean) -> Unit = {},
|
onOfflineChange: (Boolean) -> Unit = {},
|
||||||
onVerboseLoggingChange: (Boolean) -> Unit = {},
|
onVerboseLoggingChange: (Boolean) -> Unit = {},
|
||||||
onAddServer: () -> Unit,
|
onAddServer: () -> Unit,
|
||||||
@@ -380,6 +385,26 @@ fun SettingsScreen(
|
|||||||
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
|
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
item {
|
||||||
|
ListItem(
|
||||||
|
headlineContent = { Text(stringResource(R.string.settings_music_options_keep_screen_on_title)) },
|
||||||
|
supportingContent = { Text(stringResource(R.string.settings_music_options_keep_screen_on_description)) },
|
||||||
|
trailingContent = {
|
||||||
|
Switch(
|
||||||
|
checked = keepScreenOn,
|
||||||
|
onCheckedChange = onKeepScreenOnChange,
|
||||||
|
colors =
|
||||||
|
SwitchDefaults.colors(
|
||||||
|
uncheckedThumbColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
uncheckedTrackColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
uncheckedBorderColor = MaterialTheme.colorScheme.outline,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.clickable { onKeepScreenOnChange(!keepScreenOn) },
|
||||||
|
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
|
||||||
|
)
|
||||||
|
}
|
||||||
item { SectionHeader(stringResource(R.string.downloads_title)) }
|
item { SectionHeader(stringResource(R.string.downloads_title)) }
|
||||||
item {
|
item {
|
||||||
ListItem(
|
ListItem(
|
||||||
|
|||||||
@@ -76,6 +76,11 @@ class SettingsViewModel(
|
|||||||
.replayGainPreampDb()
|
.replayGainPreampDb()
|
||||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), 0f)
|
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), 0f)
|
||||||
|
|
||||||
|
val keepScreenOn: StateFlow<Boolean> =
|
||||||
|
userPreferences
|
||||||
|
.keepScreenOn()
|
||||||
|
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), false)
|
||||||
|
|
||||||
val offline: StateFlow<Boolean> = sourceRepository.offline
|
val offline: StateFlow<Boolean> = sourceRepository.offline
|
||||||
|
|
||||||
val verboseLogging: StateFlow<Boolean> =
|
val verboseLogging: StateFlow<Boolean> =
|
||||||
@@ -134,4 +139,8 @@ class SettingsViewModel(
|
|||||||
fun setReplayGainPreamp(value: Float) {
|
fun setReplayGainPreamp(value: Float) {
|
||||||
viewModelScope.launch { userPreferences.setReplayGainPreampDb(value) }
|
viewModelScope.launch { userPreferences.setReplayGainPreampDb(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setKeepScreenOn(enabled: Boolean) {
|
||||||
|
viewModelScope.launch { userPreferences.setKeepScreenOn(enabled) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,6 +85,8 @@
|
|||||||
<string name="settings_replay_gain_preamp_value">%1$s dB</string>
|
<string name="settings_replay_gain_preamp_value">%1$s dB</string>
|
||||||
<string name="settings_replay_gain_prompt">Normalise loudness using the ReplayGain tags from the server</string>
|
<string name="settings_replay_gain_prompt">Normalise loudness using the ReplayGain tags from the server</string>
|
||||||
<string name="settings_replay_gain_title">ReplayGain</string>
|
<string name="settings_replay_gain_title">ReplayGain</string>
|
||||||
|
<string name="settings_music_options_keep_screen_on_description">Keep the screen on while now playing is open</string>
|
||||||
|
<string name="settings_music_options_keep_screen_on_title">Keep screen on</string>
|
||||||
<string name="settings_network_name">Network</string>
|
<string name="settings_network_name">Network</string>
|
||||||
<string name="settings_network_options_max_bitrate_mobile_title">Stream quality: Mobile</string>
|
<string name="settings_network_options_max_bitrate_mobile_title">Stream quality: Mobile</string>
|
||||||
<string name="settings_network_options_max_bitrate_wifi_title">Stream quality: Wi-Fi</string>
|
<string name="settings_network_options_max_bitrate_wifi_title">Stream quality: Wi-Fi</string>
|
||||||
|
|||||||
@@ -155,6 +155,24 @@ class UserPreferencesTest {
|
|||||||
file.delete()
|
file.delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun keepScreenOnDefaultsOffAndRoundTrips() =
|
||||||
|
runTest {
|
||||||
|
val file = File.createTempFile("user-prefs", ".preferences_pb").apply { delete() }
|
||||||
|
val store = PreferenceDataStoreFactory.create(scope = backgroundScope) { file }
|
||||||
|
val prefs = UserPreferences(store)
|
||||||
|
|
||||||
|
assertEquals(false, prefs.keepScreenOn().first())
|
||||||
|
|
||||||
|
prefs.setKeepScreenOn(true)
|
||||||
|
assertEquals(true, prefs.keepScreenOn().first())
|
||||||
|
|
||||||
|
prefs.setKeepScreenOn(false)
|
||||||
|
assertEquals(false, prefs.keepScreenOn().first())
|
||||||
|
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun lastSeedRoundTripsWithAndWithoutASecondary() =
|
fun lastSeedRoundTripsWithAndWithoutASecondary() =
|
||||||
runTest {
|
runTest {
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package com.subtracks.ui.playback
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.test.junit4.v2.createAndroidComposeRule
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.subtracks.data.model.CoverArtRef
|
||||||
|
import com.subtracks.playback.PlaybackState
|
||||||
|
import com.subtracks.playback.QueueItem
|
||||||
|
import com.subtracks.ui.theme.SubtracksTheme
|
||||||
|
import com.subtracks.ui.theme.artworkColorsFromSeed
|
||||||
|
import org.junit.Assert.assertNotNull
|
||||||
|
import org.junit.Assert.assertNull
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.robolectric.annotation.GraphicsMode
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||||
|
class NowPlayingKeepScreenOnTest {
|
||||||
|
@get:Rule
|
||||||
|
val composeRule = createAndroidComposeRule<ComponentActivity>()
|
||||||
|
|
||||||
|
private val state =
|
||||||
|
PlaybackState(
|
||||||
|
item =
|
||||||
|
QueueItem(
|
||||||
|
id = "s-eiirp",
|
||||||
|
title = "Everything In Its Right Place",
|
||||||
|
artist = "Radiohead",
|
||||||
|
album = "Kid A",
|
||||||
|
coverArtId = "art-al-kid-a",
|
||||||
|
),
|
||||||
|
isPlaying = true,
|
||||||
|
durationMs = 251_000,
|
||||||
|
hasNext = true,
|
||||||
|
hasPrevious = false,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun theScreenOnFlagTracksTheSetting() {
|
||||||
|
var keepScreenOn by mutableStateOf(true)
|
||||||
|
composeRule.setContent {
|
||||||
|
SubtracksTheme {
|
||||||
|
NowPlayingScreen(
|
||||||
|
state = state,
|
||||||
|
positionMs = 62_000,
|
||||||
|
title = "Kid A",
|
||||||
|
coverArt = CoverArtRef("art-al-kid-a", "test:art-al-kid-a"),
|
||||||
|
artwork = artworkColorsFromSeed(android.graphics.Color.rgb(120, 80, 200)),
|
||||||
|
onBack = {},
|
||||||
|
onQueue = {},
|
||||||
|
onPlayPause = {},
|
||||||
|
onNext = {},
|
||||||
|
onPrevious = {},
|
||||||
|
onSeek = {},
|
||||||
|
keepScreenOn = keepScreenOn,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
composeRule.waitForIdle()
|
||||||
|
assertNotNull("now playing should hold the screen on", viewHoldingTheScreenOn())
|
||||||
|
|
||||||
|
composeRule.runOnIdle { keepScreenOn = false }
|
||||||
|
composeRule.waitForIdle()
|
||||||
|
assertNull("clearing the setting should release the screen-on flag", viewHoldingTheScreenOn())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun viewHoldingTheScreenOn(): View? = findKeepingScreenOn(composeRule.activity.window.decorView)
|
||||||
|
|
||||||
|
private fun findKeepingScreenOn(view: View): View? {
|
||||||
|
if (view.keepScreenOn) return view
|
||||||
|
if (view is ViewGroup) {
|
||||||
|
for (index in 0 until view.childCount) {
|
||||||
|
findKeepingScreenOn(view.getChildAt(index))?.let { return it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
package com.subtracks.ui.settings
|
||||||
|
|
||||||
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.compose.ui.test.hasAnySibling
|
||||||
|
import androidx.compose.ui.test.hasScrollToNodeAction
|
||||||
|
import androidx.compose.ui.test.hasText
|
||||||
|
import androidx.compose.ui.test.isToggleable
|
||||||
|
import androidx.compose.ui.test.junit4.v2.createAndroidComposeRule
|
||||||
|
import androidx.compose.ui.test.onAllNodesWithText
|
||||||
|
import androidx.compose.ui.test.onNodeWithText
|
||||||
|
import androidx.compose.ui.test.performClick
|
||||||
|
import androidx.compose.ui.test.performScrollToNode
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.github.takahirom.roborazzi.RobolectricDeviceQualifiers
|
||||||
|
import com.subtracks.data.prefs.StreamQuality
|
||||||
|
import com.subtracks.ui.theme.SubtracksTheme
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.robolectric.annotation.Config
|
||||||
|
import org.robolectric.annotation.GraphicsMode
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||||
|
@Config(qualifiers = RobolectricDeviceQualifiers.PixelXL)
|
||||||
|
class SettingsScreenTest {
|
||||||
|
@get:Rule
|
||||||
|
val composeRule = createAndroidComposeRule<ComponentActivity>()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun theKeepScreenOnRowTurnsTheSettingOn() {
|
||||||
|
var requested: Boolean? = null
|
||||||
|
renderSettings(keepScreenOn = false) { requested = it }
|
||||||
|
|
||||||
|
composeRule.onNodeWithText("Keep screen on").performClick()
|
||||||
|
composeRule.waitForIdle()
|
||||||
|
|
||||||
|
assertEquals(true, requested)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun theKeepScreenOnRowTurnsTheSettingOff() {
|
||||||
|
var requested: Boolean? = null
|
||||||
|
renderSettings(keepScreenOn = true) { requested = it }
|
||||||
|
|
||||||
|
composeRule.onNodeWithText("Keep screen on").performClick()
|
||||||
|
composeRule.waitForIdle()
|
||||||
|
|
||||||
|
assertEquals(false, requested)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun theKeepScreenOnSwitchTurnsTheSettingOn() {
|
||||||
|
var requested: Boolean? = null
|
||||||
|
renderSettings(keepScreenOn = false) { requested = it }
|
||||||
|
|
||||||
|
composeRule
|
||||||
|
.onNode(isToggleable() and hasAnySibling(hasText("Keep screen on")), useUnmergedTree = true)
|
||||||
|
.performClick()
|
||||||
|
composeRule.waitForIdle()
|
||||||
|
|
||||||
|
assertEquals(true, requested)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderSettings(
|
||||||
|
keepScreenOn: Boolean,
|
||||||
|
onKeepScreenOnChange: (Boolean) -> Unit,
|
||||||
|
) {
|
||||||
|
composeRule.setContent {
|
||||||
|
SubtracksTheme {
|
||||||
|
SettingsScreen(
|
||||||
|
sources = emptyList(),
|
||||||
|
activeSourceId = null,
|
||||||
|
wifiQuality = StreamQuality(),
|
||||||
|
mobileQuality = StreamQuality(),
|
||||||
|
syncConcurrency = 1,
|
||||||
|
downloadQuality = StreamQuality(),
|
||||||
|
downloadOverMetered = false,
|
||||||
|
scrobbling = false,
|
||||||
|
keepScreenOn = keepScreenOn,
|
||||||
|
onSelectSource = {},
|
||||||
|
onEditServer = {},
|
||||||
|
onWifiQualityChange = {},
|
||||||
|
onMobileQualityChange = {},
|
||||||
|
onSyncConcurrencyChange = {},
|
||||||
|
onDownloadQualityChange = {},
|
||||||
|
onDownloadOverMeteredChange = {},
|
||||||
|
onScrobblingChange = {},
|
||||||
|
onKeepScreenOnChange = onKeepScreenOnChange,
|
||||||
|
onAddServer = {},
|
||||||
|
onOpenDownloads = {},
|
||||||
|
onOpenLicenses = {},
|
||||||
|
onShareLogs = {},
|
||||||
|
onBack = {},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
awaitText("Add server")
|
||||||
|
composeRule.onNode(hasScrollToNodeAction()).performScrollToNode(hasText("Keep screen on"))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun awaitText(text: String) {
|
||||||
|
composeRule.waitUntil(timeoutMillis = 5_000) {
|
||||||
|
composeRule.onAllNodesWithText(text).fetchSemanticsNodes().isNotEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user