Fix video controls becoming unresponsive after quickly paging.

main
Cody Henthorne 2022-12-19 14:30:37 -05:00 zatwierdzone przez GitHub
rodzic 98a528f595
commit 4081ac2a83
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
6 zmienionych plików z 59 dodań i 25 usunięć

Wyświetl plik

@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.mediapreview;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -99,7 +98,7 @@ public abstract class MediaPreviewFragment extends Fragment {
void unableToPlayMedia();
void onMediaReady();
void onPlaying();
void onStopped();
void onStopped(@Nullable String tag);
default @Nullable VideoControlsDelegate getVideoControlsDelegate() {
return null;
}

Wyświetl plik

@ -6,14 +6,20 @@ import androidx.viewpager2.adapter.FragmentStateAdapter
import org.thoughtcrime.securesms.attachments.Attachment
import org.thoughtcrime.securesms.mediasend.Media
import org.thoughtcrime.securesms.util.MediaUtil
import org.thoughtcrime.securesms.util.adapter.StableIdGenerator
class MediaPreviewV2Adapter(val fragment: Fragment) : FragmentStateAdapter(fragment) {
class MediaPreviewV2Adapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
private var items: List<Attachment> = listOf()
private val stableIdGenerator = StableIdGenerator<Attachment>()
override fun getItemCount(): Int {
return items.count()
}
override fun getItemId(position: Int): Long {
return stableIdGenerator.getId(items[position])
}
override fun createFragment(position: Int): Fragment {
val attachment: Attachment = items[position]
@ -38,6 +44,14 @@ class MediaPreviewV2Adapter(val fragment: Fragment) : FragmentStateAdapter(fragm
return fragment
}
fun getFragmentTag(position: Int): String? {
if (position < 0 || position > itemCount) {
return null
}
return "f${getItemId(position)}"
}
fun findItemPosition(media: Media): Int {
return items.indexOfFirst { it.uri == media.uri }
}

Wyświetl plik

@ -75,15 +75,15 @@ import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt
class MediaPreviewV2Fragment : LoggingFragment(R.layout.fragment_media_preview_v2), MediaPreviewFragment.Events {
private val TAG = Log.tag(MediaPreviewV2Fragment::class.java)
private val lifecycleDisposable = LifecycleDisposable()
private val binding by ViewBinderDelegate(FragmentMediaPreviewV2Binding::bind)
private val viewModel: MediaPreviewV2ViewModel by viewModels()
private val debouncer = Debouncer(2, TimeUnit.SECONDS)
private lateinit var fullscreenHelper: FullscreenHelper
private lateinit var pagerAdapter: MediaPreviewV2Adapter
private lateinit var albumRailAdapter: MediaRailAdapter
private lateinit var fullscreenHelper: FullscreenHelper
private var individualItemWidth: Int = 0
@ -108,9 +108,14 @@ class MediaPreviewV2Fragment : LoggingFragment(R.layout.fragment_media_preview_v
initializeAlbumRail()
initializeFullScreenUi()
anchorMarginsToBottomInsets(binding.mediaPreviewDetailsContainer)
lifecycleDisposable += viewModel.state.distinctUntilChanged().observeOn(AndroidSchedulers.mainThread()).subscribe {
bindCurrentState(it)
}
lifecycleDisposable +=
viewModel
.state
.distinctUntilChanged()
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
bindCurrentState(it)
}
}
private fun initializeViewModel(args: MediaIntentFactory.MediaPreviewArgs) {
@ -141,8 +146,8 @@ class MediaPreviewV2Fragment : LoggingFragment(R.layout.fragment_media_preview_v
private fun initializeViewPager() {
binding.mediaPager.offscreenPageLimit = OFFSCREEN_PAGE_LIMIT_DEFAULT
binding.mediaPager.setPageTransformer(MarginPageTransformer(ViewUtil.dpToPx(24)))
val adapter = MediaPreviewV2Adapter(this)
binding.mediaPager.adapter = adapter
pagerAdapter = MediaPreviewV2Adapter(this)
binding.mediaPager.adapter = pagerAdapter
binding.mediaPager.registerOnPageChangeCallback(object : OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
@ -187,14 +192,13 @@ class MediaPreviewV2Fragment : LoggingFragment(R.layout.fragment_media_preview_v
private fun bindDataLoadedState(currentState: MediaPreviewV2State) {
val currentPosition = currentState.position
val fragmentAdapter = binding.mediaPager.adapter as MediaPreviewV2Adapter
val backingItems = currentState.mediaRecords.mapNotNull { it.attachment }
if (backingItems.isEmpty()) {
onMediaNotAvailable()
return
}
fragmentAdapter.updateBackingItems(backingItems)
pagerAdapter.updateBackingItems(backingItems)
if (binding.mediaPager.currentItem != currentPosition) {
binding.mediaPager.setCurrentItem(currentPosition, false)
@ -212,12 +216,12 @@ class MediaPreviewV2Fragment : LoggingFragment(R.layout.fragment_media_preview_v
return
}
val currentPosition = currentState.position
val currentPosition: Int = currentState.position
val currentItem: MediaTable.MediaRecord = currentState.mediaRecords[currentPosition]
val currentItemTag: String? = pagerAdapter.getFragmentTag(currentPosition)
// pause all other fragments
childFragmentManager.fragments.map { fragment ->
if (fragment.tag != "f$currentPosition") {
childFragmentManager.fragments.forEach { fragment ->
if (fragment.tag != currentItemTag) {
(fragment as? MediaPreviewFragment)?.pause()
}
}
@ -232,6 +236,8 @@ class MediaPreviewV2Fragment : LoggingFragment(R.layout.fragment_media_preview_v
currentState.albums[currentItem.attachment?.mmsId] ?: emptyList()
}
bindAlbumRail(albumThumbnailMedia, currentItem)
fullscreenHelper.showSystemUI()
crossfadeViewIn(binding.mediaPreviewDetailsContainer)
}
@ -349,11 +355,12 @@ class MediaPreviewV2Fragment : LoggingFragment(R.layout.fragment_media_preview_v
}
}
private fun getMediaPreviewFragmentFromChildFragmentManager(currentPosition: Int) = childFragmentManager.findFragmentByTag("f$currentPosition") as? MediaPreviewFragment
private fun getMediaPreviewFragmentFromChildFragmentManager(currentPosition: Int): MediaPreviewFragment? {
return childFragmentManager.findFragmentByTag(pagerAdapter.getFragmentTag(currentPosition)) as? MediaPreviewFragment
}
private fun jumpViewPagerToMedia(media: Media) {
val viewPagerAdapter = binding.mediaPager.adapter as MediaPreviewV2Adapter
val position = viewPagerAdapter.findItemPosition(media)
val position = pagerAdapter.findItemPosition(media)
binding.mediaPager.setCurrentItem(position, true)
}
@ -432,8 +439,15 @@ class MediaPreviewV2Fragment : LoggingFragment(R.layout.fragment_media_preview_v
debouncer.publish { fullscreenHelper.hideSystemUI() }
}
override fun onStopped() {
debouncer.clear()
override fun onStopped(tag: String?) {
if (tag == null) {
return
}
if (pagerAdapter.getFragmentTag(viewModel.currentPosition) == tag) {
debouncer.clear()
fullscreenHelper.showSystemUI()
}
}
override fun unableToPlayMedia() {
@ -493,6 +507,7 @@ class MediaPreviewV2Fragment : LoggingFragment(R.layout.fragment_media_preview_v
}
}
@Suppress("DEPRECATION")
fun performSaveToDisk(mediaItem: MediaTable.MediaRecord) {
val saveTask = SaveAttachmentTask(requireContext())
val saveDate = if (mediaItem.date > 0) mediaItem.date else System.currentTimeMillis()
@ -587,6 +602,8 @@ class MediaPreviewV2Fragment : LoggingFragment(R.layout.fragment_media_preview_v
}
companion object {
private val TAG = Log.tag(MediaPreviewV2Fragment::class.java)
const val ARGS_KEY: String = "args"
@JvmStatic

Wyświetl plik

@ -10,7 +10,6 @@ import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign
import io.reactivex.rxjava3.schedulers.Schedulers
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.attachments.AttachmentId
import org.thoughtcrime.securesms.attachments.DatabaseAttachment
import org.thoughtcrime.securesms.database.MediaTable
@ -19,12 +18,14 @@ import org.thoughtcrime.securesms.util.rx.RxStore
import java.util.Optional
class MediaPreviewV2ViewModel : ViewModel() {
private val TAG = Log.tag(MediaPreviewV2ViewModel::class.java)
private val store = RxStore(MediaPreviewV2State())
private val disposables = CompositeDisposable()
private val repository: MediaPreviewRepository = MediaPreviewRepository()
val state: Flowable<MediaPreviewV2State> = store.stateFlowable.observeOn(AndroidSchedulers.mainThread())
val currentPosition: Int
get() = store.state.position
fun fetchAttachments(startingAttachmentId: AttachmentId, threadId: Long, sorting: MediaTable.Sorting, forceRefresh: Boolean = false) {
if (store.state.loadState == MediaPreviewV2State.LoadState.INIT || forceRefresh) {

Wyświetl plik

@ -79,7 +79,7 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment {
@Override
public void onStopped() {
events.onStopped();
events.onStopped(getTag());
}
@Override

Wyświetl plik

@ -252,7 +252,10 @@ public class VideoPlayer extends FrameLayout {
if (this.exoPlayer != null) {
exoView.setPlayer(null);
exoControls.setPlayer(null);
if (exoPlayer.equals(exoControls.getPlayer())) {
exoControls.setPlayer(null);
}
exoPlayer.removeListener(playerListener);
exoPlayer.removeListener(exoPlayerListener);