Revert "Merge branch 'iosmodalsheet' into cmp-rewrite"

This reverts commit 0525c70368, reversing
changes made to 9d2fe291e8.
This commit is contained in:
tapframe 2026-06-05 17:16:09 +05:30
parent dcf4d059f6
commit ecd5f544b1
14 changed files with 135 additions and 253 deletions

View file

@ -238,7 +238,6 @@ kotlin {
baseName = "ComposeApp"
isStatic = true
freeCompilerArgs += listOf("-Xbinary=bundleId=$iosFrameworkBundleId")
export("com.mohamedrejeb.calf:calf-ui:${libs.versions.calf.get()}")
}
}
@ -275,7 +274,6 @@ kotlin {
implementation(libs.coil.compose)
implementation(libs.coil.network.ktor3)
implementation(libs.coil.svg)
api(libs.calf.ui)
implementation("dev.chrisbanes.haze:haze:1.7.2")
implementation(libs.compose.runtime)
implementation(libs.compose.foundation)

View file

@ -56,7 +56,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties
import androidx.compose.ui.zIndex
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
@ -68,7 +67,6 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.dialog
import androidx.navigation.compose.rememberNavController
import androidx.navigation.toRoute
import coil3.ImageLoader
@ -101,11 +99,8 @@ import com.nuvio.app.core.ui.NuvioTheme
import com.nuvio.app.core.ui.LocalNuvioBottomNavigationOverlayPadding
import com.nuvio.app.core.ui.NativeNavigationTab
import com.nuvio.app.core.ui.NativeTabBridge
import com.nuvio.app.core.ui.NuvioModalBottomSheet
import com.nuvio.app.core.ui.isLiquidGlassNativeTabBarSupported
import com.nuvio.app.core.ui.dismissNuvioBottomSheet
import com.nuvio.app.core.ui.localizedContinueWatchingSubtitle
import com.nuvio.app.core.ui.rememberNuvioBottomSheetState
import com.nuvio.app.features.auth.AuthScreen
import com.nuvio.app.features.addons.AddonRepository
import com.nuvio.app.features.catalog.CatalogRepository
@ -804,7 +799,6 @@ private fun MainAppContent(
var profileSwitchLoading by remember { mutableStateOf(false) }
var resumePromptItem by remember { mutableStateOf<ContinueWatchingItem?>(null) }
var lastExternalPlayerLaunch by remember { mutableStateOf<PlayerLaunch?>(null) }
val streamLaunchIdsPreservedForPlayerReturn = remember { mutableSetOf<Long>() }
val launchExternalPlayer = rememberExternalPlayerLauncher { result ->
if (result != null && result.positionMs > 0L) {
coroutineScope.launch {
@ -1583,8 +1577,7 @@ private fun MainAppContent(
modifier = Modifier.fillMaxSize(),
)
}
val streamRouteDestination: @Composable (NavBackStackEntry) -> Unit =
streamRouteDestination@{ backStackEntry ->
composable<StreamRoute> { backStackEntry ->
val route = backStackEntry.toRoute<StreamRoute>()
val launch = remember(route.launchId) {
StreamLaunchStore.get(route.launchId)
@ -1594,7 +1587,7 @@ private fun MainAppContent(
StreamsRepository.clear()
navController.popBackStack()
}
return@streamRouteDestination
return@composable
}
val pauseDescription = launch.pauseDescription
val streamRouteScope = rememberCoroutineScope()
@ -1604,9 +1597,7 @@ private fun MainAppContent(
DisposableEffect(lifecycleOwner, route.launchId) {
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_DESTROY) {
if (route.launchId !in streamLaunchIdsPreservedForPlayerReturn) {
StreamLaunchStore.remove(route.launchId)
}
StreamLaunchStore.remove(route.launchId)
}
}
lifecycleOwner.lifecycle.addObserver(observer)
@ -1675,21 +1666,6 @@ private fun MainAppContent(
fun p2pSentinelUrl(infoHash: String, fileIdx: Int?): String =
"torrent://$infoHash${fileIdx?.let { "?index=$it" }.orEmpty()}"
fun navigateToPlayer(
playerLaunch: PlayerLaunch,
replaceStreamRoute: Boolean = false,
) {
playerLaunch.returnStreamLaunchId?.let { streamLaunchId ->
streamLaunchIdsPreservedForPlayerReturn.add(streamLaunchId)
}
val playerLaunchId = PlayerLaunchStore.put(playerLaunch)
navController.navigate(PlayerRoute(launchId = playerLaunchId)) {
if (replaceStreamRoute) {
popUpTo<StreamRoute> { inclusive = true }
}
}
}
fun openP2pStream(
stream: StreamItem,
resolvedResumePositionMs: Long?,
@ -1752,14 +1728,15 @@ private fun MainAppContent(
torrentTrackers = stream.p2pTrackers,
initialPositionMs = resolvedResumePositionMs ?: 0L,
initialProgressFraction = resolvedResumeProgressFraction,
returnStreamLaunchId = if (isIos && !replaceStreamRoute) route.launchId else null,
)
val launchId = PlayerLaunchStore.put(playerLaunch)
StreamsRepository.cancelLoading()
navigateToPlayer(
playerLaunch = playerLaunch,
replaceStreamRoute = replaceStreamRoute,
)
navController.navigate(PlayerRoute(launchId = launchId)) {
if (replaceStreamRoute) {
popUpTo<StreamRoute> { inclusive = true }
}
}
}
fun requestOrOpenP2pStream(
@ -1875,10 +1852,10 @@ private fun MainAppContent(
}
StreamsRepository.clear()
reuseNavigated = true
navigateToPlayer(
playerLaunch = playerLaunch,
replaceStreamRoute = true,
)
val launchId = PlayerLaunchStore.put(playerLaunch)
navController.navigate(PlayerRoute(launchId = launchId)) {
popUpTo<StreamRoute> { inclusive = true }
}
}
}
@ -2007,10 +1984,10 @@ private fun MainAppContent(
}
StreamsRepository.consumeAutoPlay()
StreamsRepository.cancelLoading()
navigateToPlayer(
playerLaunch = playerLaunch,
replaceStreamRoute = true,
)
val launchId = PlayerLaunchStore.put(playerLaunch)
navController.navigate(PlayerRoute(launchId = launchId)) {
popUpTo<StreamRoute> { inclusive = true }
}
}
if (!hasResolvedVideoId) {
@ -2020,7 +1997,7 @@ private fun MainAppContent(
) {
CircularProgressIndicator(color = MaterialTheme.colorScheme.primary)
}
return@streamRouteDestination
return@composable
}
fun openSelectedStream(
@ -2122,7 +2099,6 @@ private fun MainAppContent(
parentMetaType = launch.parentMetaType ?: launch.type,
initialPositionMs = resolvedResumePositionMs ?: 0L,
initialProgressFraction = resolvedResumeProgressFraction,
returnStreamLaunchId = if (isIos) route.launchId else null,
)
if (!forceInternal && (forceExternal || playerSettings.externalPlayerEnabled)) {
@ -2131,8 +2107,11 @@ private fun MainAppContent(
return
}
val launchId = PlayerLaunchStore.put(playerLaunch)
StreamsRepository.cancelLoading()
navigateToPlayer(playerLaunch)
navController.navigate(
PlayerRoute(launchId = launchId)
)
}
// Hide overlay when reuse navigated to external player (prevents reload from showing it again)
@ -2142,142 +2121,90 @@ private fun MainAppContent(
}
}
val streamSheetState = rememberNuvioBottomSheetState(skipPartiallyExpanded = true)
fun closeStreamRoute() {
streamLaunchIdsPreservedForPlayerReturn.remove(route.launchId)
StreamsRepository.clear()
navController.popBackStack()
}
fun dismissStreamRoute() {
if (isIos) {
streamRouteScope.launch {
dismissNuvioBottomSheet(
sheetState = streamSheetState,
onDismiss = ::closeStreamRoute,
Box(modifier = Modifier.fillMaxSize()) {
StreamsScreen(
type = launch.type,
videoId = effectiveVideoId,
parentMetaId = launch.parentMetaId ?: effectiveVideoId,
parentMetaType = launch.parentMetaType ?: launch.type,
title = launch.title,
logo = launch.logo,
poster = launch.poster,
background = launch.background,
seasonNumber = launch.seasonNumber,
episodeNumber = launch.episodeNumber,
episodeTitle = launch.episodeTitle,
episodeThumbnail = launch.episodeThumbnail,
resumePositionMs = launch.resumePositionMs,
resumeProgressFraction = launch.resumeProgressFraction,
manualSelection = launch.manualSelection,
startFromBeginning = launch.startFromBeginning,
onStreamSelected = { stream, resolvedResumePositionMs, resolvedResumeProgressFraction ->
openSelectedStream(
stream = stream,
resolvedResumePositionMs = resolvedResumePositionMs,
resolvedResumeProgressFraction = resolvedResumeProgressFraction,
forceExternal = false,
forceInternal = false,
)
}
} else {
closeStreamRoute()
}
}
val streamRouteContent: @Composable (Modifier) -> Unit = { contentModifier ->
Box(modifier = contentModifier) {
StreamsScreen(
type = launch.type,
videoId = effectiveVideoId,
parentMetaId = launch.parentMetaId ?: effectiveVideoId,
parentMetaType = launch.parentMetaType ?: launch.type,
title = launch.title,
logo = launch.logo,
poster = launch.poster,
background = launch.background,
seasonNumber = launch.seasonNumber,
episodeNumber = launch.episodeNumber,
episodeTitle = launch.episodeTitle,
episodeThumbnail = launch.episodeThumbnail,
resumePositionMs = launch.resumePositionMs,
resumeProgressFraction = launch.resumeProgressFraction,
manualSelection = launch.manualSelection,
startFromBeginning = launch.startFromBeginning,
onStreamSelected = { stream, resolvedResumePositionMs, resolvedResumeProgressFraction ->
openSelectedStream(
stream = stream,
resolvedResumePositionMs = resolvedResumePositionMs,
resolvedResumeProgressFraction = resolvedResumeProgressFraction,
forceExternal = false,
forceInternal = false,
},
onStreamActionOpen = { stream, openExternally, resolvedResumePositionMs, resolvedResumeProgressFraction ->
openSelectedStream(
stream = stream,
resolvedResumePositionMs = resolvedResumePositionMs,
resolvedResumeProgressFraction = resolvedResumeProgressFraction,
forceExternal = openExternally,
forceInternal = !openExternally,
)
},
onBack = {
StreamsRepository.clear()
navController.popBackStack()
},
modifier = Modifier.fillMaxSize(),
)
pendingP2pStreamOpen?.let { pending ->
P2pConsentDialog(
onEnableP2p = {
P2pSettingsRepository.setP2pEnabled(true)
pendingP2pStreamOpen = null
openP2pStream(
stream = pending.stream,
resolvedResumePositionMs = pending.resumePositionMs,
resolvedResumeProgressFraction = pending.resumeProgressFraction,
replaceStreamRoute = pending.isAutoPlay,
)
},
onStreamActionOpen = { stream, openExternally, resolvedResumePositionMs, resolvedResumeProgressFraction ->
openSelectedStream(
stream = stream,
resolvedResumePositionMs = resolvedResumePositionMs,
resolvedResumeProgressFraction = resolvedResumeProgressFraction,
forceExternal = openExternally,
forceInternal = !openExternally,
)
},
onBack = { dismissStreamRoute() },
modifier = Modifier.fillMaxSize(),
showBackButton = !isIos,
)
pendingP2pStreamOpen?.let { pending ->
P2pConsentDialog(
onEnableP2p = {
P2pSettingsRepository.setP2pEnabled(true)
pendingP2pStreamOpen = null
openP2pStream(
stream = pending.stream,
resolvedResumePositionMs = pending.resumePositionMs,
resolvedResumeProgressFraction = pending.resumeProgressFraction,
replaceStreamRoute = pending.isAutoPlay,
)
},
onDismiss = {
if (pending.isAutoPlay) {
StreamsRepository.skipAutoPlayStream(pending.stream)
StreamsRepository.consumeAutoPlay()
}
pendingP2pStreamOpen = null
},
)
}
if (resolvingDebridStream) {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Black.copy(alpha = 0.82f)),
contentAlignment = Alignment.Center,
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
CircularProgressIndicator(color = Color.White)
Text(
text = stringResource(Res.string.streams_finding_source),
color = Color.White.copy(alpha = 0.82f),
style = MaterialTheme.typography.bodyMedium,
)
onDismiss = {
if (pending.isAutoPlay) {
StreamsRepository.skipAutoPlayStream(pending.stream)
StreamsRepository.consumeAutoPlay()
}
pendingP2pStreamOpen = null
},
)
}
if (resolvingDebridStream) {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Black.copy(alpha = 0.82f)),
contentAlignment = Alignment.Center,
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
CircularProgressIndicator(color = Color.White)
Text(
text = stringResource(Res.string.streams_finding_source),
color = Color.White.copy(alpha = 0.82f),
style = MaterialTheme.typography.bodyMedium,
)
}
}
}
}
if (isIos) {
NuvioModalBottomSheet(
onDismissRequest = { closeStreamRoute() },
sheetState = streamSheetState,
containerColor = MaterialTheme.colorScheme.background,
contentColor = MaterialTheme.colorScheme.onBackground,
iosContentTopPadding = 0.dp,
) {
streamRouteContent(
Modifier
.fillMaxWidth()
.weight(1f),
)
}
} else {
streamRouteContent(Modifier.fillMaxSize())
}
}
if (isIos) {
dialog<StreamRoute>(
dialogProperties = DialogProperties(
usePlatformDefaultWidth = false,
),
) { backStackEntry ->
streamRouteDestination(backStackEntry)
}
} else {
composable<StreamRoute> { backStackEntry ->
streamRouteDestination(backStackEntry)
}
}
composable<PlayerRoute>(
enterTransition = {
@ -2339,14 +2266,6 @@ private fun MainAppContent(
ResumePromptRepository.markPlayerExitedNormally()
PlayerLaunchStore.remove(route.launchId)
navController.popBackStack()
launch.returnStreamLaunchId?.let { streamLaunchId ->
if (isIos && StreamLaunchStore.get(streamLaunchId) != null) {
navController.navigate(StreamRoute(launchId = streamLaunchId)) {
launchSingleTop = true
}
}
streamLaunchIdsPreservedForPlayerReturn.remove(streamLaunchId)
}
},
onOpenInExternalPlayer = { request ->
val playerLaunch = PlayerLaunch(

View file

@ -4,11 +4,9 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@ -17,6 +15,8 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.SheetState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@ -26,57 +26,24 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.nuvio.app.isIos
import com.mohamedrejeb.calf.ui.sheet.AdaptiveBottomSheet
import com.mohamedrejeb.calf.ui.sheet.AdaptiveSheetState
import com.mohamedrejeb.calf.ui.sheet.rememberAdaptiveSheetState
typealias NuvioBottomSheetState = AdaptiveSheetState
@Composable
@OptIn(ExperimentalMaterial3Api::class)
fun rememberNuvioBottomSheetState(
skipPartiallyExpanded: Boolean = !isIos,
): NuvioBottomSheetState =
rememberAdaptiveSheetState(skipPartiallyExpanded = skipPartiallyExpanded)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun NuvioModalBottomSheet(
onDismissRequest: () -> Unit,
sheetState: NuvioBottomSheetState,
sheetState: SheetState,
modifier: Modifier = Modifier,
containerColor: Color = MaterialTheme.colorScheme.surface,
contentColor: Color = MaterialTheme.colorScheme.onSurface,
shape: Shape = RoundedCornerShape(topStart = 28.dp, topEnd = 28.dp),
showDragHandle: Boolean = true,
iosContentTopPadding: Dp = 28.dp,
content: @Composable ColumnScope.() -> Unit,
) {
val sheetModifier = if (isIos) {
modifier.fillMaxSize()
} else {
modifier
}
val sheetContent: @Composable ColumnScope.() -> Unit = {
if (isIos && iosContentTopPadding > 0.dp) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(top = iosContentTopPadding),
content = content,
)
} else {
content()
}
}
AdaptiveBottomSheet(
ModalBottomSheet(
onDismissRequest = onDismissRequest,
adaptiveSheetState = sheetState,
modifier = sheetModifier,
sheetState = sheetState,
modifier = modifier,
containerColor = containerColor,
contentColor = contentColor,
shape = shape,
@ -85,7 +52,7 @@ fun NuvioModalBottomSheet(
} else {
null
},
content = sheetContent,
content = content,
)
}
@ -137,7 +104,7 @@ fun NuvioBottomSheetActionRow(
@OptIn(ExperimentalMaterial3Api::class)
suspend fun dismissNuvioBottomSheet(
sheetState: NuvioBottomSheetState,
sheetState: SheetState,
onDismiss: () -> Unit,
) {
if (sheetState.isVisible) {
@ -155,4 +122,4 @@ private fun NuvioBottomSheetDragHandle() {
.clip(RoundedCornerShape(999.dp))
.background(MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.65f)),
)
}
}

View file

@ -17,6 +17,7 @@ import androidx.compose.material.icons.filled.Replay
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
@ -51,7 +52,7 @@ fun NuvioContinueWatchingActionSheet(
onRemove: () -> Unit,
) {
if (item == null) return
val sheetState = rememberNuvioBottomSheetState()
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val coroutineScope = rememberCoroutineScope()
fun dismissAfter(action: () -> Unit) {

View file

@ -18,7 +18,9 @@ import androidx.compose.material.icons.rounded.KeyboardArrowDown
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SheetState
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@ -49,7 +51,7 @@ fun NuvioDropdownChip(
modifier: Modifier = Modifier,
) {
var isSheetVisible by remember { mutableStateOf(false) }
val sheetState = rememberNuvioBottomSheetState()
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val coroutineScope = rememberCoroutineScope()
Row(
@ -115,7 +117,7 @@ private fun NuvioDropdownOptionsSheet(
title: String,
options: List<NuvioDropdownOption>,
selectedKey: String?,
sheetState: NuvioBottomSheetState,
sheetState: SheetState,
onDismiss: () -> Unit,
onSelected: (NuvioDropdownOption) -> Unit,
) {

View file

@ -23,6 +23,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
@ -56,7 +57,7 @@ fun NuvioPosterActionSheet(
onToggleWatched: () -> Unit,
) {
if (item == null) return
val sheetState = rememberNuvioBottomSheetState()
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val coroutineScope = rememberCoroutineScope()
NuvioModalBottomSheet(

View file

@ -44,7 +44,7 @@ import androidx.compose.material3.Switch
import androidx.compose.material3.SwitchDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import com.nuvio.app.core.ui.rememberNuvioBottomSheetState
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
@ -1918,7 +1918,7 @@ private fun GenrePickerSheet(
onSelect: (String?) -> Unit,
onDismiss: () -> Unit,
) {
val sheetState = rememberNuvioBottomSheetState()
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
NuvioModalBottomSheet(
onDismissRequest = onDismiss,

View file

@ -24,7 +24,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import com.nuvio.app.core.ui.rememberNuvioBottomSheetState
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
@ -51,7 +51,7 @@ fun CommentDetailSheet(
onNext: () -> Unit,
onDismiss: () -> Unit,
) {
val sheetState = rememberNuvioBottomSheetState()
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val scrollState = rememberScrollState()
LaunchedEffect(comment.id) {

View file

@ -12,7 +12,7 @@ import androidx.compose.material.icons.filled.PlaylistAddCheckCircle
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import com.nuvio.app.core.ui.rememberNuvioBottomSheetState
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
@ -46,7 +46,7 @@ fun EpisodeWatchedActionSheet(
showPlayManually: Boolean = false,
onPlayManually: (() -> Unit)? = null,
) {
val sheetState = rememberNuvioBottomSheetState()
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val coroutineScope = rememberCoroutineScope()
NuvioModalBottomSheet(
@ -140,7 +140,7 @@ fun SeasonWatchedActionSheet(
onToggleSeasonWatched: () -> Unit,
onMarkPreviousSeasonsWatched: () -> Unit,
) {
val sheetState = rememberNuvioBottomSheetState()
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val coroutineScope = rememberCoroutineScope()
NuvioModalBottomSheet(

View file

@ -18,7 +18,7 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import com.nuvio.app.core.ui.rememberNuvioBottomSheetState
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@ -67,7 +67,7 @@ fun TrailerPlayerPopup(
}
}.joinToString(separator = "")
val sheetState = rememberNuvioBottomSheetState()
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val coroutineScope = rememberCoroutineScope()
var playerError by remember(playbackSource?.videoUrl, playbackSource?.audioUrl) {
mutableStateOf<String?>(null)

View file

@ -49,7 +49,6 @@ data class PlayerLaunch(
val torrentTrackers: List<String> = emptyList(),
val initialPositionMs: Long = 0L,
val initialProgressFraction: Float? = null,
val returnStreamLaunchId: Long? = null,
)
object PlayerLaunchStore {

View file

@ -65,7 +65,7 @@ import nuvio.composeapp.generated.resources.settings_appearance_section_theme
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
import androidx.compose.material3.ExperimentalMaterial3Api
import com.nuvio.app.core.ui.rememberNuvioBottomSheetState
import androidx.compose.material3.rememberModalBottomSheetState
@OptIn(ExperimentalLayoutApi::class)
internal fun LazyListScope.appearanceSettingsContent(
@ -196,7 +196,7 @@ private fun AppearanceLanguageBottomSheet(
onLanguageSelected: (AppLanguage) -> Unit,
onDismiss: () -> Unit,
) {
val sheetState = rememberNuvioBottomSheetState()
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val coroutineScope = rememberCoroutineScope()
val options = remember {
AppLanguage.entries.map { language ->

View file

@ -87,7 +87,7 @@ import com.nuvio.app.core.ui.dismissNuvioBottomSheet
import com.nuvio.app.features.downloads.DownloadsRepository
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.compose.material3.ExperimentalMaterial3Api
import com.nuvio.app.core.ui.rememberNuvioBottomSheetState
import androidx.compose.material3.rememberModalBottomSheetState
import coil3.compose.AsyncImage
import com.nuvio.app.core.ui.nuvioSafeBottomPadding
import com.nuvio.app.features.debrid.DebridProviders
@ -132,7 +132,6 @@ fun StreamsScreen(
) -> Unit = { _, _, _, _ -> },
onBack: () -> Unit,
modifier: Modifier = Modifier,
showBackButton: Boolean = true,
) {
val uiState by StreamsRepository.uiState.collectAsStateWithLifecycle()
val playerSettings by remember {
@ -279,15 +278,13 @@ fun StreamsScreen(
.padding(start = 12.dp, top = 8.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
if (showBackButton) {
NuvioBackButton(
onClick = onBack,
modifier = Modifier
.size(40.dp),
containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.45f),
contentColor = MaterialTheme.colorScheme.onBackground,
)
}
NuvioBackButton(
onClick = onBack,
modifier = Modifier
.size(40.dp),
containerColor = MaterialTheme.colorScheme.background.copy(alpha = 0.45f),
contentColor = MaterialTheme.colorScheme.onBackground,
)
Box(
modifier = Modifier
@ -1145,7 +1142,7 @@ private fun StreamActionsSheet(
) {
if (stream == null) return
val sheetState = rememberNuvioBottomSheetState()
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val coroutineScope = rememberCoroutineScope()
NuvioModalBottomSheet(

View file

@ -14,7 +14,6 @@ androidx-work = "2.10.3"
androidx-testExt = "1.3.0"
composeMultiplatform = "1.11.1"
coil = "3.5.0-beta01"
calf = "0.11.0"
kermit = "2.0.5"
junit = "4.13.2"
kotlin = "2.3.0"
@ -53,7 +52,6 @@ coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil"
coil-gif = { module = "io.coil-kt.coil3:coil-gif", version.ref = "coil" }
coil-network-ktor3 = { module = "io.coil-kt.coil3:coil-network-ktor3", version.ref = "coil" }
coil-svg = { module = "io.coil-kt.coil3:coil-svg", version.ref = "coil" }
calf-ui = { module = "com.mohamedrejeb.calf:calf-ui", version.ref = "calf" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
ktor-client-android = { module = "io.ktor:ktor-client-android", version.ref = "ktor" }
kermit = { module = "co.touchlab:kermit", version.ref = "kermit" }