Fix multiple issues in CFv2.
This commit is contained in:
parent
6be9225fbd
commit
3db83c1602
4 changed files with 105 additions and 17 deletions
|
@ -1,40 +1,101 @@
|
|||
package org.thoughtcrime.securesms.conversation.v2
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.MotionEvent
|
||||
import android.view.Window
|
||||
import androidx.activity.viewModels
|
||||
import androidx.fragment.app.Fragment
|
||||
import org.thoughtcrime.securesms.components.FragmentWrapperActivity
|
||||
import io.reactivex.rxjava3.subjects.PublishSubject
|
||||
import io.reactivex.rxjava3.subjects.Subject
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentComponent
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.StripeRepository
|
||||
import org.thoughtcrime.securesms.components.voice.VoiceNoteMediaController
|
||||
import org.thoughtcrime.securesms.components.voice.VoiceNoteMediaControllerOwner
|
||||
import org.thoughtcrime.securesms.util.Debouncer
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* Wrapper activity for ConversationFragment.
|
||||
*/
|
||||
class ConversationActivity : FragmentWrapperActivity(), VoiceNoteMediaControllerOwner {
|
||||
class ConversationActivity : PassphraseRequiredActivity(), VoiceNoteMediaControllerOwner, DonationPaymentComponent {
|
||||
|
||||
companion object {
|
||||
private const val STATE_WATERMARK = "share_data_watermark"
|
||||
}
|
||||
|
||||
private val theme = DynamicNoActionBarTheme()
|
||||
private val transitionDebouncer: Debouncer = Debouncer(150, TimeUnit.MILLISECONDS)
|
||||
private var shareDataTimestamp: Long = -1L
|
||||
|
||||
override val voiceNoteMediaController = VoiceNoteMediaController(this, true)
|
||||
|
||||
override val stripeRepository: StripeRepository by lazy { StripeRepository(this) }
|
||||
override val googlePayResultPublisher: Subject<DonationPaymentComponent.GooglePayResult> = PublishSubject.create()
|
||||
|
||||
private val motionEventRelay: MotionEventRelay by viewModels()
|
||||
|
||||
override fun onPreCreate() {
|
||||
theme.onCreate(this)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
|
||||
supportPostponeEnterTransition()
|
||||
transitionDebouncer.publish { supportStartPostponedEnterTransition() }
|
||||
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
shareDataTimestamp = savedInstanceState.getLong(STATE_WATERMARK, -1L)
|
||||
} else if (intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY != 0) {
|
||||
shareDataTimestamp = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
setContentView(R.layout.fragment_container)
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
replaceFragment()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
theme.onResume(this)
|
||||
}
|
||||
|
||||
override fun getFragment(): Fragment = ConversationFragment().apply {
|
||||
arguments = intent.extras
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putLong(STATE_WATERMARK, shareDataTimestamp)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
transitionDebouncer.clear()
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
error("ON NEW INTENT")
|
||||
setIntent(intent)
|
||||
replaceFragment()
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
googlePayResultPublisher.onNext(DonationPaymentComponent.GooglePayResult(requestCode, resultCode, data))
|
||||
}
|
||||
|
||||
private fun replaceFragment() {
|
||||
val fragment = ConversationFragment().apply {
|
||||
arguments = intent.extras
|
||||
}
|
||||
|
||||
supportFragmentManager
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragment_container, fragment)
|
||||
.disallowAddToBackStack()
|
||||
.commitNowAllowingStateLoss()
|
||||
}
|
||||
|
||||
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
|
||||
|
|
|
@ -227,7 +227,6 @@ import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModelV2
|
|||
import org.thoughtcrime.securesms.longmessage.LongMessageFragment
|
||||
import org.thoughtcrime.securesms.mediaoverview.MediaOverviewActivity
|
||||
import org.thoughtcrime.securesms.mediapreview.MediaIntentFactory
|
||||
import org.thoughtcrime.securesms.mediapreview.MediaIntentFactory.create
|
||||
import org.thoughtcrime.securesms.mediapreview.MediaPreviewV2Activity
|
||||
import org.thoughtcrime.securesms.mediasend.Media
|
||||
import org.thoughtcrime.securesms.mediasend.MediaSendActivityResult
|
||||
|
@ -436,6 +435,7 @@ class ConversationFragment :
|
|||
private lateinit var conversationItemDecorations: ConversationItemDecorations
|
||||
private lateinit var optionsMenuCallback: ConversationOptionsMenuCallback
|
||||
private lateinit var typingIndicatorDecoration: TypingIndicatorDecoration
|
||||
private lateinit var backPressedCallback: BackPressedDelegate
|
||||
|
||||
private var animationsAllowed = false
|
||||
private var actionMode: ActionMode? = null
|
||||
|
@ -773,6 +773,11 @@ class ConversationFragment :
|
|||
|
||||
private fun doAfterFirstRender() {
|
||||
Log.d(TAG, "doAfterFirstRender")
|
||||
activity?.supportStartPostponedEnterTransition()
|
||||
|
||||
backPressedCallback = BackPressedDelegate()
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, backPressedCallback)
|
||||
|
||||
attachmentManager = AttachmentManager(requireContext(), requireView(), AttachmentManagerListener())
|
||||
|
||||
EventBus.getDefault().registerForLifecycle(groupCallViewModel, viewLifecycleOwner)
|
||||
|
@ -900,6 +905,7 @@ class ConversationFragment :
|
|||
disposables.add(
|
||||
draftViewModel
|
||||
.state
|
||||
.distinctUntilChanged { previous, next -> previous.voiceNoteDraft == next.voiceNoteDraft }
|
||||
.subscribe {
|
||||
inputPanel.voiceNoteDraft = it.voiceNoteDraft
|
||||
updateToggleButtonState()
|
||||
|
@ -1897,6 +1903,21 @@ class ConversationFragment :
|
|||
composeText.clearFocus()
|
||||
}
|
||||
|
||||
private inner class BackPressedDelegate : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
Log.d(TAG, "onBackPressed()")
|
||||
if (reactionDelegate.isShowing) {
|
||||
reactionDelegate.hide()
|
||||
} else if (isSearchRequested) {
|
||||
searchMenuItem?.collapseActionView()
|
||||
} else if (args.conversationScreenType.isInBubble) {
|
||||
requireActivity().onBackPressed()
|
||||
} else {
|
||||
requireActivity().finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//region Message action handling
|
||||
|
||||
private fun handleReplyToMessage(conversationMessage: ConversationMessage) {
|
||||
|
@ -2490,7 +2511,13 @@ class ConversationFragment :
|
|||
|
||||
override fun goToMediaPreview(parent: ConversationItem, sharedElement: View, args: MediaIntentFactory.MediaPreviewArgs) {
|
||||
if (this@ConversationFragment.args.conversationScreenType.isInBubble) {
|
||||
requireActivity().startActivity(create(requireActivity(), args.skipSharedElementTransition(true)))
|
||||
val recipient = viewModel.recipientSnapshot ?: return
|
||||
val intent = ConversationIntents.createBuilderSync(requireActivity(), recipient.id, viewModel.threadId)
|
||||
.withStartingPosition(binding.conversationItemRecycler.getChildAdapterPosition(parent))
|
||||
.build()
|
||||
|
||||
requireActivity().startActivity(intent)
|
||||
requireActivity().startActivity(MediaIntentFactory.create(requireActivity(), args.skipSharedElementTransition(true)))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -2506,7 +2533,7 @@ class ConversationFragment :
|
|||
sharedElement.transitionName = MediaPreviewV2Activity.SHARED_ELEMENT_TRANSITION_NAME
|
||||
requireActivity().setExitSharedElementCallback(MaterialContainerTransformSharedElementCallback())
|
||||
val options = ActivityOptions.makeSceneTransitionAnimation(requireActivity(), sharedElement, MediaPreviewV2Activity.SHARED_ELEMENT_TRANSITION_NAME)
|
||||
requireActivity().startActivity(create(requireActivity(), args), options.toBundle())
|
||||
requireActivity().startActivity(MediaIntentFactory.create(requireActivity(), args), options.toBundle())
|
||||
}
|
||||
|
||||
override fun onEditedIndicatorClicked(messageRecord: MessageRecord) {
|
||||
|
@ -2655,13 +2682,13 @@ class ConversationFragment :
|
|||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
clearFocusedItem()
|
||||
adapter.toggleSelection(item)
|
||||
binding.conversationItemRecycler.invalidateItemDecorations()
|
||||
|
||||
actionMode = (requireActivity() as AppCompatActivity).startSupportActionMode(actionModeCallback)
|
||||
}
|
||||
} else {
|
||||
clearFocusedItem()
|
||||
adapter.toggleSelection(item)
|
||||
binding.conversationItemRecycler.invalidateItemDecorations()
|
||||
|
||||
actionMode = (requireActivity() as AppCompatActivity).startSupportActionMode(actionModeCallback)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ class ConversationRepository(
|
|||
identityRecordsState: IdentityRecordsState?
|
||||
): Completable {
|
||||
val sendCompletable = Completable.create { emitter ->
|
||||
if (body.isEmpty() && slideDeck?.containsMediaSlide() != true && preUploadResults.isEmpty()) {
|
||||
if (body.isEmpty() && slideDeck?.containsMediaSlide() != true && preUploadResults.isEmpty() && contacts.isEmpty()) {
|
||||
emitter.onError(InvalidMessageException("Message is empty!"))
|
||||
return@create
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ import kotlin.time.Duration
|
|||
* ConversationViewModel, which operates solely off of a thread id that never changes.
|
||||
*/
|
||||
class ConversationViewModel(
|
||||
private val threadId: Long,
|
||||
val threadId: Long,
|
||||
requestedStartingPosition: Int,
|
||||
private val repository: ConversationRepository,
|
||||
recipientRepository: ConversationRecipientRepository,
|
||||
|
|
Loading…
Add table
Reference in a new issue