From 63334f5893a275fb1edfb3a15d06ec6d6b957b2c Mon Sep 17 00:00:00 2001 From: Christian Schabesberger Date: Mon, 26 Aug 2024 12:27:55 +0200 Subject: [PATCH] convert all callbacks to flows --- .../newpipe/newplayer/ActivityBrainSlug.kt | 16 ++++++++++----- .../newpipe/newplayer/NewPlayerException.kt | 20 +++++++++++++++++++ .../newplayer/model/VideoPlayerViewModel.kt | 9 ++------- .../model/VideoPlayerViewModelImpl.kt | 20 ++++++++++--------- .../model/ViewoPlayerViewModelDummy.kt | 8 ++++---- 5 files changed, 48 insertions(+), 25 deletions(-) diff --git a/new-player/src/main/java/net/newpipe/newplayer/ActivityBrainSlug.kt b/new-player/src/main/java/net/newpipe/newplayer/ActivityBrainSlug.kt index 5ee92fe..0a80831 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ActivityBrainSlug.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ActivityBrainSlug.kt @@ -23,10 +23,17 @@ package net.newpipe.newplayer import android.view.View import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch import net.newpipe.newplayer.model.VideoPlayerViewModel class ActivityBrainSlug(val viewModel: VideoPlayerViewModel) { + val brainSlugScope = CoroutineScope(Dispatchers.Main + Job()) + var rootView: View? = null set(value) { field = value @@ -65,9 +72,9 @@ class ActivityBrainSlug(val viewModel: VideoPlayerViewModel) { } init { - viewModel.addCallbackListener(object : VideoPlayerViewModel.Listener { - override fun onFullscreenToggle(isFullscreen: Boolean) { - if (isFullscreen) { + brainSlugScope.launch { + viewModel.uiState.collect { uiState -> + if (uiState.uiMode.fullscreen) { removeSystemInsets() viewsToHideOnFullscreen.forEach { it.visibility = View.GONE } fullscreenPlayerView?.visibility = View.VISIBLE @@ -77,8 +84,7 @@ class ActivityBrainSlug(val viewModel: VideoPlayerViewModel) { fullscreenPlayerView?.visibility = View.GONE } } - - }) + } } fun addViewToHideOnFullscreen(view: View) { diff --git a/new-player/src/main/java/net/newpipe/newplayer/NewPlayerException.kt b/new-player/src/main/java/net/newpipe/newplayer/NewPlayerException.kt index 3f05652..8ba11bf 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/NewPlayerException.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/NewPlayerException.kt @@ -1,3 +1,23 @@ +/* NewPlayer + * + * @author Christian Schabesberger + * + * Copyright (C) NewPipe e.V. 2024 + * + * NewPlayer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * NewPlayer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NewPlayer. If not, see . + */ + package net.newpipe.newplayer class NewPlayerException : Exception { diff --git a/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModel.kt b/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModel.kt index 9d5f5a6..0240a43 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModel.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModel.kt @@ -22,6 +22,7 @@ package net.newpipe.newplayer.model import android.os.Bundle import androidx.media3.common.Player +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import net.newpipe.newplayer.NewPlayer import net.newpipe.newplayer.ui.ContentScale @@ -34,8 +35,8 @@ interface VideoPlayerViewModel { var minContentRatio: Float var maxContentRatio: Float var contentFitMode: ContentScale + val embeddedPlayerDraggedDownBy: SharedFlow - fun addCallbackListener(listener: Listener) fun initUIState(instanceState: Bundle) fun play() fun pause() @@ -52,10 +53,4 @@ interface VideoPlayerViewModel { fun finishFastSeek() fun brightnessChange(changeRate: Float, systemBrightness: Float) fun volumeChange(changeRate: Float) - - interface Listener { - fun onFullscreenToggle(isFullscreen: Boolean) {} - - fun embeddedPlayerDraggedDown(offset: Float) {} - } } \ No newline at end of file diff --git a/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModelImpl.kt b/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModelImpl.kt index d146fcd..b57738a 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModelImpl.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModelImpl.kt @@ -26,15 +26,20 @@ import android.os.Build import android.os.Bundle import android.util.Log import androidx.annotation.RequiresApi +import androidx.collection.mutableFloatFloatMapOf import androidx.core.content.ContextCompat.getSystemService import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope +import androidx.lifecycle.viewmodel.compose.viewModel import androidx.media3.common.Player import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Job import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow import javax.inject.Inject import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update @@ -63,8 +68,6 @@ class VideoPlayerViewModelImpl @Inject constructor( private val audioManager = getSystemService(application.applicationContext, AudioManager::class.java)!! - var callbackListeners: MutableList = ArrayList() - init { val soundVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC).toFloat() / audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC).toFloat() @@ -118,6 +121,9 @@ class VideoPlayerViewModelImpl @Inject constructor( } } + var mutableEmbeddedPlayerDraggedDownBy = MutableSharedFlow () + override val embeddedPlayerDraggedDownBy = mutableEmbeddedPlayerDraggedDownBy.asSharedFlow() + private fun installNewPlayer() { internalPlayer?.let { player -> Log.d(TAG, "Install player: ${player.videoSize.width}") @@ -195,10 +201,6 @@ class VideoPlayerViewModelImpl @Inject constructor( } } - override fun addCallbackListener(listener: VideoPlayerViewModel.Listener) { - callbackListeners.add(listener) - } - override fun play() { hideUi() newPlayer?.play() @@ -285,7 +287,9 @@ class VideoPlayerViewModelImpl @Inject constructor( } override fun embeddedDraggedDown(offset: Float) { - callbackListeners.forEach { it?.embeddedPlayerDraggedDown(offset) } + viewModelScope.launch { + mutableEmbeddedPlayerDraggedDownBy.emit(offset) + } } override fun fastSeek(count: Int) { @@ -344,14 +348,12 @@ class VideoPlayerViewModelImpl @Inject constructor( } override fun switchToEmbeddedView() { - callbackListeners.forEach { it?.onFullscreenToggle(false) } uiVisibilityJob?.cancel() finishFastSeek() updateUiMode(UIModeState.EMBEDDED_VIDEO) } override fun switchToFullscreen() { - callbackListeners.forEach { it?.onFullscreenToggle(true) } uiVisibilityJob?.cancel() finishFastSeek() updateUiMode(UIModeState.FULLSCREEN_VIDEO) diff --git a/new-player/src/main/java/net/newpipe/newplayer/model/ViewoPlayerViewModelDummy.kt b/new-player/src/main/java/net/newpipe/newplayer/model/ViewoPlayerViewModelDummy.kt index b4f99cc..ed041c5 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/model/ViewoPlayerViewModelDummy.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/model/ViewoPlayerViewModelDummy.kt @@ -2,7 +2,10 @@ package net.newpipe.newplayer.model import android.os.Bundle import androidx.media3.common.Player +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow import net.newpipe.newplayer.NewPlayer import net.newpipe.newplayer.ui.ContentScale @@ -13,15 +16,12 @@ open class VideoPlayerViewModelDummy : VideoPlayerViewModel { override var minContentRatio = 4F / 3F override var maxContentRatio = 16F / 9F override var contentFitMode = ContentScale.FIT_INSIDE + override val embeddedPlayerDraggedDownBy = MutableSharedFlow().asSharedFlow() override fun initUIState(instanceState: Bundle) { println("dummy impl") } - override fun addCallbackListener(listener: VideoPlayerViewModel.Listener) { - println("dummy impl") - } - override fun play() { println("dummy impl") }