shared: Add top app bar composable to reflect different active services
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
parent
42d6e83185
commit
a6bda1768e
11 changed files with 453 additions and 2 deletions
|
|
@ -157,7 +157,8 @@ pinterest-ktlint = { module = "com.pinterest.ktlint:ktlint-cli", version.ref = "
|
||||||
puppycrawl-checkstyle = { module = "com.puppycrawl.tools:checkstyle", version.ref = "checkstyle" }
|
puppycrawl-checkstyle = { module = "com.puppycrawl.tools:checkstyle", version.ref = "checkstyle" }
|
||||||
reactivex-rxandroid = { module = "io.reactivex.rxjava3:rxandroid", version.ref = "rxandroid" }
|
reactivex-rxandroid = { module = "io.reactivex.rxjava3:rxandroid", version.ref = "rxandroid" }
|
||||||
reactivex-rxjava = { module = "io.reactivex.rxjava3:rxjava", version.ref = "rxjava" }
|
reactivex-rxjava = { module = "io.reactivex.rxjava3:rxjava", version.ref = "rxjava" }
|
||||||
russhwolf-settings = { module = "com.russhwolf:multiplatform-settings", version.ref = "settings" }
|
russhwolf-settings-core = { module = "com.russhwolf:multiplatform-settings", version.ref = "settings" }
|
||||||
|
russhwolf-settings-test = { module = "com.russhwolf:multiplatform-settings-test", version.ref = "settings" }
|
||||||
squareup-leakcanary-core = { module = "com.squareup.leakcanary:leakcanary-android-core", version.ref = "leakcanary" }
|
squareup-leakcanary-core = { module = "com.squareup.leakcanary:leakcanary-android-core", version.ref = "leakcanary" }
|
||||||
squareup-leakcanary-plumber = { module = "com.squareup.leakcanary:plumber-android", version.ref = "leakcanary" }
|
squareup-leakcanary-plumber = { module = "com.squareup.leakcanary:plumber-android", version.ref = "leakcanary" }
|
||||||
squareup-leakcanary-watcher = { module = "com.squareup.leakcanary:leakcanary-object-watcher-android", version.ref = "leakcanary" }
|
squareup-leakcanary-watcher = { module = "com.squareup.leakcanary:leakcanary-object-watcher-android", version.ref = "leakcanary" }
|
||||||
|
|
|
||||||
|
|
@ -107,12 +107,13 @@ kotlin {
|
||||||
implementation(libs.koin.compose.viewmodel)
|
implementation(libs.koin.compose.viewmodel)
|
||||||
implementation(libs.koin.annotations)
|
implementation(libs.koin.annotations)
|
||||||
|
|
||||||
implementation(libs.russhwolf.settings)
|
implementation(libs.russhwolf.settings.core)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commonTest.dependencies {
|
commonTest.dependencies {
|
||||||
implementation(libs.kotlin.test.core)
|
implementation(libs.kotlin.test.core)
|
||||||
implementation(libs.jetbrains.compose.test.ui)
|
implementation(libs.jetbrains.compose.test.ui)
|
||||||
|
implementation(libs.russhwolf.settings.test)
|
||||||
}
|
}
|
||||||
androidMain.dependencies {
|
androidMain.dependencies {
|
||||||
implementation(libs.jetbrains.compose.preview)
|
implementation(libs.jetbrains.compose.preview)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ SPDX-FileCopyrightText: Material Design Authors / Google LLC
|
||||||
|
~ SPDX-License-Identifier: Apache-2.0
|
||||||
|
-->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?attr/colorControlNormal"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" />
|
||||||
|
</vector>
|
||||||
|
|
@ -5,4 +5,7 @@
|
||||||
-->
|
-->
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">NewPipe</string>
|
<string name="app_name">NewPipe</string>
|
||||||
|
|
||||||
|
<!-- TopAppBar -->
|
||||||
|
<string name="navigate_back">Back</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
10
shared/src/commonMain/kotlin/net/newpipe/app/Constants.kt
Normal file
10
shared/src/commonMain/kotlin/net/newpipe/app/Constants.kt
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 NewPipe e.V. <https://newpipe-ev.de>
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.newpipe.app
|
||||||
|
|
||||||
|
object Constants {
|
||||||
|
const val KEY_STREAMING_SERVICE = "service"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 NewPipe e.V. <https://newpipe-ev.de>
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.newpipe.app.composable
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.RowScope
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TopAppBar
|
||||||
|
import androidx.compose.material3.TopAppBarColors
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewWrapper
|
||||||
|
import net.newpipe.app.preview.ThemePreviewProvider
|
||||||
|
import net.newpipe.app.theme.currentServiceTopAppBarColors
|
||||||
|
import newpipe.shared.generated.resources.Res
|
||||||
|
import newpipe.shared.generated.resources.app_name
|
||||||
|
import newpipe.shared.generated.resources.ic_arrow_back
|
||||||
|
import newpipe.shared.generated.resources.navigate_back
|
||||||
|
import org.jetbrains.compose.resources.painterResource
|
||||||
|
import org.jetbrains.compose.resources.stringResource
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A top app bar composable to be used with Scaffold
|
||||||
|
* @param modifier The modifier to be applied to the composable
|
||||||
|
* @param title Title of the screen
|
||||||
|
* @param navigationIcon Icon for the navigation button
|
||||||
|
* @param onNavigateUp Action when user clicks the navigation icon
|
||||||
|
* @param actions Actions to display on the top app bar (for e.g. menu)
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun TopAppBar(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
title: String? = null,
|
||||||
|
navigationIcon: Painter = painterResource(Res.drawable.ic_arrow_back),
|
||||||
|
onNavigateUp: (() -> Unit)? = null,
|
||||||
|
colors: TopAppBarColors = currentServiceTopAppBarColors(),
|
||||||
|
actions: @Composable (RowScope.() -> Unit) = {}
|
||||||
|
) {
|
||||||
|
TopAppBar(
|
||||||
|
modifier = modifier,
|
||||||
|
colors = colors,
|
||||||
|
title = { if (title != null) Text(text = title) },
|
||||||
|
navigationIcon = {
|
||||||
|
if (onNavigateUp != null) {
|
||||||
|
IconButton(onClick = onNavigateUp) {
|
||||||
|
Icon(
|
||||||
|
painter = navigationIcon,
|
||||||
|
contentDescription = stringResource(Res.string.navigate_back)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions = actions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreviewWrapper(ThemePreviewProvider::class)
|
||||||
|
@PreviewLightDark
|
||||||
|
@Composable
|
||||||
|
private fun TopAppBarPreview() {
|
||||||
|
TopAppBar(
|
||||||
|
title = stringResource(Res.string.app_name),
|
||||||
|
onNavigateUp = {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 NewPipe e.V. <https://newpipe-ev.de>
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.newpipe.app.preview
|
||||||
|
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewWrapperProvider
|
||||||
|
import net.newpipe.app.theme.AppTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default preview provider for composables
|
||||||
|
*/
|
||||||
|
class ThemePreviewProvider : PreviewWrapperProvider {
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun Wrap(content: @Composable (() -> Unit)) {
|
||||||
|
AppTheme {
|
||||||
|
Surface(content = content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 NewPipe e.V. <https://newpipe-ev.de>
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.newpipe.app.theme
|
||||||
|
|
||||||
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
|
import androidx.compose.material3.ColorScheme
|
||||||
|
import androidx.compose.material3.TopAppBarColors
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
|
import androidx.compose.material3.darkColorScheme
|
||||||
|
import androidx.compose.material3.lightColorScheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalInspectionMode
|
||||||
|
import com.russhwolf.settings.Settings
|
||||||
|
import net.newpipe.app.Constants.KEY_STREAMING_SERVICE
|
||||||
|
import org.koin.compose.koinInject
|
||||||
|
|
||||||
|
val youTubeLightScheme = lightColorScheme(
|
||||||
|
primaryContainer = Color(0xFFE53935),
|
||||||
|
onPrimaryContainer = Color(0xFFFFFFFF)
|
||||||
|
)
|
||||||
|
|
||||||
|
val youTubeDarkScheme = darkColorScheme(
|
||||||
|
primaryContainer = Color(0xFF992722),
|
||||||
|
onPrimaryContainer = Color(0xFFFFFFFF)
|
||||||
|
)
|
||||||
|
|
||||||
|
val soundCloudLightScheme = lightColorScheme(
|
||||||
|
primaryContainer = Color(0xFFF57C00),
|
||||||
|
onPrimaryContainer = Color(0xFFFFFFFF)
|
||||||
|
)
|
||||||
|
|
||||||
|
val soundCloudDarkScheme = darkColorScheme(
|
||||||
|
primaryContainer = Color(0xFFA35300),
|
||||||
|
onPrimaryContainer = Color(0xFFFFFFFF)
|
||||||
|
)
|
||||||
|
|
||||||
|
val mediaCCCLightScheme = lightColorScheme(
|
||||||
|
primaryContainer = Color(0xFF9E9E9E),
|
||||||
|
onPrimaryContainer = Color(0xFFFFFFFF)
|
||||||
|
)
|
||||||
|
|
||||||
|
val mediaCCCDarkScheme = darkColorScheme(
|
||||||
|
primaryContainer = Color(0xFF878787),
|
||||||
|
onPrimaryContainer = Color(0xFFFFFFFF)
|
||||||
|
)
|
||||||
|
|
||||||
|
val peerTubeLightScheme = lightColorScheme(
|
||||||
|
primaryContainer = Color(0xFFFF6F00),
|
||||||
|
onPrimaryContainer = Color(0xFFFFFFFF)
|
||||||
|
)
|
||||||
|
|
||||||
|
val peerTubeDarkScheme = darkColorScheme(
|
||||||
|
primaryContainer = Color(0xFFA34700),
|
||||||
|
onPrimaryContainer = Color(0xFFFFFFFF)
|
||||||
|
)
|
||||||
|
|
||||||
|
val bandCampLightScheme = lightColorScheme(
|
||||||
|
primaryContainer = Color(0xFF17A0C4),
|
||||||
|
onPrimaryContainer = Color(0xFFFFFFFF)
|
||||||
|
)
|
||||||
|
|
||||||
|
val bandCampDarkScheme = darkColorScheme(
|
||||||
|
primaryContainer = Color(0xFF1383A1),
|
||||||
|
onPrimaryContainer = Color(0xFFFFFFFF)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supported services in the NewPipe app and minor information about them for UI decisions.
|
||||||
|
* @property serviceId ID of the service as defined in NewPipeExtractor
|
||||||
|
* @property serviceName Name of the service as defined in NewPipeExtractor
|
||||||
|
* @property lightScheme Light color scheme to reflect the brand
|
||||||
|
* @property darkScheme Dark color scheme to reflect the brand
|
||||||
|
* @property isSchemeColorDensityLight Whether this brand's color schemes are of lighter density.
|
||||||
|
*/
|
||||||
|
enum class Service(
|
||||||
|
val serviceId: Int,
|
||||||
|
val serviceName: String,
|
||||||
|
val lightScheme: ColorScheme,
|
||||||
|
val darkScheme: ColorScheme,
|
||||||
|
val isSchemeColorDensityLight: Boolean = false
|
||||||
|
) {
|
||||||
|
YOUTUBE(
|
||||||
|
serviceId = 0,
|
||||||
|
serviceName = "YouTube",
|
||||||
|
lightScheme = youTubeLightScheme,
|
||||||
|
darkScheme = youTubeDarkScheme
|
||||||
|
),
|
||||||
|
SOUNDCLOUD(
|
||||||
|
serviceId = 1,
|
||||||
|
serviceName = "SoundCloud",
|
||||||
|
lightScheme = soundCloudLightScheme,
|
||||||
|
darkScheme = soundCloudDarkScheme
|
||||||
|
),
|
||||||
|
MEDIA_CCC(
|
||||||
|
serviceId = 2,
|
||||||
|
serviceName = "media.ccc.de",
|
||||||
|
lightScheme = mediaCCCLightScheme,
|
||||||
|
darkScheme = mediaCCCDarkScheme
|
||||||
|
),
|
||||||
|
PEERTUBE(
|
||||||
|
serviceId = 3,
|
||||||
|
serviceName = "PeerTube",
|
||||||
|
lightScheme = peerTubeLightScheme,
|
||||||
|
darkScheme = peerTubeDarkScheme
|
||||||
|
),
|
||||||
|
BANDCAMP(
|
||||||
|
serviceId = 4,
|
||||||
|
serviceName = "Bandcamp",
|
||||||
|
lightScheme = bandCampLightScheme,
|
||||||
|
darkScheme = bandCampDarkScheme
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Currently active/selected service by user
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun currentService(settings: Settings = koinInject()): Service {
|
||||||
|
return Service.entries.find { service ->
|
||||||
|
service.serviceName == settings.getString(
|
||||||
|
KEY_STREAMING_SERVICE,
|
||||||
|
Service.YOUTUBE.serviceName
|
||||||
|
)
|
||||||
|
}!!
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Currently active/selected service's color that can be used to represent it.
|
||||||
|
* Fallbacks to YouTube on preview.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun currentServiceScheme(
|
||||||
|
isPreview: Boolean = LocalInspectionMode.current,
|
||||||
|
useDarkTheme: Boolean = isSystemInDarkTheme(),
|
||||||
|
service: Service = if (isPreview) Service.YOUTUBE else currentService()
|
||||||
|
): ColorScheme {
|
||||||
|
return when {
|
||||||
|
useDarkTheme -> service.darkScheme
|
||||||
|
else -> service.lightScheme
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Top app bar colors to represent the currently active service.
|
||||||
|
* Fallbacks to YouTube on preview.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun currentServiceTopAppBarColors(
|
||||||
|
serviceScheme: ColorScheme = currentServiceScheme()
|
||||||
|
): TopAppBarColors {
|
||||||
|
return TopAppBarDefaults.topAppBarColors(
|
||||||
|
containerColor = serviceScheme.primaryContainer,
|
||||||
|
scrolledContainerColor = serviceScheme.primaryContainer,
|
||||||
|
navigationIconContentColor = serviceScheme.onPrimaryContainer,
|
||||||
|
titleContentColor = serviceScheme.onPrimaryContainer,
|
||||||
|
subtitleContentColor = serviceScheme.onPrimaryContainer,
|
||||||
|
actionIconContentColor = serviceScheme.onPrimaryContainer
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 NewPipe e.V. <https://newpipe-ev.de>
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.newpipe.app.composable
|
||||||
|
|
||||||
|
import androidx.compose.ui.test.ExperimentalTestApi
|
||||||
|
import androidx.compose.ui.test.assertIsDisplayed
|
||||||
|
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||||
|
import androidx.compose.ui.test.onNodeWithText
|
||||||
|
import androidx.compose.ui.test.performClick
|
||||||
|
import androidx.compose.ui.test.v2.runComposeUiTest
|
||||||
|
import com.russhwolf.settings.MapSettings
|
||||||
|
import com.russhwolf.settings.Settings
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
import net.newpipe.app.extensions.withKoin
|
||||||
|
import newpipe.shared.generated.resources.Res
|
||||||
|
import newpipe.shared.generated.resources.app_name
|
||||||
|
import newpipe.shared.generated.resources.navigate_back
|
||||||
|
import org.jetbrains.compose.resources.getString
|
||||||
|
import org.jetbrains.compose.resources.stringResource
|
||||||
|
import org.koin.dsl.module
|
||||||
|
|
||||||
|
@OptIn(ExperimentalTestApi::class)
|
||||||
|
class TopAppBarTest {
|
||||||
|
|
||||||
|
private val emptySettings = module {
|
||||||
|
single<Settings> { MapSettings() }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testTopAppBarHasNoNavigationByDefault() = runComposeUiTest {
|
||||||
|
withKoin(
|
||||||
|
modules = listOf(emptySettings),
|
||||||
|
content = {
|
||||||
|
TopAppBar()
|
||||||
|
},
|
||||||
|
onContent = {
|
||||||
|
onNodeWithContentDescription(getString(Res.string.navigate_back))
|
||||||
|
.assertDoesNotExist()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testTopAppBarCanHaveNavigation() = runComposeUiTest {
|
||||||
|
var navigationBackClicked = false
|
||||||
|
withKoin(
|
||||||
|
modules = listOf(emptySettings),
|
||||||
|
content = {
|
||||||
|
TopAppBar(
|
||||||
|
title = stringResource(Res.string.app_name),
|
||||||
|
onNavigateUp = { navigationBackClicked = true }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onContent = {
|
||||||
|
onNodeWithText(getString(Res.string.app_name)).assertIsDisplayed()
|
||||||
|
onNodeWithContentDescription(getString(Res.string.navigate_back)).apply {
|
||||||
|
assertExists()
|
||||||
|
performClick()
|
||||||
|
assertTrue(navigationBackClicked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 NewPipe e.V. <https://newpipe-ev.de>
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.newpipe.app.extensions
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.test.ComposeUiTest
|
||||||
|
import androidx.compose.ui.test.ExperimentalTestApi
|
||||||
|
import org.koin.compose.KoinApplication
|
||||||
|
import org.koin.core.context.stopKoin
|
||||||
|
import org.koin.core.logger.Level
|
||||||
|
import org.koin.core.module.Module
|
||||||
|
import org.koin.dsl.koinConfiguration
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the content for the UI test wrapped inside Koin
|
||||||
|
* @param modules Modules for Koin to init for the composables
|
||||||
|
* @param content Composable content for testing
|
||||||
|
* @param onContent Non-composable code for testing, maybe dependent upon composable code
|
||||||
|
*/
|
||||||
|
@OptIn(ExperimentalTestApi::class)
|
||||||
|
inline fun ComposeUiTest.withKoin(
|
||||||
|
modules: List<Module>,
|
||||||
|
noinline content: @Composable () -> Unit = {},
|
||||||
|
onContent: () -> Unit = {}
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
setContent {
|
||||||
|
KoinApplication(
|
||||||
|
configuration = koinConfiguration {
|
||||||
|
modules(modules)
|
||||||
|
},
|
||||||
|
logLevel = Level.DEBUG,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
onContent()
|
||||||
|
} finally {
|
||||||
|
stopKoin()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 NewPipe e.V. <https://newpipe-ev.de>
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.newpipe.app.theme
|
||||||
|
|
||||||
|
import androidx.compose.ui.test.ExperimentalTestApi
|
||||||
|
import androidx.compose.ui.test.v2.runComposeUiTest
|
||||||
|
import com.russhwolf.settings.MapSettings
|
||||||
|
import com.russhwolf.settings.Settings
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNotEquals
|
||||||
|
import net.newpipe.app.Constants.KEY_STREAMING_SERVICE
|
||||||
|
import net.newpipe.app.extensions.withKoin
|
||||||
|
import org.koin.dsl.module
|
||||||
|
|
||||||
|
@OptIn(ExperimentalTestApi::class)
|
||||||
|
class ServiceThemeTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDefaultServiceIsYouTube() = runComposeUiTest {
|
||||||
|
val emptySettings = module {
|
||||||
|
single<Settings> { MapSettings() }
|
||||||
|
}
|
||||||
|
|
||||||
|
withKoin(
|
||||||
|
modules = listOf(emptySettings),
|
||||||
|
content = {
|
||||||
|
assertEquals(currentService(), Service.YOUTUBE)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testServiceSwitchingWorks() = runComposeUiTest {
|
||||||
|
val settings = module {
|
||||||
|
single<Settings> {
|
||||||
|
MapSettings(KEY_STREAMING_SERVICE to "PeerTube")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
withKoin(
|
||||||
|
modules = listOf(settings),
|
||||||
|
content = {
|
||||||
|
assertNotEquals(currentService(), Service.YOUTUBE)
|
||||||
|
assertEquals(currentService(), Service.PEERTUBE)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue