kopia lustrzana https://github.com/ryukoposting/Signal-Android
Fix video controls becoming unresponsive after quickly paging.
rodzic
98a528f595
commit
4081ac2a83
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -79,7 +79,7 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment {
|
|||
|
||||
@Override
|
||||
public void onStopped() {
|
||||
events.onStopped();
|
||||
events.onStopped(getTag());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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);
|
||||
|
|
Ładowanie…
Reference in New Issue