Skip to content

Commit

Permalink
feat: support playing from links
Browse files Browse the repository at this point in the history
closes #31

* make sleep timer button a toggleable (it should make it fit in more with the text button next to it)
  • Loading branch information
abdallahmehiz committed Sep 5, 2024
1 parent 384fdf5 commit a1d8a5f
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 19 deletions.
10 changes: 7 additions & 3 deletions app/src/main/java/live/mehiz/mpvkt/ui/player/PlayerViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,18 @@ class PlayerViewModel(

val sheetShown = MutableStateFlow(Sheets.None)
val panelShown = MutableStateFlow(Panels.None)
val gestureSeekAmount = MutableStateFlow(0)

// Pair(startingPosition, seekAmount)
val gestureSeekAmount = MutableStateFlow<Pair<Int, Int>?>(null)

private var timerJob: Job? = null
private val _remainingTime = MutableStateFlow<Int?>(null)
private val _remainingTime = MutableStateFlow(0)
val remainingTime = _remainingTime.asStateFlow()

fun startTimer(seconds: Int) {
timerJob?.cancel()
_remainingTime.value = seconds
if (seconds < 1) return
timerJob = viewModelScope.launch {
for (time in seconds downTo 0) {
_remainingTime.value = time
Expand Down Expand Up @@ -210,7 +214,7 @@ class PlayerViewModel(
chapters.add(
Segment(
name = title,
start = time.toFloat(),
start = time.toFloat().coerceAtLeast(0f),
),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ fun GestureHandler(modifier: Modifier = Modifier) {
viewModel.pause()
},
onDragEnd = {
viewModel.gestureSeekAmount.update { 0 }
viewModel.gestureSeekAmount.update { null }
viewModel.hideSeekBar()
if (!wasPlayerAlreadyPause) viewModel.unpause()
},
Expand All @@ -219,7 +219,9 @@ fun GestureHandler(modifier: Modifier = Modifier) {
if (position <= 0f && dragAmount < 0) return@detectHorizontalDragGestures
val seekBy = ((dragAmount * 150f / size.width).coerceIn(0f - position, duration - position)).toInt()
viewModel.seekBy(seekBy)
viewModel.gestureSeekAmount.update { (position - startingPosition).toInt() }
viewModel.gestureSeekAmount.update {
Pair(startingPosition.toInt(), (position - startingPosition).toInt())
}
if (showSeekbarWhenSeeking) viewModel.showSeekBar()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
Expand All @@ -43,9 +44,12 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension
import `is`.xyz.mpv.Utils
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.update
Expand All @@ -63,6 +67,7 @@ import live.mehiz.mpvkt.ui.player.controls.components.VolumeSlider
import live.mehiz.mpvkt.ui.theme.PlayerRippleTheme
import live.mehiz.mpvkt.ui.theme.spacing
import org.koin.compose.koinInject
import kotlin.math.abs

@Suppress("CompositionLocalAllowlist")
val LocalPlayerButtonsClickEvent = staticCompositionLocalOf { {} }
Expand All @@ -83,6 +88,7 @@ fun PlayerControls(
val duration by viewModel.duration.collectAsState()
val position by viewModel.pos.collectAsState()
val paused by viewModel.paused.collectAsState()
val gestureSeekAmount by viewModel.gestureSeekAmount.collectAsState()
var isSeeking by remember { mutableStateOf(false) }
var resetControls by remember { mutableStateOf(true) }
LaunchedEffect(
Expand Down Expand Up @@ -171,18 +177,32 @@ fun PlayerControls(
viewModel.playerUpdate.update { PlayerUpdates.None }
}
AnimatedVisibility(
currentPlayerUpdate != PlayerUpdates.None,
gestureSeekAmount != null || currentPlayerUpdate != PlayerUpdates.None,
enter = fadeIn(playControlsAnimationSpec()),
exit = fadeOut(playControlsAnimationSpec()),
modifier = Modifier.constrainAs(playerUpdates) {
linkTo(parent.start, parent.end)
linkTo(parent.top, parent.bottom, bias = 0.2f)
},
) {
when (currentPlayerUpdate) {
PlayerUpdates.DoubleSpeed -> DoubleSpeedPlayerUpdate()
PlayerUpdates.AspectRatio -> TextPlayerUpdate(stringResource(aspectRatio.titleRes))
else -> {}
if (gestureSeekAmount != null) {
Text(
stringResource(
R.string.player_gesture_seek_indicator,
if (gestureSeekAmount!!.second >= 0) '+' else '-',
Utils.prettyTime(abs(gestureSeekAmount!!.second)),
Utils.prettyTime(gestureSeekAmount!!.first + gestureSeekAmount!!.second),
),
style = MaterialTheme.typography.headlineMedium,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
)
} else {
when (currentPlayerUpdate) {
PlayerUpdates.DoubleSpeed -> DoubleSpeedPlayerUpdate()
PlayerUpdates.AspectRatio -> TextPlayerUpdate(stringResource(aspectRatio.titleRes))
else -> {}
}
}
}

Expand Down Expand Up @@ -225,7 +245,7 @@ fun PlayerControls(
interaction,
rememberRipple(),
) { viewModel.pauseUnpause() }
.padding(16.dp),
.padding(MaterialTheme.spacing.medium),
contentDescription = null,
)
}
Expand Down Expand Up @@ -307,5 +327,5 @@ fun PlayerControls(

fun <T> playControlsAnimationSpec(): FiniteAnimationSpec<T> = tween(
durationMillis = 200,
easing = LinearOutSlowInEasing
easing = LinearOutSlowInEasing,
)
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FilterChip
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconToggleButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
Expand Down Expand Up @@ -89,18 +90,18 @@ fun MoreSheet(
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.extraSmall),
) {
var isSleepTimerDialogShown by remember { mutableStateOf(false) }
IconButton(onClick = { isSleepTimerDialogShown = true }) {
val remainingTime by viewModel.remainingTime.collectAsState()
IconToggleButton(
checked = remainingTime > 0,
onCheckedChange = { isSleepTimerDialogShown = true },
) {
Icon(imageVector = Icons.Outlined.Timer, contentDescription = null)
}
if (isSleepTimerDialogShown) {
val remainingTime by viewModel.remainingTime.collectAsState()
TimePickerDialog(
remainingTime = remainingTime ?: 0,
remainingTime = remainingTime,
onDismissRequest = { isSleepTimerDialogShown = false },
onTimeSelect = {
if (it < 1) return@TimePickerDialog
viewModel.startTimer(it)
}
onTimeSelect = viewModel::startTimer
)
}
TextButton(onClick = onEnterFiltersPanel) {
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
<string name="player_sheets_stats_page_chip">Page %d</string>
<string name="player_seek_n_seconds">%d seconds</string>
<string name="player_speed" translatable="false">x%.2f</string>
<string name="player_gesture_seek_indicator" translatable="false">%c%s\n[%s]</string>

<string name="player_aspect_fit">Fit Screen</string>
<string name="player_aspect_crop">Crop</string>
Expand Down

0 comments on commit a1d8a5f

Please sign in to comment.