mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-23 12:38:33 +00:00
CFV2 Implement delete, forward, view once handling.
This commit is contained in:
committed by
Cody Henthorne
parent
a656d65d1d
commit
399421e20e
@@ -121,6 +121,8 @@ import org.thoughtcrime.securesms.conversation.colors.RecyclerViewColorizer
|
|||||||
import org.thoughtcrime.securesms.conversation.mutiselect.ConversationItemAnimator
|
import org.thoughtcrime.securesms.conversation.mutiselect.ConversationItemAnimator
|
||||||
import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectItemDecoration
|
import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectItemDecoration
|
||||||
import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart
|
import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart
|
||||||
|
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment
|
||||||
|
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
|
||||||
import org.thoughtcrime.securesms.conversation.quotes.MessageQuotesBottomSheet
|
import org.thoughtcrime.securesms.conversation.quotes.MessageQuotesBottomSheet
|
||||||
import org.thoughtcrime.securesms.conversation.ui.edit.EditMessageHistoryDialog
|
import org.thoughtcrime.securesms.conversation.ui.edit.EditMessageHistoryDialog
|
||||||
import org.thoughtcrime.securesms.conversation.ui.error.EnableCallNotificationSettingsDialog
|
import org.thoughtcrime.securesms.conversation.ui.error.EnableCallNotificationSettingsDialog
|
||||||
@@ -177,6 +179,8 @@ import org.thoughtcrime.securesms.recipients.RecipientFormattingException
|
|||||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||||
import org.thoughtcrime.securesms.recipients.ui.bottomsheet.RecipientBottomSheetDialogFragment
|
import org.thoughtcrime.securesms.recipients.ui.bottomsheet.RecipientBottomSheetDialogFragment
|
||||||
import org.thoughtcrime.securesms.registration.RegistrationNavigationActivity
|
import org.thoughtcrime.securesms.registration.RegistrationNavigationActivity
|
||||||
|
import org.thoughtcrime.securesms.revealable.ViewOnceMessageActivity
|
||||||
|
import org.thoughtcrime.securesms.revealable.ViewOnceUtil
|
||||||
import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet
|
import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet
|
||||||
import org.thoughtcrime.securesms.stickers.StickerLocator
|
import org.thoughtcrime.securesms.stickers.StickerLocator
|
||||||
import org.thoughtcrime.securesms.stickers.StickerPackPreviewActivity
|
import org.thoughtcrime.securesms.stickers.StickerPackPreviewActivity
|
||||||
@@ -185,6 +189,7 @@ import org.thoughtcrime.securesms.stories.viewer.StoryViewerActivity
|
|||||||
import org.thoughtcrime.securesms.util.BottomSheetUtil
|
import org.thoughtcrime.securesms.util.BottomSheetUtil
|
||||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||||
import org.thoughtcrime.securesms.util.ContextUtil
|
import org.thoughtcrime.securesms.util.ContextUtil
|
||||||
|
import org.thoughtcrime.securesms.util.DeleteDialog
|
||||||
import org.thoughtcrime.securesms.util.DrawableUtil
|
import org.thoughtcrime.securesms.util.DrawableUtil
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
import org.thoughtcrime.securesms.util.FeatureFlags
|
||||||
import org.thoughtcrime.securesms.util.FullscreenHelper
|
import org.thoughtcrime.securesms.util.FullscreenHelper
|
||||||
@@ -580,7 +585,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun invalidateOptionsMenu() {
|
private fun invalidateOptionsMenu() {
|
||||||
// TODO [alex] -- Handle search... is there a better way to manage this state? Maybe an event system?
|
// TODO [cfv2] -- Handle search... is there a better way to manage this state? Maybe an event system?
|
||||||
conversationOptionsMenuProvider.onCreateMenu(binding.toolbar.menu, requireActivity().menuInflater)
|
conversationOptionsMenuProvider.onCreateMenu(binding.toolbar.menu, requireActivity().menuInflater)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -808,7 +813,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
quickAttachment.hide()
|
quickAttachment.hide()
|
||||||
inlineAttachment.hide()
|
inlineAttachment.hide()
|
||||||
}
|
}
|
||||||
// todo [cody] draftViewModel.voiceNoteDraft != null) { {
|
// todo [cfv2] draftViewModel.voiceNoteDraft != null) { {
|
||||||
// buttonToggle.display(sendButton)
|
// buttonToggle.display(sendButton)
|
||||||
// quickAttachment.hide()
|
// quickAttachment.hide()
|
||||||
// inlineAttachment.hide()
|
// inlineAttachment.hide()
|
||||||
@@ -823,7 +828,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
buttonToggle.display(sendButton)
|
buttonToggle.display(sendButton)
|
||||||
quickAttachment.hide()
|
quickAttachment.hide()
|
||||||
|
|
||||||
if (!attachmentManager.isAttachmentPresent) { // todo [cody] && !linkPreviewViewModel.hasLinkPreviewUi()) {
|
if (!attachmentManager.isAttachmentPresent) { // todo [cfv2] && !linkPreviewViewModel.hasLinkPreviewUi()) {
|
||||||
inlineAttachment.show()
|
inlineAttachment.show()
|
||||||
} else {
|
} else {
|
||||||
inlineAttachment.hide()
|
inlineAttachment.hide()
|
||||||
@@ -872,14 +877,14 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo [cody] fragment.setLastSeen(0);
|
// todo [cfv2] fragment.setLastSeen(0);
|
||||||
|
|
||||||
scrollToPositionDelegate.resetScrollPosition()
|
scrollToPositionDelegate.resetScrollPosition()
|
||||||
attachmentManager.cleanup()
|
attachmentManager.cleanup()
|
||||||
|
|
||||||
// todo [cody] updateLinkPreviewState();
|
// todo [cfv2] updateLinkPreviewState();
|
||||||
|
|
||||||
// todo [cody] draftViewModel.onSendComplete(threadId);
|
// todo [cfv2] draftViewModel.onSendComplete(threadId);
|
||||||
|
|
||||||
inputPanel.exitEditMessageMode()
|
inputPanel.exitEditMessageMode()
|
||||||
}
|
}
|
||||||
@@ -1087,7 +1092,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
composeText.clearFocus()
|
composeText.clearFocus()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// TODO [alex]
|
// TODO [cfv2]
|
||||||
if (attachmentKeyboardStub.resolved()) {
|
if (attachmentKeyboardStub.resolved()) {
|
||||||
attachmentKeyboardStub.get().hide(true);
|
attachmentKeyboardStub.get().hide(true);
|
||||||
}
|
}
|
||||||
@@ -1097,31 +1102,39 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
//region Message action handling
|
//region Message action handling
|
||||||
|
|
||||||
private fun handleReplyToMessage(conversationMessage: ConversationMessage) {
|
private fun handleReplyToMessage(conversationMessage: ConversationMessage) {
|
||||||
// TODO [alex] -- Not implemented yet.
|
// TODO [cfv2] -- Not implemented yet.
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleEditMessage(conversationMessage: ConversationMessage) {
|
private fun handleEditMessage(conversationMessage: ConversationMessage) {
|
||||||
// TODO [alex] -- Not implemented yet.
|
// TODO [cfv2] -- Not implemented yet.
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleForwardMessageParts(messageParts: Set<MultiselectPart>) {
|
private fun handleForwardMessageParts(messageParts: Set<MultiselectPart>) {
|
||||||
// TODO [alex] -- Not implemented yet.
|
inputPanel.clearQuote()
|
||||||
|
|
||||||
|
MultiselectForwardFragmentArgs.create(requireContext(), messageParts) { args ->
|
||||||
|
MultiselectForwardFragment.showBottomSheet(childFragmentManager, args)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleSaveAttachment(record: MediaMmsMessageRecord) {
|
private fun handleSaveAttachment(record: MediaMmsMessageRecord) {
|
||||||
// TODO [alex] -- Not implemented yet.
|
// TODO [cfv2] -- Not implemented yet.
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleCopyMessage(messageParts: Set<MultiselectPart>) {
|
private fun handleCopyMessage(messageParts: Set<MultiselectPart>) {
|
||||||
// TODO [alex] -- Not implemented yet.
|
// TODO [cfv2] -- Not implemented yet.
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleDisplayDetails(conversationMessage: ConversationMessage) {
|
private fun handleDisplayDetails(conversationMessage: ConversationMessage) {
|
||||||
// TODO [alex] -- Not implemented yet.
|
val recipientSnapshot = viewModel.recipientSnapshot ?: return
|
||||||
|
MessageDetailsFragment.create(conversationMessage.messageRecord, recipientSnapshot.id).show(parentFragmentManager, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleDeleteMessages(messageParts: Set<MultiselectPart>) {
|
private fun handleDeleteMessages(messageParts: Set<MultiselectPart>) {
|
||||||
// TODO [alex] -- Not implemented yet.
|
disposables += DeleteDialog.show(
|
||||||
|
context = requireContext(),
|
||||||
|
messageRecords = messageParts.map(MultiselectPart::getMessageRecord).toSet()
|
||||||
|
).subscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
@@ -1249,7 +1262,28 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewOnceMessageClicked(messageRecord: MmsMessageRecord) {
|
override fun onViewOnceMessageClicked(messageRecord: MmsMessageRecord) {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
if (!messageRecord.isViewOnce) {
|
||||||
|
error("Non-revealable message clicked.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ViewOnceUtil.isViewable(messageRecord)) {
|
||||||
|
val toastText = if (messageRecord.isOutgoing) {
|
||||||
|
R.string.ConversationFragment_outgoing_view_once_media_files_are_automatically_removed
|
||||||
|
} else {
|
||||||
|
R.string.ConversationFragment_you_already_viewed_this_message
|
||||||
|
}
|
||||||
|
|
||||||
|
toast(toastText)
|
||||||
|
}
|
||||||
|
|
||||||
|
disposables += viewModel.getTemporaryViewOnceUri(messageRecord).subscribeBy(
|
||||||
|
onSuccess = {
|
||||||
|
startActivity(ViewOnceMessageActivity.getIntent(requireContext(), messageRecord.id, it))
|
||||||
|
},
|
||||||
|
onComplete = {
|
||||||
|
toast(R.string.ConversationFragment_failed_to_open_message)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSharedContactDetailsClicked(contact: Contact, avatarTransitionView: View) {
|
override fun onSharedContactDetailsClicked(contact: Contact, avatarTransitionView: View) {
|
||||||
@@ -1507,7 +1541,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemClick(item: MultiselectPart?) {
|
override fun onItemClick(item: MultiselectPart?) {
|
||||||
// TODO [alex] -- ("Not yet implemented")
|
// TODO [cfv2] -- ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemLongClick(itemView: View, item: MultiselectPart) {
|
override fun onItemLongClick(itemView: View, item: MultiselectPart) {
|
||||||
@@ -1554,7 +1588,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
|
|
||||||
val snapshot = ConversationItemSelection.snapshotView(itemView, binding.conversationItemRecycler, messageRecord, videoBitmap)
|
val snapshot = ConversationItemSelection.snapshotView(itemView, binding.conversationItemRecycler, messageRecord, videoBitmap)
|
||||||
|
|
||||||
// TODO [alex] -- Should only have a focused view if the keyboard was open.
|
// TODO [cfv2] -- Should only have a focused view if the keyboard was open.
|
||||||
val focusedView = null // itemView.rootView.findFocus()
|
val focusedView = null // itemView.rootView.findFocus()
|
||||||
val bodyBubble = itemView.bodyBubble!!
|
val bodyBubble = itemView.bodyBubble!!
|
||||||
val selectedConversationModel = SelectedConversationModel(
|
val selectedConversationModel = SelectedConversationModel(
|
||||||
@@ -1585,7 +1619,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
}
|
}
|
||||||
|
|
||||||
val conversationItem: ConversationItem = itemView
|
val conversationItem: ConversationItem = itemView
|
||||||
val isAttachmentKeyboardOpen = false /* TODO [alex] -- isAttachmentKeyboardOpen */
|
val isAttachmentKeyboardOpen = false /* TODO [cfv2] -- isAttachmentKeyboardOpen */
|
||||||
handleReaction(
|
handleReaction(
|
||||||
item.conversationMessage,
|
item.conversationMessage,
|
||||||
ReactionsToolbarListener(item.conversationMessage),
|
ReactionsToolbarListener(item.conversationMessage),
|
||||||
@@ -1665,7 +1699,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
val recipient: Recipient? = viewModel.recipientSnapshot
|
val recipient: Recipient? = viewModel.recipientSnapshot
|
||||||
return ConversationOptionsMenu.Snapshot(
|
return ConversationOptionsMenu.Snapshot(
|
||||||
recipient = recipient,
|
recipient = recipient,
|
||||||
isPushAvailable = true, // TODO [alex]
|
isPushAvailable = true, // TODO [cfv2]
|
||||||
canShowAsBubble = Observable.empty(),
|
canShowAsBubble = Observable.empty(),
|
||||||
isActiveGroup = recipient?.isActiveGroup == true,
|
isActiveGroup = recipient?.isActiveGroup == true,
|
||||||
isActiveV2Group = recipient?.let { it.isActiveGroup && it.isPushV2Group } == true,
|
isActiveV2Group = recipient?.let { it.isActiveGroup && it.isPushV2Group } == true,
|
||||||
@@ -1679,7 +1713,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsMenuCreated(menu: Menu) {
|
override fun onOptionsMenuCreated(menu: Menu) {
|
||||||
// TODO [alex]
|
// TODO [cfv2]
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleVideo() {
|
override fun handleVideo() {
|
||||||
@@ -1687,71 +1721,71 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun handleDial(isSecure: Boolean) {
|
override fun handleDial(isSecure: Boolean) {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleViewMedia() {
|
override fun handleViewMedia() {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleAddShortcut() {
|
override fun handleAddShortcut() {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleSearch() {
|
override fun handleSearch() {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleAddToContacts() {
|
override fun handleAddToContacts() {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleDisplayGroupRecipients() {
|
override fun handleDisplayGroupRecipients() {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleDistributionBroadcastEnabled(menuItem: MenuItem) {
|
override fun handleDistributionBroadcastEnabled(menuItem: MenuItem) {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleDistributionConversationEnabled(menuItem: MenuItem) {
|
override fun handleDistributionConversationEnabled(menuItem: MenuItem) {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleManageGroup() {
|
override fun handleManageGroup() {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleLeavePushGroup() {
|
override fun handleLeavePushGroup() {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleInviteLink() {
|
override fun handleInviteLink() {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleMuteNotifications() {
|
override fun handleMuteNotifications() {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleUnmuteNotifications() {
|
override fun handleUnmuteNotifications() {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleConversationSettings() {
|
override fun handleConversationSettings() {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleSelectMessageExpiration() {
|
override fun handleSelectMessageExpiration() {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleCreateBubble() {
|
override fun handleCreateBubble() {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleGoHome() {
|
override fun handleGoHome() {
|
||||||
// TODO [alex] - ("Not yet implemented")
|
// TODO [cfv2] - ("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showExpiring(recipient: Recipient) = Unit
|
override fun showExpiring(recipient: Recipient) = Unit
|
||||||
@@ -1800,7 +1834,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
inner class ActionModeCallback : ActionMode.Callback {
|
inner class ActionModeCallback : ActionMode.Callback {
|
||||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||||
mode.title = calculateSelectedItemCount()
|
mode.title = calculateSelectedItemCount()
|
||||||
// TODO [alex] listener.onMessageActionToolbarOpened();
|
// TODO [cfv2] listener.onMessageActionToolbarOpened();
|
||||||
setCorrectActionModeMenuVisibility()
|
setCorrectActionModeMenuVisibility()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -1812,7 +1846,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
override fun onDestroyActionMode(mode: ActionMode) {
|
override fun onDestroyActionMode(mode: ActionMode) {
|
||||||
adapter.clearSelection()
|
adapter.clearSelection()
|
||||||
setBottomActionBarVisibility(false)
|
setBottomActionBarVisibility(false)
|
||||||
// TODO [alex] listener.onMessageActionToolbarClosed();
|
// TODO [cfv2] listener.onMessageActionToolbarClosed();
|
||||||
binding.conversationItemRecycler.invalidateItemDecorations()
|
binding.conversationItemRecycler.invalidateItemDecorations()
|
||||||
actionMode = null
|
actionMode = null
|
||||||
}
|
}
|
||||||
@@ -2083,7 +2117,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
if (composeText.textTrimmed.isEmpty() || beforeLength == 0) {
|
if (composeText.textTrimmed.isEmpty() || beforeLength == 0) {
|
||||||
composeText.postDelayed({ updateToggleButtonState() }, 50)
|
composeText.postDelayed({ updateToggleButtonState() }, 50)
|
||||||
}
|
}
|
||||||
// todo [cody] stickerViewModel.onInputTextUpdated(s.toString())
|
// todo [cfv2] stickerViewModel.onInputTextUpdated(s.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFocusChange(v: View, hasFocus: Boolean) {
|
override fun onFocusChange(v: View, hasFocus: Boolean) {
|
||||||
@@ -2093,7 +2127,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCursorPositionChanged(start: Int, end: Int) {
|
override fun onCursorPositionChanged(start: Int, end: Int) {
|
||||||
// todo [cody] linkPreviewViewModel.onTextChanged(requireContext(), composeText.getTextTrimmed().toString(), start, end);
|
// todo [cfv2] linkPreviewViewModel.onTextChanged(requireContext(), composeText.getTextTrimmed().toString(), start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) = Unit
|
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) = Unit
|
||||||
@@ -2105,11 +2139,11 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
|||||||
|
|
||||||
private inner class AttachmentManagerListener : AttachmentManager.AttachmentListener {
|
private inner class AttachmentManagerListener : AttachmentManager.AttachmentListener {
|
||||||
override fun onAttachmentChanged() {
|
override fun onAttachmentChanged() {
|
||||||
// TODO [cody] implement
|
// TODO [cfv2] implement
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLocationRemoved() {
|
override fun onLocationRemoved() {
|
||||||
// TODO [cody] implement
|
// TODO [cfv2] implement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.thoughtcrime.securesms.conversation.v2
|
package org.thoughtcrime.securesms.conversation.v2
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import io.reactivex.rxjava3.core.Completable
|
import io.reactivex.rxjava3.core.Completable
|
||||||
import io.reactivex.rxjava3.core.Flowable
|
import io.reactivex.rxjava3.core.Flowable
|
||||||
@@ -14,6 +15,7 @@ import io.reactivex.rxjava3.core.Observable
|
|||||||
import io.reactivex.rxjava3.core.Single
|
import io.reactivex.rxjava3.core.Single
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||||
import org.signal.core.util.concurrent.SignalExecutors
|
import org.signal.core.util.concurrent.SignalExecutors
|
||||||
|
import org.signal.core.util.logging.Log
|
||||||
import org.signal.core.util.toOptional
|
import org.signal.core.util.toOptional
|
||||||
import org.signal.libsignal.protocol.InvalidMessageException
|
import org.signal.libsignal.protocol.InvalidMessageException
|
||||||
import org.signal.paging.PagedData
|
import org.signal.paging.PagedData
|
||||||
@@ -31,26 +33,33 @@ import org.thoughtcrime.securesms.conversation.v2.data.ConversationDataSource
|
|||||||
import org.thoughtcrime.securesms.crypto.ReentrantSessionLock
|
import org.thoughtcrime.securesms.crypto.ReentrantSessionLock
|
||||||
import org.thoughtcrime.securesms.database.GroupTable
|
import org.thoughtcrime.securesms.database.GroupTable
|
||||||
import org.thoughtcrime.securesms.database.IdentityTable.VerifiedStatus
|
import org.thoughtcrime.securesms.database.IdentityTable.VerifiedStatus
|
||||||
|
import org.thoughtcrime.securesms.database.MessageTable
|
||||||
import org.thoughtcrime.securesms.database.RecipientTable
|
import org.thoughtcrime.securesms.database.RecipientTable
|
||||||
import org.thoughtcrime.securesms.database.RxDatabaseObserver
|
import org.thoughtcrime.securesms.database.RxDatabaseObserver
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||||
|
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.attachments
|
||||||
import org.thoughtcrime.securesms.database.model.GroupRecord
|
import org.thoughtcrime.securesms.database.model.GroupRecord
|
||||||
import org.thoughtcrime.securesms.database.model.IdentityRecord
|
import org.thoughtcrime.securesms.database.model.IdentityRecord
|
||||||
import org.thoughtcrime.securesms.database.model.Mention
|
import org.thoughtcrime.securesms.database.model.Mention
|
||||||
import org.thoughtcrime.securesms.database.model.MessageId
|
import org.thoughtcrime.securesms.database.model.MessageId
|
||||||
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.Quote
|
import org.thoughtcrime.securesms.database.model.Quote
|
||||||
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
|
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||||
|
import org.thoughtcrime.securesms.jobs.MultiDeviceViewOnceOpenJob
|
||||||
import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob
|
import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
import org.thoughtcrime.securesms.mms.OutgoingMessage
|
import org.thoughtcrime.securesms.mms.OutgoingMessage
|
||||||
|
import org.thoughtcrime.securesms.mms.PartAuthority
|
||||||
import org.thoughtcrime.securesms.mms.QuoteModel
|
import org.thoughtcrime.securesms.mms.QuoteModel
|
||||||
import org.thoughtcrime.securesms.mms.SlideDeck
|
import org.thoughtcrime.securesms.mms.SlideDeck
|
||||||
|
import org.thoughtcrime.securesms.providers.BlobProvider
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientFormattingException
|
import org.thoughtcrime.securesms.recipients.RecipientFormattingException
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||||
import org.thoughtcrime.securesms.sms.MessageSender
|
import org.thoughtcrime.securesms.sms.MessageSender
|
||||||
import org.thoughtcrime.securesms.util.SignalLocalMetrics
|
import org.thoughtcrime.securesms.util.SignalLocalMetrics
|
||||||
|
import java.io.IOException
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
@@ -60,6 +69,10 @@ class ConversationRepository(
|
|||||||
private val isInBubble: Boolean
|
private val isInBubble: Boolean
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TAG = Log.tag(ConversationRepository::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
private val applicationContext = context.applicationContext
|
private val applicationContext = context.applicationContext
|
||||||
private val oldConversationRepository = org.thoughtcrime.securesms.conversation.ConversationRepository()
|
private val oldConversationRepository = org.thoughtcrime.securesms.conversation.ConversationRepository()
|
||||||
|
|
||||||
@@ -261,6 +274,33 @@ class ConversationRepository(
|
|||||||
}.subscribeOn(Schedulers.io())
|
}.subscribeOn(Schedulers.io())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getTemporaryViewOnceUri(mmsMessageRecord: MmsMessageRecord): Maybe<Uri> {
|
||||||
|
return Maybe.fromCallable<Uri> {
|
||||||
|
Log.i(TAG, "Copying the view-once photo to temp storage and deleting underlying media.")
|
||||||
|
|
||||||
|
try {
|
||||||
|
val thumbnailSlide = mmsMessageRecord.slideDeck.thumbnailSlide ?: return@fromCallable null
|
||||||
|
val thumbnailUri = thumbnailSlide.uri ?: return@fromCallable null
|
||||||
|
|
||||||
|
val inputStream = PartAuthority.getAttachmentStream(applicationContext, thumbnailUri)
|
||||||
|
val tempUri = BlobProvider.getInstance().forData(inputStream, thumbnailSlide.fileSize)
|
||||||
|
.withMimeType(thumbnailSlide.contentType)
|
||||||
|
.createForSingleSessionOnDisk(applicationContext)
|
||||||
|
|
||||||
|
attachments.deleteAttachmentFilesForViewOnceMessage(mmsMessageRecord.id)
|
||||||
|
ApplicationDependencies.getViewOnceMessageManager().scheduleIfNecessary()
|
||||||
|
ApplicationDependencies.getJobManager().add(MultiDeviceViewOnceOpenJob(MessageTable.SyncMessageId(mmsMessageRecord.fromRecipient.id, mmsMessageRecord.dateSent)))
|
||||||
|
|
||||||
|
tempUri
|
||||||
|
} catch (e: IOException) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}.doOnComplete {
|
||||||
|
Log.w(TAG, "Failed to open view-once photo. Deleting the attachments for the message just in case.")
|
||||||
|
attachments.deleteAttachmentFilesForViewOnceMessage(mmsMessageRecord.id)
|
||||||
|
}.subscribeOn(Schedulers.io())
|
||||||
|
}
|
||||||
|
|
||||||
data class MessageCounts(
|
data class MessageCounts(
|
||||||
val unread: Int,
|
val unread: Int,
|
||||||
val mentions: Int
|
val mentions: Int
|
||||||
|
|||||||
@@ -5,10 +5,12 @@
|
|||||||
|
|
||||||
package org.thoughtcrime.securesms.conversation.v2
|
package org.thoughtcrime.securesms.conversation.v2
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.rxjava3.core.Completable
|
import io.reactivex.rxjava3.core.Completable
|
||||||
import io.reactivex.rxjava3.core.Flowable
|
import io.reactivex.rxjava3.core.Flowable
|
||||||
|
import io.reactivex.rxjava3.core.Maybe
|
||||||
import io.reactivex.rxjava3.core.Observable
|
import io.reactivex.rxjava3.core.Observable
|
||||||
import io.reactivex.rxjava3.core.Single
|
import io.reactivex.rxjava3.core.Single
|
||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
@@ -31,6 +33,7 @@ import org.thoughtcrime.securesms.database.model.IdentityRecord
|
|||||||
import org.thoughtcrime.securesms.database.model.Mention
|
import org.thoughtcrime.securesms.database.model.Mention
|
||||||
import org.thoughtcrime.securesms.database.model.MessageId
|
import org.thoughtcrime.securesms.database.model.MessageId
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||||
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.Quote
|
import org.thoughtcrime.securesms.database.model.Quote
|
||||||
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
|
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||||
@@ -251,4 +254,8 @@ class ConversationViewModel(
|
|||||||
fun updateIdentityRecords() {
|
fun updateIdentityRecords() {
|
||||||
refreshIdentityRecords.onNext(Unit)
|
refreshIdentityRecords.onNext(Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getTemporaryViewOnceUri(mmsMessageRecord: MmsMessageRecord): Maybe<Uri> {
|
||||||
|
return repository.getTemporaryViewOnceUri(mmsMessageRecord).observeOn(AndroidSchedulers.mainThread())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user