mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-08-09 08:27:54 +00:00
feat: local db switch for development
This commit is contained in:
parent
611b934000
commit
69f0dab65e
13 changed files with 309 additions and 14 deletions
|
|
@ -40,6 +40,9 @@ abstract class GenerateRuntimeConfigsTask : DefaultTask() {
|
|||
@get:Input
|
||||
abstract val syncBackendManifestUrl: Property<String>
|
||||
|
||||
@get:Input
|
||||
abstract val debugBuild: Property<Boolean>
|
||||
|
||||
@TaskAction
|
||||
fun generate() {
|
||||
val props = Properties()
|
||||
|
|
@ -140,6 +143,15 @@ abstract class GenerateRuntimeConfigsTask : DefaultTask() {
|
|||
|}
|
||||
""".trimMargin()
|
||||
)
|
||||
resolve("AppBuildConfig.kt").writeText(
|
||||
"""
|
||||
|package com.nuvio.app.core.build
|
||||
|
|
||||
|object AppBuildConfig {
|
||||
| const val IS_DEBUG_BUILD = ${debugBuild.get()}
|
||||
|}
|
||||
""".trimMargin()
|
||||
)
|
||||
}
|
||||
|
||||
outDir.resolve("com/nuvio/app/features/settings").apply {
|
||||
|
|
@ -256,6 +268,35 @@ fun runtimeConfigValue(key: String, fallback: String = ""): String =
|
|||
?: providers.environmentVariable(key).orNull?.trim()?.takeIf { it.isNotBlank() }
|
||||
?: fallback
|
||||
|
||||
fun booleanConfigValue(key: String): Boolean? {
|
||||
val rawValue = runtimeLocalProperties.getProperty(key)
|
||||
?: providers.environmentVariable(key).orNull
|
||||
?: providers.gradleProperty(key).orNull
|
||||
return rawValue
|
||||
?.trim()
|
||||
?.lowercase()
|
||||
?.let { value ->
|
||||
when (value) {
|
||||
"1", "true", "yes", "y", "debug" -> true
|
||||
"0", "false", "no", "n", "release" -> false
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val xcodeConfiguration = providers.environmentVariable("CONFIGURATION").orNull
|
||||
?.trim()
|
||||
?.lowercase()
|
||||
val kotlinFrameworkBuildType = providers.environmentVariable("KOTLIN_FRAMEWORK_BUILD_TYPE").orNull
|
||||
?.trim()
|
||||
?.lowercase()
|
||||
val inferredDebugBuild = requestedGradleTasks.any { "debug" in it } ||
|
||||
xcodeConfiguration == "debug" ||
|
||||
kotlinFrameworkBuildType == "debug"
|
||||
val isDebugBuild = booleanConfigValue("NUVIO_DEBUG_BUILD")
|
||||
?: booleanConfigValue("nuvio.debugBuild")
|
||||
?: inferredDebugBuild
|
||||
|
||||
val generateRuntimeConfigs = tasks.register<GenerateRuntimeConfigsTask>("generateRuntimeConfigs") {
|
||||
outputDir.set(generatedRuntimeConfigDir)
|
||||
localPropertiesFile.set(rootProject.layout.projectDirectory.file("local.properties"))
|
||||
|
|
@ -266,6 +307,7 @@ val generateRuntimeConfigs = tasks.register<GenerateRuntimeConfigsTask>("generat
|
|||
nuvioSupabaseUrl.set(runtimeConfigValue("NUVIO_SUPABASE_URL"))
|
||||
nuvioSupabaseAnonKey.set(runtimeConfigValue("NUVIO_SUPABASE_ANON_KEY"))
|
||||
syncBackendManifestUrl.set(runtimeConfigValue("SYNC_BACKEND_MANIFEST_URL"))
|
||||
debugBuild.set(isDebugBuild)
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompilationTask<*>>().configureEach {
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ actual object AppFeaturePolicy {
|
|||
actual val heroTrailerPlaybackSupported: Boolean = true
|
||||
actual val inAppUpdaterEnabled: Boolean = true
|
||||
actual val imdbRatingLogoEnabled: Boolean = true
|
||||
actual val debugBackendSwitcherEnabled: Boolean = AppBuildConfig.IS_DEBUG_BUILD
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ actual object AppFeaturePolicy {
|
|||
actual val heroTrailerPlaybackSupported: Boolean = false
|
||||
actual val inAppUpdaterEnabled: Boolean = false
|
||||
actual val imdbRatingLogoEnabled: Boolean = false
|
||||
actual val debugBackendSwitcherEnabled: Boolean = AppBuildConfig.IS_DEBUG_BUILD
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
<string name="action_retry">Retry</string>
|
||||
<string name="action_save">Save</string>
|
||||
<string name="action_saving">Saving…</string>
|
||||
<string name="action_switch">Switch</string>
|
||||
<string name="action_validate">Validate</string>
|
||||
<string name="addon_installing">Installing</string>
|
||||
<string name="addon_title">Addons</string>
|
||||
|
|
@ -533,6 +534,8 @@
|
|||
<string name="settings_account_status_anonymous">Anonymous</string>
|
||||
<string name="settings_account_status_signed_in">Signed in</string>
|
||||
<string name="settings_account_sync_backend">Sync backend</string>
|
||||
<string name="debug_backend_switch_confirm_title">Switch backend?</string>
|
||||
<string name="debug_backend_switch_confirm_message">Switch to %1$s and sign out? You can sign in again on the selected backend.</string>
|
||||
<string name="settings_appearance_amoled_black">AMOLED Black</string>
|
||||
<string name="settings_appearance_amoled_description">Use pure black backgrounds for OLED screens.</string>
|
||||
<string name="settings_appearance_app_language">App Language</string>
|
||||
|
|
|
|||
|
|
@ -12,4 +12,5 @@ expect object AppFeaturePolicy {
|
|||
val heroTrailerPlaybackSupported: Boolean
|
||||
val inAppUpdaterEnabled: Boolean
|
||||
val imdbRatingLogoEnabled: Boolean
|
||||
val debugBackendSwitcherEnabled: Boolean
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ data class SyncBackendState(
|
|||
val appliedRevision: String = "",
|
||||
val isLoaded: Boolean = false,
|
||||
val lastManifestError: String? = null,
|
||||
val isManualDebugOverride: Boolean = false,
|
||||
)
|
||||
|
||||
sealed interface SyncBackendRefreshResult {
|
||||
|
|
@ -68,6 +69,7 @@ internal data class StoredSyncBackendSelection(
|
|||
val backend: SyncBackendConfig? = null,
|
||||
val backendId: String = "",
|
||||
val appliedRevision: String = "",
|
||||
val manualDebugOverride: Boolean = false,
|
||||
)
|
||||
|
||||
object SyncBackendDefaults {
|
||||
|
|
@ -113,7 +115,7 @@ internal fun SyncBackendManifest.backendConfigForActiveBackend(): SyncBackendCon
|
|||
?.takeIf { it.isUsableClientConfig() }
|
||||
}
|
||||
|
||||
private fun SyncBackendConfig.isUsableClientConfig(): Boolean =
|
||||
internal fun SyncBackendConfig.isUsableClientConfig(): Boolean =
|
||||
id in setOf(SYNC_BACKEND_HOSTED_ID, SYNC_BACKEND_NUVIO_ID) &&
|
||||
normalizedSupabaseUrl.startsWith("https://") &&
|
||||
anonKey.isNotBlank() &&
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.nuvio.app.core.network
|
||||
|
||||
import co.touchlab.kermit.Logger
|
||||
import com.nuvio.app.core.build.AppFeaturePolicy
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
|
@ -35,23 +36,37 @@ object SyncBackendRepository {
|
|||
.getOrNull()
|
||||
}
|
||||
|
||||
val backend = storedSelection
|
||||
?.let { selection ->
|
||||
selection.backendId.ifBlank { selection.backend?.id.orEmpty() }
|
||||
}
|
||||
?.let(SyncBackendDefaults::byId)
|
||||
?: SyncBackendDefaults.hosted()
|
||||
val storedManualDebugOverride = storedSelection?.manualDebugOverride == true
|
||||
val backend = if (storedManualDebugOverride && !AppFeaturePolicy.debugBackendSwitcherEnabled) {
|
||||
SyncBackendDefaults.hosted()
|
||||
} else {
|
||||
storedSelection
|
||||
?.let { selection ->
|
||||
selection.backendId.ifBlank { selection.backend?.id.orEmpty() }
|
||||
}
|
||||
?.let(SyncBackendDefaults::byId)
|
||||
?: SyncBackendDefaults.hosted()
|
||||
}
|
||||
|
||||
_state.value = SyncBackendState(
|
||||
selectedBackend = backend,
|
||||
appliedRevision = storedSelection?.appliedRevision.orEmpty(),
|
||||
appliedRevision = if (storedManualDebugOverride && !AppFeaturePolicy.debugBackendSwitcherEnabled) {
|
||||
""
|
||||
} else {
|
||||
storedSelection?.appliedRevision.orEmpty()
|
||||
},
|
||||
isLoaded = true,
|
||||
isManualDebugOverride = storedManualDebugOverride && AppFeaturePolicy.debugBackendSwitcherEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun refreshFromManifest(): SyncBackendRefreshResult {
|
||||
ensureLoaded()
|
||||
|
||||
if (_state.value.isManualDebugOverride && AppFeaturePolicy.debugBackendSwitcherEnabled) {
|
||||
return SyncBackendRefreshResult.Unchanged
|
||||
}
|
||||
|
||||
val manifestUrl = SyncBackendBootstrapConfig.SWITCH_MANIFEST_URL.trim()
|
||||
if (manifestUrl.isBlank()) {
|
||||
return SyncBackendRefreshResult.NotConfigured
|
||||
|
|
@ -97,19 +112,40 @@ object SyncBackendRepository {
|
|||
revision: String,
|
||||
): SyncBackendConfig {
|
||||
val normalizedBackend = backend.normalized()
|
||||
saveSelection(normalizedBackend, revision)
|
||||
saveSelection(normalizedBackend, revision, manualDebugOverride = false)
|
||||
return normalizedBackend
|
||||
}
|
||||
|
||||
fun debugSelectableBackends(): List<SyncBackendConfig> =
|
||||
listOf(SyncBackendDefaults.hosted(), SyncBackendDefaults.nuvio())
|
||||
.filter { backend -> backend.isUsableClientConfig() }
|
||||
|
||||
fun applyDebugBackendAfterLogout(backend: SyncBackendConfig): SyncBackendConfig? {
|
||||
if (!AppFeaturePolicy.debugBackendSwitcherEnabled) return null
|
||||
|
||||
val normalizedBackend = backend.normalized()
|
||||
.takeIf { it.isUsableClientConfig() }
|
||||
?: return null
|
||||
|
||||
saveSelection(
|
||||
backend = normalizedBackend,
|
||||
revision = DEBUG_MANUAL_REVISION,
|
||||
manualDebugOverride = true,
|
||||
)
|
||||
return normalizedBackend
|
||||
}
|
||||
|
||||
private fun saveSelection(
|
||||
backend: SyncBackendConfig,
|
||||
revision: String,
|
||||
manualDebugOverride: Boolean = false,
|
||||
) {
|
||||
val normalizedBackend = backend.normalized()
|
||||
val payload = json.encodeToString(
|
||||
StoredSyncBackendSelection(
|
||||
backendId = normalizedBackend.id,
|
||||
appliedRevision = revision,
|
||||
manualDebugOverride = manualDebugOverride,
|
||||
),
|
||||
)
|
||||
SyncBackendStorage.saveSelectionPayload(payload)
|
||||
|
|
@ -117,6 +153,9 @@ object SyncBackendRepository {
|
|||
selectedBackend = normalizedBackend,
|
||||
appliedRevision = revision,
|
||||
isLoaded = true,
|
||||
isManualDebugOverride = manualDebugOverride,
|
||||
)
|
||||
}
|
||||
|
||||
private const val DEBUG_MANUAL_REVISION = "debug-manual"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ import com.nuvio.app.core.auth.AuthRepository
|
|||
import com.nuvio.app.core.ui.nuvioOverlayGradientBrush
|
||||
import com.nuvio.app.core.ui.NuvioPrimaryButton
|
||||
import com.nuvio.app.core.ui.NuvioSurfaceCard
|
||||
import com.nuvio.app.features.dev.DebugSyncBackendSwitch
|
||||
import com.nuvio.app.features.dev.shouldShowDebugSyncBackendSwitch
|
||||
import kotlinx.coroutines.launch
|
||||
import nuvio.composeapp.generated.resources.Res
|
||||
import nuvio.composeapp.generated.resources.app_logo_wordmark
|
||||
|
|
@ -157,6 +159,15 @@ fun AuthScreen(
|
|||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
|
||||
if (shouldShowDebugSyncBackendSwitch()) {
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
DebugSyncBackendSwitch(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
requireConfirmation = false,
|
||||
container = true,
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(48.dp))
|
||||
|
||||
NuvioSurfaceCard {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,182 @@
|
|||
package com.nuvio.app.features.dev
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.SwitchDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.nuvio.app.core.auth.AuthRepository
|
||||
import com.nuvio.app.core.build.AppFeaturePolicy
|
||||
import com.nuvio.app.core.network.NetworkStatusRepository
|
||||
import com.nuvio.app.core.network.SYNC_BACKEND_HOSTED_ID
|
||||
import com.nuvio.app.core.network.SYNC_BACKEND_NUVIO_ID
|
||||
import com.nuvio.app.core.network.SupabaseProvider
|
||||
import com.nuvio.app.core.network.SyncBackendConfig
|
||||
import com.nuvio.app.core.network.SyncBackendRepository
|
||||
import com.nuvio.app.core.network.hasSameConnectionIdentity
|
||||
import com.nuvio.app.core.ui.NuvioStatusModal
|
||||
import com.nuvio.app.core.ui.NuvioTokens
|
||||
import com.nuvio.app.core.ui.nuvio
|
||||
import kotlinx.coroutines.launch
|
||||
import nuvio.composeapp.generated.resources.Res
|
||||
import nuvio.composeapp.generated.resources.action_cancel
|
||||
import nuvio.composeapp.generated.resources.action_switch
|
||||
import nuvio.composeapp.generated.resources.debug_backend_switch_confirm_message
|
||||
import nuvio.composeapp.generated.resources.debug_backend_switch_confirm_title
|
||||
import nuvio.composeapp.generated.resources.settings_account_sync_backend
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
|
||||
internal fun shouldShowDebugSyncBackendSwitch(): Boolean =
|
||||
AppFeaturePolicy.debugBackendSwitcherEnabled &&
|
||||
SyncBackendRepository.debugSelectableBackends().size >= 2
|
||||
|
||||
@Composable
|
||||
internal fun DebugSyncBackendSwitch(
|
||||
modifier: Modifier = Modifier,
|
||||
requireConfirmation: Boolean,
|
||||
container: Boolean = false,
|
||||
) {
|
||||
if (!shouldShowDebugSyncBackendSwitch()) return
|
||||
|
||||
val backendState by SyncBackendRepository.state.collectAsStateWithLifecycle()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val selectableBackends = remember { SyncBackendRepository.debugSelectableBackends() }
|
||||
val hostedBackend = selectableBackends.firstOrNull { backend -> backend.id == SYNC_BACKEND_HOSTED_ID }
|
||||
?: return
|
||||
val nuvioBackend = selectableBackends.firstOrNull { backend -> backend.id == SYNC_BACKEND_NUVIO_ID }
|
||||
?: return
|
||||
val selectedBackend = backendState.selectedBackend
|
||||
val nuvioSelected = selectedBackend.id == SYNC_BACKEND_NUVIO_ID
|
||||
val targetBackend = if (nuvioSelected) hostedBackend else nuvioBackend
|
||||
val tokens = MaterialTheme.nuvio
|
||||
var pendingBackend by remember { mutableStateOf<SyncBackendConfig?>(null) }
|
||||
var isSwitching by remember { mutableStateOf(false) }
|
||||
|
||||
fun switchToBackend(backend: SyncBackendConfig) {
|
||||
if (isSwitching || selectedBackend.hasSameConnectionIdentity(backend)) return
|
||||
|
||||
isSwitching = true
|
||||
coroutineScope.launch {
|
||||
AuthRepository.resetForSyncBackendChange()
|
||||
.onSuccess {
|
||||
val appliedBackend = SyncBackendRepository.applyDebugBackendAfterLogout(backend)
|
||||
if (appliedBackend != null) {
|
||||
SupabaseProvider.rebuildClient()
|
||||
NetworkStatusRepository.requestRefresh(force = true)
|
||||
}
|
||||
}
|
||||
pendingBackend = null
|
||||
isSwitching = false
|
||||
}
|
||||
}
|
||||
|
||||
fun requestBackendSwitch(backend: SyncBackendConfig) {
|
||||
if (selectedBackend.hasSameConnectionIdentity(backend)) return
|
||||
|
||||
if (requireConfirmation) {
|
||||
pendingBackend = backend
|
||||
} else {
|
||||
switchToBackend(backend)
|
||||
}
|
||||
}
|
||||
|
||||
val content: @Composable () -> Unit = {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(enabled = !isSwitching) { requestBackendSwitch(targetBackend) }
|
||||
.padding(horizontal = 16.dp, vertical = 14.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
verticalArrangement = Arrangement.spacedBy(3.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(Res.string.settings_account_sync_backend),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = tokens.colors.textMuted,
|
||||
)
|
||||
Text(
|
||||
text = selectedBackend.displayName,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = tokens.colors.textPrimary,
|
||||
fontWeight = FontWeight.Medium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
if (isSwitching) {
|
||||
CircularProgressIndicator(
|
||||
color = tokens.colors.accent,
|
||||
strokeWidth = NuvioTokens.Border.medium,
|
||||
)
|
||||
} else {
|
||||
Switch(
|
||||
checked = nuvioSelected,
|
||||
onCheckedChange = { checked ->
|
||||
requestBackendSwitch(if (checked) nuvioBackend else hostedBackend)
|
||||
},
|
||||
colors = SwitchDefaults.colors(
|
||||
checkedThumbColor = tokens.colors.onAccent,
|
||||
checkedTrackColor = tokens.colors.accent,
|
||||
uncheckedThumbColor = tokens.colors.textMuted,
|
||||
uncheckedTrackColor = tokens.colors.borderDefault,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (container) {
|
||||
Surface(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
color = tokens.colors.surface,
|
||||
shape = tokens.shapes.compactCard,
|
||||
border = BorderStroke(tokens.borders.hairline, tokens.colors.borderSubtle),
|
||||
) {
|
||||
content()
|
||||
}
|
||||
} else {
|
||||
Row(modifier = modifier.fillMaxWidth()) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
||||
pendingBackend?.let { backend ->
|
||||
NuvioStatusModal(
|
||||
title = stringResource(Res.string.debug_backend_switch_confirm_title),
|
||||
message = stringResource(
|
||||
Res.string.debug_backend_switch_confirm_message,
|
||||
backend.displayName,
|
||||
),
|
||||
isVisible = true,
|
||||
isBusy = isSwitching,
|
||||
confirmText = stringResource(Res.string.action_switch),
|
||||
dismissText = stringResource(Res.string.action_cancel),
|
||||
onConfirm = { switchToBackend(backend) },
|
||||
onDismiss = { pendingBackend = null },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -29,6 +29,8 @@ import com.nuvio.app.core.network.SyncBackendRepository
|
|||
import com.nuvio.app.core.ui.NuvioPrimaryButton
|
||||
import com.nuvio.app.core.ui.NuvioStatusModal
|
||||
import com.nuvio.app.core.ui.NuvioSurfaceCard
|
||||
import com.nuvio.app.features.dev.DebugSyncBackendSwitch
|
||||
import com.nuvio.app.features.dev.shouldShowDebugSyncBackendSwitch
|
||||
import kotlinx.coroutines.launch
|
||||
import nuvio.composeapp.generated.resources.Res
|
||||
import nuvio.composeapp.generated.resources.action_cancel
|
||||
|
|
@ -100,11 +102,19 @@ private fun AccountSettingsBody(
|
|||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
AccountInfoRow(
|
||||
label = stringResource(Res.string.settings_account_sync_backend),
|
||||
value = syncBackendLabel,
|
||||
)
|
||||
if (shouldShowDebugSyncBackendSwitch()) {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
DebugSyncBackendSwitch(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
requireConfirmation = true,
|
||||
)
|
||||
} else {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
AccountInfoRow(
|
||||
label = stringResource(Res.string.settings_account_sync_backend),
|
||||
value = syncBackendLabel,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
NuvioPrimaryButton(
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ actual object AppFeaturePolicy {
|
|||
actual val heroTrailerPlaybackSupported: Boolean = false
|
||||
actual val inAppUpdaterEnabled: Boolean = false
|
||||
actual val imdbRatingLogoEnabled: Boolean = true
|
||||
actual val debugBackendSwitcherEnabled: Boolean = AppBuildConfig.IS_DEBUG_BUILD
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ actual object AppFeaturePolicy {
|
|||
actual val heroTrailerPlaybackSupported: Boolean = false
|
||||
actual val inAppUpdaterEnabled: Boolean = false
|
||||
actual val imdbRatingLogoEnabled: Boolean = false
|
||||
actual val debugBackendSwitcherEnabled: Boolean = AppBuildConfig.IS_DEBUG_BUILD
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ actual object AppFeaturePolicy {
|
|||
actual val heroTrailerPlaybackSupported: Boolean = false
|
||||
actual val inAppUpdaterEnabled: Boolean = false
|
||||
actual val imdbRatingLogoEnabled: Boolean = true
|
||||
actual val debugBackendSwitcherEnabled: Boolean = AppBuildConfig.IS_DEBUG_BUILD
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue