diff --git a/composeApp/src/androidMain/kotlin/dev/datlag/burningseries/MainActivity.kt b/composeApp/src/androidMain/kotlin/dev/datlag/burningseries/MainActivity.kt index 71850c4b..f81799cf 100644 --- a/composeApp/src/androidMain/kotlin/dev/datlag/burningseries/MainActivity.kt +++ b/composeApp/src/androidMain/kotlin/dev/datlag/burningseries/MainActivity.kt @@ -24,6 +24,7 @@ import dev.datlag.burningseries.model.BSUtil import dev.datlag.burningseries.other.Constants import dev.datlag.burningseries.other.DomainVerifier import dev.datlag.burningseries.other.DownloadManager +import dev.datlag.burningseries.other.PictureInPicture import dev.datlag.burningseries.settings.Settings import dev.datlag.burningseries.ui.custom.video.pip.enterPIPMode import dev.datlag.burningseries.ui.custom.video.pip.isActivityStatePipMode @@ -76,7 +77,7 @@ class MainActivity : ComponentActivity() { Kast.setup(this) DownloadManager.setClient(httpClient).setFile(appContext ?: this) DomainVerifier.verify(this) - PictureInPicture.update { this.isActivityStatePipMode() } + PictureInPicture.setActive(this.isActivityStatePipMode()) setContent { val appSettings by di.instance() @@ -113,7 +114,10 @@ class MainActivity : ComponentActivity() { override fun onUserLeaveHint() { super.onUserLeaveHint() - enterPIPMode(this) + + if (PictureInPicture.isEnabled) { + enterPIPMode(this) + } } @RequiresApi(Build.VERSION_CODES.O) @@ -123,7 +127,7 @@ class MainActivity : ComponentActivity() { ) { super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig) - PictureInPicture.update { isInPictureInPictureMode } + PictureInPicture.setActive(isInPictureInPictureMode) } override fun onDestroy() { @@ -133,35 +137,35 @@ class MainActivity : ComponentActivity() { Kast.dispose() DomainVerifier.verify(this) - PictureInPicture.update { this.isActivityStatePipMode() } + PictureInPicture.setActive(this.isActivityStatePipMode()) } override fun onStart() { super.onStart() DomainVerifier.verify(this) - PictureInPicture.update { this.isActivityStatePipMode() } + PictureInPicture.setActive(this.isActivityStatePipMode()) } override fun onResume() { super.onResume() DomainVerifier.verify(this) - PictureInPicture.update { this.isActivityStatePipMode() } + PictureInPicture.setActive(this.isActivityStatePipMode()) } override fun onPause() { super.onPause() DomainVerifier.verify(this) - PictureInPicture.update { this.isActivityStatePipMode() } + PictureInPicture.setActive(this.isActivityStatePipMode()) } override fun onRestart() { super.onRestart() DomainVerifier.verify(this) - PictureInPicture.update { this.isActivityStatePipMode() } + PictureInPicture.setActive(this.isActivityStatePipMode()) } private fun Uri.findSyncId(): String? { diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/App.kt b/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/App.kt index 68b2701c..fc47cd46 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/App.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/App.kt @@ -37,7 +37,6 @@ import org.kodein.di.DI val LocalDarkMode = compositionLocalOf { error("No dark mode state provided") } val LocalEdgeToEdge = staticCompositionLocalOf { false } -val PictureInPicture = MutableStateFlow(false) val LocalDI = compositionLocalOf { error("No dependency injection provided") } val LocalHaze = compositionLocalOf { error("No Haze state provided") } diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/other/PictureInPicture.kt b/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/other/PictureInPicture.kt new file mode 100644 index 00000000..3d5b9bd9 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/other/PictureInPicture.kt @@ -0,0 +1,15 @@ +package dev.datlag.burningseries.other + +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.update + +data object PictureInPicture { + val enabled = MutableStateFlow(false) + val active = MutableStateFlow(false) + + val isEnabled: Boolean + get() = enabled.value + + fun setEnabled(value: Boolean) = enabled.update { value } + fun setActive(value: Boolean) = active.update { value } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/Component.kt b/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/Component.kt index 03aab5cb..ebfe4384 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/Component.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/Component.kt @@ -12,6 +12,8 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment @@ -22,9 +24,9 @@ import com.arkivanov.decompose.ComponentContext import com.arkivanov.essenty.lifecycle.Lifecycle import com.arkivanov.essenty.lifecycle.LifecycleOwner import dev.datlag.burningseries.LocalDI -import dev.datlag.burningseries.PictureInPicture import dev.datlag.burningseries.common.nullableFirebaseInstance import dev.datlag.burningseries.common.screen +import dev.datlag.burningseries.other.PictureInPicture import dev.datlag.burningseries.ui.custom.PIPContent import dev.datlag.burningseries.ui.theme.SchemeTheme import dev.datlag.tooling.compose.launchDefault @@ -43,6 +45,9 @@ interface Component : DIAware, ComponentContext { val handlesPIP: Boolean get() = false + val enablePIP: Boolean + get() = false + @Composable fun render() @@ -52,6 +57,10 @@ interface Component : DIAware, ComponentContext { @Composable fun onRender(content: @Composable (Boolean) -> Unit) { + LaunchedEffect(Unit) { + PictureInPicture.setEnabled(enablePIP) + } + CompositionLocalProvider( LocalDI provides di, LocalLifecycleOwner provides object : LifecycleOwner { @@ -59,7 +68,7 @@ interface Component : DIAware, ComponentContext { } ) { Box { - val pip by PictureInPicture.collectAsStateWithLifecycle() + val pip by PictureInPicture.active.collectAsStateWithLifecycle() content(pip) if (pip && !handlesPIP) { diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/DialogComponent.kt b/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/DialogComponent.kt index 5a403aba..7aae0be5 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/DialogComponent.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/DialogComponent.kt @@ -2,7 +2,7 @@ package dev.datlag.burningseries.ui.navigation import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import dev.datlag.burningseries.PictureInPicture +import dev.datlag.burningseries.other.PictureInPicture import dev.datlag.tooling.decompose.lifecycle.collectAsStateWithLifecycle interface DialogComponent : Component { @@ -10,7 +10,7 @@ interface DialogComponent : Component { @Composable override fun onRender(content: @Composable (Boolean) -> Unit) { - val isPip by PictureInPicture.collectAsStateWithLifecycle() + val isPip by PictureInPicture.active.collectAsStateWithLifecycle() if (!isPip || handlesPIP) { super.onRender(content) diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/screen/activate/dialog/error/ErrorDialog.kt b/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/screen/activate/dialog/error/ErrorDialog.kt index 93c93359..0da9801e 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/screen/activate/dialog/error/ErrorDialog.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/screen/activate/dialog/error/ErrorDialog.kt @@ -20,6 +20,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import dev.datlag.burningseries.composeapp.generated.resources.Res @@ -57,10 +58,15 @@ fun ErrorDialog(component: ErrorComponent) { }, text = { Column( + modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically), horizontalAlignment = Alignment.CenterHorizontally ) { - Text(text = stringResource(Res.string.activate_error_text)) + Text( + modifier = Modifier.fillMaxWidth(), + text = stringResource(Res.string.activate_error_text), + textAlign = TextAlign.Center + ) component.stream.ifEmpty { null }?.let { stream -> Button( modifier = Modifier.fillMaxWidth(), diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/screen/activate/dialog/success/SuccessDialog.kt b/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/screen/activate/dialog/success/SuccessDialog.kt index 21a446f3..435a7b28 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/screen/activate/dialog/success/SuccessDialog.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/screen/activate/dialog/success/SuccessDialog.kt @@ -17,6 +17,7 @@ import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import dev.datlag.burningseries.composeapp.generated.resources.Res @@ -49,10 +50,15 @@ fun SuccessDialog(component: SuccessComponent) { }, text = { Column( + modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically), horizontalAlignment = Alignment.CenterHorizontally ) { - Text(text = stringResource(Res.string.activate_success_text)) + Text( + modifier = Modifier.fillMaxWidth(), + text = stringResource(Res.string.activate_success_text), + textAlign = TextAlign.Center + ) component.stream.ifEmpty { null }?.let { stream -> Button( modifier = Modifier.fillMaxWidth(), diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/screen/video/VideoScreenComponent.kt b/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/screen/video/VideoScreenComponent.kt index 434e485f..7d0c612b 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/screen/video/VideoScreenComponent.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/screen/video/VideoScreenComponent.kt @@ -52,6 +52,7 @@ class VideoScreenComponent( } override val handlesPIP: Boolean = true + override val enablePIP: Boolean = true @Composable override fun render() {