Skip to content

Commit

Permalink
refactor(PlayerActivity): use callbacks instead of injecting viewmode…
Browse files Browse the repository at this point in the history
…l into composables
  • Loading branch information
abdallahmehiz committed Nov 12, 2024
1 parent c904edb commit 7c28812
Show file tree
Hide file tree
Showing 12 changed files with 326 additions and 235 deletions.
16 changes: 4 additions & 12 deletions app/src/main/java/live/mehiz/mpvkt/ui/player/PlayerActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,12 @@ import live.mehiz.mpvkt.ui.player.controls.PlayerControls
import live.mehiz.mpvkt.ui.theme.MpvKtTheme
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.context.loadKoinModules
import org.koin.core.context.unloadKoinModules
import org.koin.core.module.Module
import org.koin.dsl.module
import java.io.File

@Suppress("TooManyFunctions")
class PlayerActivity : AppCompatActivity() {

private val viewModel: PlayerViewModel by lazy { PlayerViewModel(this) }
private val viewModelModule: Module by lazy { module { viewModel { viewModel } } }
private val binding by lazy { PlayerLayoutBinding.inflate(layoutInflater) }
private val playerObserver by lazy { PlayerObserver(this) }
private val playbackStateRepository: PlaybackStateRepository by inject()
Expand Down Expand Up @@ -113,14 +108,15 @@ class PlayerActivity : AppCompatActivity() {
setupMPV()
setupAudio()
setupMediaSession()
getPlayableUri(intent)?.let { player.playFile(it) }
getPlayableUri(intent)?.let(player::playFile)
setIntentExtras(intent.extras)
setOrientation()
loadKoinModules(viewModelModule)

binding.controls.setContent {
MpvKtTheme {
PlayerControls(
viewModel = viewModel,
onBackPress = ::finish,
modifier = Modifier.onGloballyPositioned {
pipRect = it.boundsInWindow().toAndroidRect()
},
Expand All @@ -146,7 +142,6 @@ class PlayerActivity : AppCompatActivity() {
noisyReceiver.initialized = false
}

unloadKoinModules(viewModelModule)
MPVLib.removeObserver(playerObserver)
MPVLib.destroy()

Expand Down Expand Up @@ -522,10 +517,7 @@ class PlayerActivity : AppCompatActivity() {
internal fun onObserverEvent(property: String, value: Double) {
if (player.isExiting) return
when (property) {
"speed" -> {
if (viewModel.sheetShown.value == Sheets.PlaybackSpeed) return
viewModel.playbackSpeed.update { value.toFloat() }
}
"speed" -> viewModel.playbackSpeed.update { value.toFloat() }
"video-params/aspect" -> if (isPipSupported) createPipParams()
}
}
Expand Down
16 changes: 8 additions & 8 deletions app/src/main/java/live/mehiz/mpvkt/ui/player/PlayerViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -562,14 +562,6 @@ class PlayerViewModel(
}
}

fun executeCustomButton(button: CustomButtonEntity) {
MPVLib.command(arrayOf("script-message", "call_button${button.id}"))
}

fun executeCustomButtonLongClick(button: CustomButtonEntity) {
MPVLib.command(arrayOf("script-message", "call_button${button.id}long"))
}

override fun onCleared() {
super.onCleared()
viewModelScope.cancel()
Expand All @@ -585,3 +577,11 @@ data class Track(
fun Float.normalize(inMin: Float, inMax: Float, outMin: Float, outMax: Float): Float {
return (this - inMin) * (outMax - outMin) / (inMax - inMin) + outMin
}

fun CustomButtonEntity.execute() {
MPVLib.command(arrayOf("script-message", "call_button$id"))
}

fun CustomButtonEntity.executeLongClick() {
MPVLib.command(arrayOf("script-message", "call_button${id}long"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,57 +9,57 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.LockOpen
import androidx.compose.material.icons.filled.ScreenRotation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import `is`.xyz.mpv.MPVLib
import kotlinx.coroutines.flow.update
import dev.vivvvek.seeker.Segment
import live.mehiz.mpvkt.R
import live.mehiz.mpvkt.preferences.PlayerPreferences
import live.mehiz.mpvkt.ui.player.PlayerViewModel
import live.mehiz.mpvkt.ui.player.Sheets
import live.mehiz.mpvkt.ui.player.controls.components.ControlsButton
import live.mehiz.mpvkt.ui.player.controls.components.CurrentChapter
import org.koin.compose.koinInject

@Composable
fun BottomLeftPlayerControls(modifier: Modifier = Modifier) {
val viewModel = koinInject<PlayerViewModel>()
fun BottomLeftPlayerControls(
playbackSpeed: Float,
currentChapter: Segment?,
onLockControls: () -> Unit,
onCycleRotation: () -> Unit,
onPlaybackSpeedChange: (Float) -> Unit,
onOpenSheet: (Sheets) -> Unit,
modifier: Modifier = Modifier
) {
val playerPreferences = koinInject<PlayerPreferences>()
val currentChapter by viewModel.currentChapter.collectAsState()
Row(
modifier = modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
) {
ControlsButton(
Icons.Default.LockOpen,
onClick = { viewModel.lockControls() },
onClick = onLockControls,
)
ControlsButton(
icon = Icons.Default.ScreenRotation,
onClick = { viewModel.cycleScreenRotations() }
onClick = onCycleRotation
)
val currentSpeed by viewModel.playbackSpeed.collectAsState()
ControlsButton(
text = stringResource(R.string.player_speed, currentSpeed),
text = stringResource(R.string.player_speed, playbackSpeed),
onClick = {
val newSpeed = if (currentSpeed >= 2) 0.25f else currentSpeed + 0.25f
viewModel.playbackSpeed.update { newSpeed }
MPVLib.setPropertyDouble("speed", newSpeed.toDouble())
val newSpeed = if (playbackSpeed >= 2) 0.25f else playbackSpeed + 0.25f
onPlaybackSpeedChange(newSpeed)
playerPreferences.defaultSpeed.set(newSpeed)
},
onLongClick = { viewModel.sheetShown.update { Sheets.PlaybackSpeed } }
onLongClick = { onOpenSheet(Sheets.PlaybackSpeed) },
)
AnimatedVisibility(
currentChapter != null && playerPreferences.currentChaptersIndicator.get(),
enter = fadeIn(),
exit = fadeOut(),
) {
CurrentChapter(
currentChapter!!,
onClick = { viewModel.sheetShown.update { Sheets.Chapters } },
chapter = currentChapter!!,
onClick = { onOpenSheet(Sheets.Chapters) }
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package live.mehiz.mpvkt.ui.player.controls

import android.annotation.SuppressLint
import android.os.Build
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
Expand All @@ -15,76 +14,56 @@ import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import live.mehiz.mpvkt.preferences.PlayerPreferences
import live.mehiz.mpvkt.preferences.preference.collectAsState
import live.mehiz.mpvkt.ui.custombuttons.getButtons
import live.mehiz.mpvkt.ui.player.PlayerActivity
import live.mehiz.mpvkt.ui.player.PlayerViewModel
import live.mehiz.mpvkt.ui.player.VideoAspect
import live.mehiz.mpvkt.database.entities.CustomButtonEntity
import live.mehiz.mpvkt.ui.player.controls.components.ControlsButton
import live.mehiz.mpvkt.ui.player.execute
import live.mehiz.mpvkt.ui.player.executeLongClick
import live.mehiz.mpvkt.ui.theme.spacing
import org.koin.compose.koinInject

@OptIn(ExperimentalFoundationApi::class)
@SuppressLint("NewApi")
@Composable
fun BottomRightPlayerControls(modifier: Modifier = Modifier) {
val viewModel = koinInject<PlayerViewModel>()
val playerPreferences = koinInject<PlayerPreferences>()
val aspect by playerPreferences.videoAspect.collectAsState()
val primaryCustomButtonId by playerPreferences.primaryCustomButtonId.collectAsState()
val customButtons by viewModel.customButtons.collectAsState()
fun BottomRightPlayerControls(
customButton: CustomButtonEntity?,
isPipAvailable: Boolean,
onAspectClick: () -> Unit,
onPipClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Row(modifier) {
if (primaryCustomButtonId != 0 && customButtons.getButtons().isNotEmpty()) {
val button = customButtons.getButtons().first { it.id == primaryCustomButtonId }
val interactionSource = remember { MutableInteractionSource() }

if (customButton != null) {
Box(
modifier = Modifier.padding(end = MaterialTheme.spacing.smaller),
) {
Button(onClick = {}) {
Text(text = button.title)
Text(text = customButton.title)
}
Box(
modifier = Modifier
.matchParentSize()
.combinedClickable(
onClick = { viewModel.executeCustomButton(button) },
onLongClick = { viewModel.executeCustomButtonLongClick(button) },
interactionSource = interactionSource,
onClick = customButton::execute,
onLongClick = customButton::executeLongClick,
interactionSource = remember { MutableInteractionSource() },
indication = null,
)
),
)
}
}

val activity = LocalContext.current as PlayerActivity
if (activity.isPipSupported) {
if (isPipAvailable) {
ControlsButton(
Icons.Default.PictureInPictureAlt,
onClick = {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
activity.enterPictureInPictureMode(activity.createPipParams())
} else {
activity.enterPictureInPictureMode()
}
},
onClick = onPipClick,
)
}

ControlsButton(
Icons.Default.AspectRatio,
onClick = {
when (aspect) {
VideoAspect.Fit -> viewModel.changeVideoAspect(VideoAspect.Stretch)
VideoAspect.Stretch -> viewModel.changeVideoAspect(VideoAspect.Crop)
VideoAspect.Crop -> viewModel.changeVideoAspect(VideoAspect.Fit)
}
},
onClick = onAspectClick,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ import org.koin.compose.koinInject
@Suppress("CyclomaticComplexMethod", "MultipleEmitters")
@Composable
fun GestureHandler(
viewModel: PlayerViewModel,
interactionSource: MutableInteractionSource,
modifier: Modifier = Modifier
) {
val viewModel = koinInject<PlayerViewModel>()
val playerPreferences = koinInject<PlayerPreferences>()
val audioPreferences = koinInject<AudioPreferences>()
val panelShown by viewModel.panelShown.collectAsState()
Expand Down
Loading

0 comments on commit 7c28812

Please sign in to comment.