Merge pull request #653 from hjubb/conversation_handling_intents

Properly Handle External Keyboard Content & Handle Text Content Shared via Intent
This commit is contained in:
Niels Andriesse 2021-07-13 13:29:47 +10:00 committed by GitHub
commit 15d74137d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 16 deletions

View File

@ -76,6 +76,7 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity
private ImageView searchAction; private ImageView searchAction;
private View progressWheel; private View progressWheel;
private Uri resolvedExtra; private Uri resolvedExtra;
private CharSequence resolvedPlaintext;
private String mimeType; private String mimeType;
private boolean isPassingAlongMedia; private boolean isPassingAlongMedia;
@ -173,12 +174,16 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity
isPassingAlongMedia = false; isPassingAlongMedia = false;
Uri streamExtra = getIntent().getParcelableExtra(Intent.EXTRA_STREAM); Uri streamExtra = getIntent().getParcelableExtra(Intent.EXTRA_STREAM);
CharSequence charSequenceExtra = getIntent().getCharSequenceExtra(Intent.EXTRA_TEXT);
mimeType = getMimeType(streamExtra); mimeType = getMimeType(streamExtra);
if (streamExtra != null && PartAuthority.isLocalUri(streamExtra)) { if (streamExtra != null && PartAuthority.isLocalUri(streamExtra)) {
isPassingAlongMedia = true; isPassingAlongMedia = true;
resolvedExtra = streamExtra; resolvedExtra = streamExtra;
handleResolvedMedia(getIntent(), false); handleResolvedMedia(getIntent(), false);
} else if (charSequenceExtra != null && mimeType != null && mimeType.startsWith("text/")) {
resolvedPlaintext = charSequenceExtra;
handleResolvedMedia(getIntent(), false);
} else { } else {
contactsFragment.getView().setVisibility(View.GONE); contactsFragment.getView().setVisibility(View.GONE);
progressWheel.setVisibility(View.VISIBLE); progressWheel.setVisibility(View.VISIBLE);
@ -225,7 +230,12 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity
private Intent getBaseShareIntent(final @NonNull Class<?> target) { private Intent getBaseShareIntent(final @NonNull Class<?> target) {
final Intent intent = new Intent(this, target); final Intent intent = new Intent(this, target);
if (resolvedExtra != null) intent.setDataAndType(resolvedExtra, mimeType); if (resolvedExtra != null) {
intent.setDataAndType(resolvedExtra, mimeType);
} else if (resolvedPlaintext != null) {
intent.putExtra(Intent.EXTRA_TEXT, resolvedPlaintext);
intent.setType("text/plain");
}
return intent; return intent;
} }

View File

@ -76,8 +76,9 @@ import org.session.libsignal.utilities.guava.Optional
import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.audio.AudioRecorder import org.thoughtcrime.securesms.audio.AudioRecorder
import org.thoughtcrime.securesms.contacts.SelectContactsActivity
import org.thoughtcrime.securesms.contacts.SelectContactsActivity.Companion.selectedContactsKey
import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher
import org.thoughtcrime.securesms.conversation.v2.dialogs.* import org.thoughtcrime.securesms.conversation.v2.dialogs.*
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarButton import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarButton
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarDelegate import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarDelegate
@ -91,6 +92,7 @@ import org.thoughtcrime.securesms.conversation.v2.search.SearchBottomBar
import org.thoughtcrime.securesms.conversation.v2.search.SearchViewModel import org.thoughtcrime.securesms.conversation.v2.search.SearchViewModel
import org.thoughtcrime.securesms.conversation.v2.utilities.AttachmentManager import org.thoughtcrime.securesms.conversation.v2.utilities.AttachmentManager
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities
import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.DraftDatabase import org.thoughtcrime.securesms.database.DraftDatabase
import org.thoughtcrime.securesms.database.DraftDatabase.Drafts import org.thoughtcrime.securesms.database.DraftDatabase.Drafts
@ -101,10 +103,6 @@ import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil
import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel
import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel.LinkPreviewState import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel.LinkPreviewState
import org.thoughtcrime.securesms.contacts.SelectContactsActivity
import org.thoughtcrime.securesms.contacts.SelectContactsActivity.Companion.selectedContactsKey
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities
import org.thoughtcrime.securesms.util.toPx
import org.thoughtcrime.securesms.mediasend.Media import org.thoughtcrime.securesms.mediasend.Media
import org.thoughtcrime.securesms.mediasend.MediaSendActivity import org.thoughtcrime.securesms.mediasend.MediaSendActivity
import org.thoughtcrime.securesms.mms.* import org.thoughtcrime.securesms.mms.*
@ -359,13 +357,17 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
}) })
return return
} }
} } else if (intent.hasExtra(Intent.EXTRA_TEXT)) {
val dataTextExtra = intent.getCharSequenceExtra(Intent.EXTRA_TEXT) ?: ""
inputBar.text = dataTextExtra.toString()
} else {
val draftDB = DatabaseFactory.getDraftDatabase(this) val draftDB = DatabaseFactory.getDraftDatabase(this)
val drafts = draftDB.getDrafts(threadID) val drafts = draftDB.getDrafts(threadID)
draftDB.clearDrafts(threadID) draftDB.clearDrafts(threadID)
val text = drafts.find { it.type == DraftDatabase.Draft.TEXT }?.value ?: return val text = drafts.find { it.type == DraftDatabase.Draft.TEXT }?.value ?: return
inputBar.text = text inputBar.text = text
} }
}
private fun addOpenGroupGuidelinesIfNeeded() { private fun addOpenGroupGuidelinesIfNeeded() {
val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID) ?: return val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID) ?: return
@ -885,6 +887,11 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
} }
} }
override fun commitInputContent(contentUri: Uri) {
val media = Media(contentUri, MediaUtil.getMimeType(this, contentUri)!!, 0, 0, 0, 0, Optional.absent(), Optional.absent())
startActivityForResult(MediaSendActivity.buildEditorIntent(this, listOf( media ), thread, getMessageBody()), ConversationActivityV2.PICK_FROM_LIBRARY)
}
private fun sendTextOnlyMessage() { private fun sendTextOnlyMessage() {
// Create the message // Create the message
val message = VisibleMessage() val message = VisibleMessage()

View File

@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.conversation.v2.input_bar
import android.content.Context import android.content.Context
import android.content.res.Resources import android.content.res.Resources
import android.net.Uri
import android.text.InputType import android.text.InputType
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
@ -19,9 +20,9 @@ import org.thoughtcrime.securesms.conversation.v2.messages.QuoteView
import org.thoughtcrime.securesms.conversation.v2.messages.QuoteViewDelegate import org.thoughtcrime.securesms.conversation.v2.messages.QuoteViewDelegate
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.MmsMessageRecord
import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.util.toDp import org.thoughtcrime.securesms.util.toDp
import org.thoughtcrime.securesms.util.toPx import org.thoughtcrime.securesms.util.toPx
import org.thoughtcrime.securesms.mms.GlideRequests
import kotlin.math.max import kotlin.math.max
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -96,6 +97,10 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate, Li
setHeight(newHeight) setHeight(newHeight)
} }
override fun commitInputContent(contentUri: Uri) {
delegate?.commitInputContent(contentUri)
}
private fun toggleAttachmentOptions() { private fun toggleAttachmentOptions() {
delegate?.toggleAttachmentOptions() delegate?.toggleAttachmentOptions()
} }
@ -193,4 +198,5 @@ interface InputBarDelegate {
fun onMicrophoneButtonCancel(event: MotionEvent) fun onMicrophoneButtonCancel(event: MotionEvent)
fun onMicrophoneButtonUp(event: MotionEvent) fun onMicrophoneButtonUp(event: MotionEvent)
fun sendMessage() fun sendMessage()
fun commitInputContent(contentUri: Uri)
} }

View File

@ -2,12 +2,15 @@ package org.thoughtcrime.securesms.conversation.v2.input_bar
import android.content.Context import android.content.Context
import android.content.res.Resources import android.content.res.Resources
import android.text.Layout import android.net.Uri
import android.text.StaticLayout import android.os.Build
import android.util.AttributeSet import android.util.AttributeSet
import android.util.Log import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputConnection
import android.widget.RelativeLayout import android.widget.RelativeLayout
import androidx.appcompat.widget.AppCompatEditText import androidx.appcompat.widget.AppCompatEditText
import androidx.core.view.inputmethod.EditorInfoCompat
import androidx.core.view.inputmethod.InputConnectionCompat
import org.thoughtcrime.securesms.conversation.v2.utilities.TextUtilities import org.thoughtcrime.securesms.conversation.v2.utilities.TextUtilities
import org.thoughtcrime.securesms.util.toPx import org.thoughtcrime.securesms.util.toPx
import kotlin.math.max import kotlin.math.max
@ -41,10 +44,38 @@ class InputBarEditText : AppCompatEditText {
this.layoutParams = layoutParams this.layoutParams = layoutParams
delegate?.inputBarEditTextHeightChanged(constrainedHeight.roundToInt()) delegate?.inputBarEditTextHeightChanged(constrainedHeight.roundToInt())
} }
override fun onCreateInputConnection(editorInfo: EditorInfo): InputConnection {
val ic: InputConnection = super.onCreateInputConnection(editorInfo)
EditorInfoCompat.setContentMimeTypes(editorInfo, arrayOf("image/png", "image/gif", "image/jpg"))
val callback =
InputConnectionCompat.OnCommitContentListener { inputContentInfo, flags, opts ->
val lacksPermission = (flags and InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0
// read and display inputContentInfo asynchronously
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1 && lacksPermission) {
try {
inputContentInfo.requestPermission()
} catch (e: Exception) {
return@OnCommitContentListener false // return false if failed
}
}
inputContentInfo.contentUri
// read and display inputContentInfo asynchronously.
delegate?.commitInputContent(inputContentInfo.contentUri)
true // return true if succeeded
}
return InputConnectionCompat.createWrapper(ic, editorInfo, callback)
}
} }
interface InputBarEditTextDelegate { interface InputBarEditTextDelegate {
fun inputBarEditTextContentChanged(text: CharSequence) fun inputBarEditTextContentChanged(text: CharSequence)
fun inputBarEditTextHeightChanged(newValue: Int) fun inputBarEditTextHeightChanged(newValue: Int)
fun commitInputContent(contentUri: Uri)
} }