WIP: integrate onBackPressed flow as callback

This sets up a little JavaFlow wrapper so we can register callbacks on
the back press flow in Java-land.

Inspired by one of the answers in
https://stackoverflow.com/questions/60605176/kotlin-flows-java-interop-callback

Kotlin generates default interface instances, but only if
`-Xjvm-default=all` is set in the compiler flags. The Java IDE
would propose using a lambda, which would fail because the kotlin
compiler would not generate the right ABI without that flag.
This commit is contained in:
Profpatsch 2024-12-23 20:28:27 +01:00
parent 10163e1082
commit 6c3f31a721
3 changed files with 48 additions and 0 deletions

View File

@ -88,6 +88,11 @@ android {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17
freeCompilerArgs += [
// Generate default method implementations for interfaces
// https://kotlinlang.org/docs/java-to-kotlin-interop.html#default-methods-in-interfaces
'-Xjvm-default=all'
]
}
sourceSets {

View File

@ -103,6 +103,7 @@ import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.InfoCache;
import org.schabi.newpipe.util.JavaFlow;
import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
@ -130,6 +131,7 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import kotlin.Unit;
@UnstableApi
@AndroidEntryPoint
@ -311,6 +313,11 @@ public final class VideoDetailFragment
newPlayerViewModel = new ViewModelProvider(this).get(NewPlayerViewModelImpl.class);
newPlayerViewModel.setNewPlayer(this.newPlayer);
newPlayerViewModel.setContentFitMode(ContentScale.FIT_INSIDE);
new JavaFlow<Unit>().collect(newPlayerViewModel.getOnBackPressed(), result -> {
Log.d(TAG, "NewPlayer forwarded backpress");
newPlayerViewModel.setNewPlayer(null);
newPlayer.pause();
});
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
showComments = prefs.getBoolean(getString(R.string.show_comments_key), true);

View File

@ -0,0 +1,36 @@
package org.schabi.newpipe.util
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
class JavaFlow<T>(
private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Default)
) {
interface OperatorCallback <T> {
fun onStart() = Unit
fun onCompletion(thr: Throwable?) = Unit
fun onResult(result: T)
}
fun collect(
flow: Flow<T>,
operatorCallback: OperatorCallback<T>,
) {
coroutineScope.launch {
flow
.onStart { operatorCallback.onStart() }
.onCompletion { operatorCallback.onCompletion(it) }
.collect { operatorCallback.onResult(it) }
}
}
fun close() {
coroutineScope.cancel()
}
}