From bd58c91d2c35d7fc04d2d90eb7b9a5078020adc9 Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Thu, 24 Feb 2022 17:39:56 -0400 Subject: [PATCH] Refactor viewer to prepare for enhanced video duration support. --- .../mediapreview/MediaPreviewFragment.java | 3 + .../mediapreview/VideoControlsDelegate.kt | 71 +++++++++++++++ .../VideoMediaPreviewFragment.java | 16 +++- .../stories/viewer/page/StoryPost.kt | 1 - .../viewer/page/StoryViewerPageFragment.kt | 88 +++++++++++++------ .../viewer/page/StoryViewerPageRepository.kt | 13 +-- .../viewer/page/StoryViewerPageState.kt | 3 + .../viewer/page/StoryViewerPageViewModel.kt | 43 ++++++--- .../viewer/page/StoryViewerPlaybackState.kt | 22 +++++ .../direct/StoryDirectReplyDialogFragment.kt | 2 +- ...toryGroupReplyBottomSheetDialogFragment.kt | 2 +- .../StoryViewsAndRepliesDialogFragment.kt | 2 +- .../StoryViewsBottomSheetDialogFragment.kt | 2 +- 13 files changed, 208 insertions(+), 60 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/mediapreview/VideoControlsDelegate.kt create mode 100644 app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPlaybackState.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewFragment.java b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewFragment.java index 90fd8ddfad..5ca20c0791 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewFragment.java @@ -101,5 +101,8 @@ public abstract class MediaPreviewFragment extends Fragment { public interface Events { boolean singleTapOnMedia(); void mediaNotAvailable(); + default @Nullable VideoControlsDelegate getVideoControlsDelegate() { + return null; + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/VideoControlsDelegate.kt b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/VideoControlsDelegate.kt new file mode 100644 index 0000000000..a5a728e45e --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/VideoControlsDelegate.kt @@ -0,0 +1,71 @@ +package org.thoughtcrime.securesms.mediapreview + +import android.net.Uri +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.core.Observable +import io.reactivex.rxjava3.subjects.BehaviorSubject +import io.reactivex.rxjava3.subjects.PublishSubject +import org.thoughtcrime.securesms.video.VideoPlayer + +/** + * Class to manage video playback in preview screen. + */ +class VideoControlsDelegate { + + private val playWhenReady: MutableMap = mutableMapOf() + private val playerSubject = BehaviorSubject.create() + private val playerReadySignal = PublishSubject.create() + val playerUpdates: Observable = playerReadySignal + .observeOn(AndroidSchedulers.mainThread()) + .flatMap { playerSubject } + .filter { it.videoPlayer != null } + .map { PlayerUpdate(it.uri, it.videoPlayer?.duration!!) } + + fun pause() = playerSubject.value?.videoPlayer?.pause() + + fun resume(uri: Uri) { + val player = playerSubject.value + if (player?.uri == uri) { + player.videoPlayer?.play() + } else { + playWhenReady[uri] = true + } + + playerSubject.value?.videoPlayer?.play() + } + + fun restart() { + playerSubject.value?.videoPlayer?.playbackPosition = 0L + } + + fun attachPlayer(uri: Uri, videoPlayer: VideoPlayer?) { + playerSubject.onNext(Player(uri, videoPlayer)) + + if ((videoPlayer?.duration ?: -1L) > 0L) { + playerReadySignal.onNext(Unit) + } else { + videoPlayer?.setPlayerStateCallbacks { + playerReadySignal.onNext(Unit) + } + } + + if (playWhenReady[uri] == true) { + playWhenReady[uri] = false + videoPlayer?.play() + } + } + + fun detachPlayer() { + playerSubject.onNext(Player()) + } + + private data class Player( + val uri: Uri = Uri.EMPTY, + val videoPlayer: VideoPlayer? = null + ) + + data class PlayerUpdate( + val mediaUri: Uri, + val duration: Long + ) +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/VideoMediaPreviewFragment.java b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/VideoMediaPreviewFragment.java index 0db216f10c..910bbd15ff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/VideoMediaPreviewFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/VideoMediaPreviewFragment.java @@ -6,6 +6,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; @@ -28,7 +29,8 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + Bundle savedInstanceState) + { View itemView = inflater.inflate(R.layout.media_preview_video_fragment, container, false); Bundle arguments = requireArguments(); Uri uri = arguments.getParcelable(DATA_URI); @@ -70,6 +72,10 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment { if (videoView != null && isVideoGif) { videoView.play(); } + + if (events.getVideoControlsDelegate() != null) { + events.getVideoControlsDelegate().attachPlayer(getUri(), videoView); + } } @Override @@ -77,10 +83,18 @@ public final class VideoMediaPreviewFragment extends MediaPreviewFragment { if (videoView != null) { videoView.pause(); } + + if (events.getVideoControlsDelegate() != null) { + events.getVideoControlsDelegate().detachPlayer(); + } } @Override public View getPlaybackControls() { return videoView != null && !isVideoGif ? videoView.getControlView() : null; } + + private @NonNull Uri getUri() { + return requireArguments().getParcelable(DATA_URI); + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryPost.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryPost.kt index 6d71527a1d..5edd18624d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryPost.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryPost.kt @@ -15,7 +15,6 @@ class StoryPost( val viewCount: Int, val replyCount: Int, val dateInMilliseconds: Long, - val durationMillis: Long, val attachment: Attachment, val conversationMessage: ConversationMessage ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageFragment.kt index 6733bdfbdd..318039d585 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageFragment.kt @@ -33,6 +33,7 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord import org.thoughtcrime.securesms.mediapreview.MediaPreviewFragment +import org.thoughtcrime.securesms.mediapreview.VideoControlsDelegate import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.stories.dialogs.StoryContextMenu @@ -48,6 +49,7 @@ import org.thoughtcrime.securesms.util.fragments.requireListener import org.thoughtcrime.securesms.util.views.TouchInterceptingFrameLayout import org.thoughtcrime.securesms.util.visible import java.util.Locale +import java.util.concurrent.TimeUnit import kotlin.math.abs class StoryViewerPageFragment : Fragment(R.layout.stories_viewer_fragment_page), MediaPreviewFragment.Events, MultiselectForwardBottomSheet.Callback { @@ -65,6 +67,8 @@ class StoryViewerPageFragment : Fragment(R.layout.stories_viewer_fragment_page), } ) + private val videoControlsDelegate = VideoControlsDelegate() + private val lifecycleDisposable = LifecycleDisposable() private val storyRecipientId: RecipientId @@ -122,10 +126,10 @@ class StoryViewerPageFragment : Fragment(R.layout.stories_viewer_fragment_page), cardWrapper.setOnTouchListener { _, event -> val result = gestureDetector.onTouchEvent(event) if (event.actionMasked == MotionEvent.ACTION_DOWN) { - progressBar.pause() + viewModel.setIsUserTouching(true) hideChrome() } else if (event.actionMasked == MotionEvent.ACTION_UP || event.actionMasked == MotionEvent.ACTION_CANCEL) { - resumeProgressIfNotDisplayingDialog() + viewModel.setIsUserTouching(false) showChrome() } @@ -147,6 +151,10 @@ class StoryViewerPageFragment : Fragment(R.layout.stories_viewer_fragment_page), .replace(R.id.story_content_container, createFragmentForPost(viewModel.getPostAt(newPageIndex))) .commit() } + + if (oldPageIndex == newPageIndex) { + videoControlsDelegate.restart() + } } override fun onFinished() { @@ -166,27 +174,45 @@ class StoryViewerPageFragment : Fragment(R.layout.stories_viewer_fragment_page), presentDistributionList(distributionList, post) presentCaption(caption, largeCaption, largeCaptionOverlay, post) - if (progressBar.segmentCount != state.posts.size) { + val durations: Map = state.posts + .mapIndexed { index, storyPost -> + index to (storyPost.attachment.uri?.let { state.durations[it] } ?: TimeUnit.SECONDS.toMillis(5)) + } + .toMap() + + if (progressBar.segmentCount != state.posts.size || progressBar.segmentDurations != durations) { progressBar.segmentCount = state.posts.size - progressBar.segmentDurations = state.posts.mapIndexed { index, storyPost -> index to storyPost.durationMillis }.toMap() - progressBar.start() + progressBar.segmentDurations = durations } + + viewModel.setAreSegmentsInitialized(true) } else if (state.selectedPostIndex >= state.posts.size) { callback.onFinishedPosts(storyRecipientId) } } + viewModel.storyViewerPlaybackState.observe(viewLifecycleOwner) { state -> + if (state.isPaused) { + pauseProgress() + } else { + resumeProgress() + } + } + lifecycleDisposable.bindTo(viewLifecycleOwner) lifecycleDisposable += viewModel.groupDirectReplyObservable.subscribe { opt -> if (opt.isPresent) { - progressBar.pause() when (val sheet = opt.get()) { is StoryViewerDialog.GroupDirectReply -> { onStartDirectReply(sheet.storyId, sheet.recipientId) } } - } else { - resumeProgress() + } + } + + lifecycleDisposable += videoControlsDelegate.playerUpdates.subscribe { update -> + if (update.duration > 0L) { + viewModel.setDuration(update.mediaUri, update.duration) } } @@ -195,7 +221,6 @@ class StoryViewerPageFragment : Fragment(R.layout.stories_viewer_fragment_page), override fun onPause() { super.onPause() - progressBar.pause() } override fun onResume() { @@ -205,14 +230,12 @@ class StoryViewerPageFragment : Fragment(R.layout.stories_viewer_fragment_page), progressBar.reset() progressBar.setPosition(viewModel.getRestartIndex()) } - - resumeProgressIfNotDisplayingDialog() } override fun onFinishForwardAction() = Unit override fun onDismissForwardSheet() { - viewModel.onForwardDismissed() + viewModel.setIsDisplayingForwardDialog(false) } private fun hideChrome() { @@ -264,18 +287,18 @@ class StoryViewerPageFragment : Fragment(R.layout.stories_viewer_fragment_page), constraintSet.applyTo(requireView() as ConstraintLayout) } - private fun resumeProgressIfNotDisplayingDialog() { - if (childFragmentManager.findFragmentByTag(BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG) == null) { - resumeProgress() - } - } - private fun resumeProgress() { if (progressBar.segmentCount != 0) { progressBar.start() + videoControlsDelegate.resume(viewModel.getPost().attachment.uri!!) } } + private fun pauseProgress() { + progressBar.pause() + videoControlsDelegate.pause() + } + private fun startReply() { val replyFragment: DialogFragment = when (viewModel.getSwipeToReplyState()) { StoryViewerPageState.ReplyState.NONE -> return @@ -285,12 +308,17 @@ class StoryViewerPageFragment : Fragment(R.layout.stories_viewer_fragment_page), StoryViewerPageState.ReplyState.GROUP_SELF -> StoryViewsAndRepliesDialogFragment.create(viewModel.getPost().id, viewModel.getPost().group!!.id, getViewsAndRepliesDialogStartPage()) } - progressBar.pause() + if (viewModel.getSwipeToReplyState() == StoryViewerPageState.ReplyState.PRIVATE) { + viewModel.setIsDisplayingDirectReplyDialog(true) + } else { + viewModel.setIsDisplayingViewsAndRepliesDialog(true) + } + replyFragment.showNow(childFragmentManager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG) } private fun onStartDirectReply(storyId: Long, recipientId: RecipientId) { - progressBar.pause() + viewModel.setIsDisplayingDirectReplyDialog(true) StoryDirectReplyDialogFragment.create( storyId = storyId, recipientId = recipientId @@ -359,7 +387,7 @@ class StoryViewerPageFragment : Fragment(R.layout.stories_viewer_fragment_page), largeCaptionOverlay.setOnClickListener { onHideCaptionOverlay(caption, largeCaption, largeCaptionOverlay) } - progressBar.pause() + viewModel.setIsDisplayingCaptionOverlay(true) } private fun onHideCaptionOverlay(caption: TextView, largeCaption: TextView, largeCaptionOverlay: View) { @@ -367,7 +395,7 @@ class StoryViewerPageFragment : Fragment(R.layout.stories_viewer_fragment_page), largeCaption.visible = false largeCaptionOverlay.visible = false largeCaptionOverlay.setOnClickListener(null) - resumeProgress() + viewModel.setIsDisplayingCaptionOverlay(false) } private fun presentFrom(from: TextView, storyPost: StoryPost) { @@ -420,20 +448,24 @@ class StoryViewerPageFragment : Fragment(R.layout.stories_viewer_fragment_page), } private fun createFragmentForPost(storyPost: StoryPost): Fragment { - return MediaPreviewFragment.newInstance(storyPost.attachment, true) + return MediaPreviewFragment.newInstance(storyPost.attachment, false) + } + + override fun getVideoControlsDelegate(): VideoControlsDelegate { + return videoControlsDelegate } private fun displayMoreContextMenu(anchor: View) { - progressBar.pause() + viewModel.setIsDisplayingContextMenu(true) StoryContextMenu.show( context = requireContext(), anchorView = anchor, storyViewerPageState = viewModel.getStateSnapshot(), onDismiss = { - viewModel.onDismissContextMenu() + viewModel.setIsDisplayingContextMenu(false) }, onForward = { storyPost -> - viewModel.startForward() + viewModel.setIsDisplayingForwardDialog(true) MultiselectForwardFragmentArgs.create( requireContext(), storyPost.conversationMessage.multiselectCollection.toSet(), @@ -456,9 +488,9 @@ class StoryViewerPageFragment : Fragment(R.layout.stories_viewer_fragment_page), StoryContextMenu.save(requireContext(), it.conversationMessage.messageRecord) }, onDelete = { - viewModel.startDelete() + viewModel.setIsDisplayingDeleteDialog(true) lifecycleDisposable += StoryContextMenu.delete(requireContext(), setOf(it.conversationMessage.messageRecord)).subscribe { _ -> - viewModel.onDeleteDismissed() + viewModel.setIsDisplayingDeleteDialog(false) viewModel.refresh() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageRepository.kt index 6582aafcd5..574dd56011 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageRepository.kt @@ -66,8 +66,7 @@ class StoryViewerPageRepository(context: Context) { viewCount = record.viewedReceiptCount, replyCount = SignalDatabase.mms.getNumberOfStoryReplies(record.id), dateInMilliseconds = record.dateSent, - durationMillis = getDurationMillis(record as MmsMessageRecord), - attachment = record.slideDeck.firstSlide!!.asAttachment(), + attachment = (record as MmsMessageRecord).slideDeck.firstSlide!!.asAttachment(), conversationMessage = ConversationMessage.ConversationMessageFactory.createWithUnresolvedData(context, record) ) @@ -125,16 +124,6 @@ class StoryViewerPageRepository(context: Context) { }.observeOn(Schedulers.io()) } - private fun getDurationMillis(record: MmsMessageRecord): Long { - val slide = record.slideDeck.firstSlide!! - return if (slide.hasVideo()) { - // TODO [stories] Remove duration from this stuff... Videos will need to actually start playback before we know how long they are... - 5000 - } else { - 5000 - } - } - fun hideStory(recipientId: RecipientId): Completable { return Completable.fromAction { SignalDatabase.recipients.setHideStory(recipientId, true) diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageState.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageState.kt index b0921bec94..01e2045143 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageState.kt @@ -1,7 +1,10 @@ package org.thoughtcrime.securesms.stories.viewer.page +import android.net.Uri + data class StoryViewerPageState( val posts: List = emptyList(), + val durations: Map = emptyMap(), val selectedPostIndex: Int = 0, val replyState: ReplyState = ReplyState.NONE ) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageViewModel.kt index a8ae7dc9b6..3417fc2211 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageViewModel.kt @@ -1,5 +1,6 @@ package org.thoughtcrime.securesms.stories.viewer.page +import android.net.Uri import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider @@ -28,6 +29,10 @@ class StoryViewerPageViewModel( private val storyViewerDialogSubject: Subject> = BehaviorSubject.createDefault(Optional.empty()) private val dismissSubject = PublishSubject.create() + private val storyViewerPlaybackStore = Store(StoryViewerPlaybackState()) + + val storyViewerPlaybackState: LiveData = storyViewerPlaybackStore.stateLiveData + val groupDirectReplyObservable: Observable> = Observable.combineLatest(storyViewerDialogSubject, dismissSubject) { sheet, dismissed -> if (sheet.isPresent && sheet.get().type != dismissed) { sheet @@ -50,6 +55,12 @@ class StoryViewerPageViewModel( refresh() } + fun setDuration(uri: Uri, duration: Long) { + store.update { + it.copy(durations = it.durations + (uri to duration)) + } + } + fun refresh() { disposables.clear() disposables += repository.getStoryPostsFor(recipientId).subscribe { posts -> @@ -95,32 +106,36 @@ class StoryViewerPageViewModel( storyViewerDialogSubject.onNext(Optional.of(StoryViewerDialog.GroupDirectReply(recipientId, storyId))) } - fun startForward() { - storyViewerDialogSubject.onNext(Optional.of(StoryViewerDialog.Forward)) + fun setIsDisplayingContextMenu(isDisplayingContextMenu: Boolean) { + storyViewerPlaybackStore.update { it.copy(isDisplayingContextMenu = isDisplayingContextMenu) } } - fun startDelete() { - storyViewerDialogSubject.onNext(Optional.of(StoryViewerDialog.Delete)) + fun setIsDisplayingForwardDialog(isDisplayingForwardDialog: Boolean) { + storyViewerPlaybackStore.update { it.copy(isDisplayingForwardDialog = isDisplayingForwardDialog) } } - fun onForwardDismissed() { - dismissSubject.onNext(StoryViewerDialog.Type.FORWARD) + fun setIsDisplayingDeleteDialog(isDisplayingDeleteDialog: Boolean) { + storyViewerPlaybackStore.update { it.copy(isDisplayingDeleteDialog = isDisplayingDeleteDialog) } } - fun onDeleteDismissed() { - dismissSubject.onNext(StoryViewerDialog.Type.DELETE) + fun setIsDisplayingViewsAndRepliesDialog(isDisplayingViewsAndRepliesDialog: Boolean) { + storyViewerPlaybackStore.update { it.copy(isDisplayingViewsAndRepliesDialog = isDisplayingViewsAndRepliesDialog) } } - fun onDismissContextMenu() { - dismissSubject.onNext(StoryViewerDialog.Type.CONTEXT_MENU) + fun setIsDisplayingDirectReplyDialog(isDisplayingDirectReplyDialog: Boolean) { + storyViewerPlaybackStore.update { it.copy(isDisplayingDirectReplyDialog = isDisplayingDirectReplyDialog) } } - fun onViewsAndRepliesSheetDismissed() { - dismissSubject.onNext(StoryViewerDialog.Type.VIEWS_AND_REPLIES) + fun setIsDisplayingCaptionOverlay(isDisplayingCaptionOverlay: Boolean) { + storyViewerPlaybackStore.update { it.copy(isDisplayingCaptionOverlay = isDisplayingCaptionOverlay) } } - fun onDirectReplyDismissed() { - dismissSubject.onNext(StoryViewerDialog.Type.DIRECT_REPLY) + fun setIsUserTouching(isUserTouching: Boolean) { + storyViewerPlaybackStore.update { it.copy(isUserTouching = isUserTouching) } + } + + fun setAreSegmentsInitialized(areSegmentsInitialized: Boolean) { + storyViewerPlaybackStore.update { it.copy(areSegmentsInitialized = areSegmentsInitialized) } } private fun resolveSwipeToReplyState(state: StoryViewerPageState, index: Int = state.selectedPostIndex): StoryViewerPageState.ReplyState { diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPlaybackState.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPlaybackState.kt new file mode 100644 index 0000000000..9e2925cb95 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPlaybackState.kt @@ -0,0 +1,22 @@ +package org.thoughtcrime.securesms.stories.viewer.page + +data class StoryViewerPlaybackState( + val areSegmentsInitialized: Boolean = false, + val isUserTouching: Boolean = false, + val isDisplayingForwardDialog: Boolean = false, + val isDisplayingDeleteDialog: Boolean = false, + val isDisplayingContextMenu: Boolean = false, + val isDisplayingViewsAndRepliesDialog: Boolean = false, + val isDisplayingDirectReplyDialog: Boolean = false, + val isDisplayingCaptionOverlay: Boolean = false +) { + val isPaused: Boolean = !areSegmentsInitialized || + isUserTouching || + isDisplayingCaptionOverlay || + isDisplayingForwardDialog || + isDisplayingDeleteDialog || + isDisplayingContextMenu || + isDisplayingViewsAndRepliesDialog || + isDisplayingDirectReplyDialog || + isDisplayingCaptionOverlay +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/direct/StoryDirectReplyDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/direct/StoryDirectReplyDialogFragment.kt index ededb1bf7a..dc1a1ba720 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/direct/StoryDirectReplyDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/direct/StoryDirectReplyDialogFragment.kt @@ -122,7 +122,7 @@ class StoryDirectReplyDialogFragment : override fun onDismiss(dialog: DialogInterface) { super.onDismiss(dialog) - storyViewerPageViewModel.onDirectReplyDismissed() + storyViewerPageViewModel.setIsDisplayingDirectReplyDialog(false) } companion object { diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyBottomSheetDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyBottomSheetDialogFragment.kt index ed012e6704..5e13a2121c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyBottomSheetDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyBottomSheetDialogFragment.kt @@ -66,7 +66,7 @@ class StoryGroupReplyBottomSheetDialogFragment : FixedRoundedCornerBottomSheetDi override fun onDismiss(dialog: DialogInterface) { super.onDismiss(dialog) - storyViewerPageViewModel.onViewsAndRepliesSheetDismissed() + storyViewerPageViewModel.setIsDisplayingViewsAndRepliesDialog(false) } override fun onStartDirectReply(recipientId: RecipientId) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/tabs/StoryViewsAndRepliesDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/tabs/StoryViewsAndRepliesDialogFragment.kt index d5f32bae8b..49b76b1c9f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/tabs/StoryViewsAndRepliesDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/tabs/StoryViewsAndRepliesDialogFragment.kt @@ -102,7 +102,7 @@ class StoryViewsAndRepliesDialogFragment : FixedRoundedCornerBottomSheetDialogFr override fun onDismiss(dialog: DialogInterface) { super.onDismiss(dialog) - storyViewerPageViewModel.onViewsAndRepliesSheetDismissed() + storyViewerPageViewModel.setIsDisplayingViewsAndRepliesDialog(false) } override fun onStartDirectReply(recipientId: RecipientId) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/views/StoryViewsBottomSheetDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/views/StoryViewsBottomSheetDialogFragment.kt index acaf1086d3..04f6786ff9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/views/StoryViewsBottomSheetDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/views/StoryViewsBottomSheetDialogFragment.kt @@ -40,7 +40,7 @@ class StoryViewsBottomSheetDialogFragment : FixedRoundedCornerBottomSheetDialogF override fun onDismiss(dialog: DialogInterface) { super.onDismiss(dialog) - storyViewerPageViewModel.onViewsAndRepliesSheetDismissed() + storyViewerPageViewModel.setIsDisplayingViewsAndRepliesDialog(false) } companion object {