Support for image keyboards

// FREEBIE
This commit is contained in:
Moxie Marlinspike
2016-12-26 15:14:23 -08:00
parent 373a0f9527
commit a3019be7b6
5 changed files with 114 additions and 27 deletions

View File

@@ -38,10 +38,12 @@ import android.provider.Browser;
import android.provider.ContactsContract;
import android.provider.Telephony;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.WindowCompat;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.util.Pair;
@@ -169,7 +171,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
RecipientsModifiedListener,
OnKeyboardShownListener,
AttachmentDrawerListener,
InputPanel.Listener
InputPanel.Listener,
InputPanel.MediaListener
{
private static final String TAG = ConversationActivity.class.getSimpleName();
@@ -982,6 +985,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
container.addOnKeyboardShownListener(this);
inputPanel.setListener(this, emojiDrawer);
inputPanel.setMediaListener(this);
int[] attributes = new int[]{R.attr.conversation_item_bubble_background};
TypedArray colors = obtainStyledAttributes(attributes);
@@ -1147,7 +1151,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
}
private void setMedia(Uri uri, MediaType mediaType) {
private void setMedia(@Nullable Uri uri, @NonNull MediaType mediaType) {
if (uri == null) return;
attachmentManager.setMedia(masterSecret, uri, mediaType, getCurrentMediaConstraints());
}
@@ -1605,6 +1609,20 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
else container.show(composeText, emojiDrawer);
}
@Override
public void onMediaSelected(@NonNull Uri uri, String contentType) {
if (!TextUtils.isEmpty(contentType) && contentType.trim().equals("image/gif")) {
setMedia(uri, MediaType.GIF);
} else if (ContentType.isImageType(contentType)) {
setMedia(uri, MediaType.IMAGE);
} else if (ContentType.isVideoType(contentType)) {
setMedia(uri, MediaType.VIDEO);
} else if (ContentType.isAudioType(contentType)) {
setMedia(uri, MediaType.AUDIO);
}
}
// Listeners
private class AttachmentTypeListener implements AttachmentTypeSelector.AttachmentClickedListener {

View File

@@ -2,8 +2,15 @@ package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v13.view.inputmethod.EditorInfoCompat;
import android.support.v13.view.inputmethod.InputConnectionCompat;
import android.support.v13.view.inputmethod.InputContentInfoCompat;
import android.support.v4.os.BuildCompat;
import android.text.InputType;
import android.text.Spannable;
import android.text.SpannableString;
@@ -12,6 +19,7 @@ import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
import android.text.style.RelativeSizeSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
@@ -25,6 +33,8 @@ public class ComposeText extends EmojiEditText {
private SpannableString hint;
private SpannableString subHint;
@Nullable private InputPanel.MediaListener mediaListener;
public ComposeText(Context context) {
super(context);
}
@@ -114,11 +124,56 @@ public class ComposeText extends EmojiEditText {
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
InputConnection conn = super.onCreateInputConnection(outAttrs);
public InputConnection onCreateInputConnection(EditorInfo editorInfo) {
InputConnection inputConnection = super.onCreateInputConnection(editorInfo);
if(TextSecurePreferences.isEnterSendsEnabled(getContext())) {
outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
editorInfo.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
}
return conn;
if (Build.VERSION.SDK_INT <= 13) return inputConnection;
if (mediaListener == null) return inputConnection;
EditorInfoCompat.setContentMimeTypes(editorInfo, new String[] {"image/jpeg", "image/png", "image/gif"});
return InputConnectionCompat.createWrapper(inputConnection, editorInfo, new CommitContentListener(mediaListener));
}
public void setMediaListener(@Nullable InputPanel.MediaListener mediaListener) {
this.mediaListener = mediaListener;
}
@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB_MR2)
private static class CommitContentListener implements InputConnectionCompat.OnCommitContentListener {
private static final String TAG = CommitContentListener.class.getName();
private final InputPanel.MediaListener mediaListener;
private CommitContentListener(@NonNull InputPanel.MediaListener mediaListener) {
this.mediaListener = mediaListener;
}
@Override
public boolean onCommitContent(InputContentInfoCompat inputContentInfo, int flags, Bundle opts) {
if (BuildCompat.isAtLeastNMR1() && (flags & InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) {
try {
inputContentInfo.requestPermission();
} catch (Exception e) {
Log.w(TAG, e);
return false;
}
}
if (inputContentInfo.getDescription().getMimeTypeCount() > 0) {
mediaListener.onMediaSelected(inputContentInfo.getContentUri(),
inputContentInfo.getDescription().getMimeType(0));
return true;
}
return false;
}
}
}

View File

@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.components;
import android.annotation.TargetApi;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.NonNull;
@@ -32,14 +33,17 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
public class InputPanel extends LinearLayout
implements MicrophoneRecorderView.Listener, KeyboardAwareLinearLayout.OnKeyboardShownListener, EmojiDrawer.EmojiEventListener {
implements MicrophoneRecorderView.Listener,
KeyboardAwareLinearLayout.OnKeyboardShownListener,
EmojiDrawer.EmojiEventListener
{
private static final String TAG = InputPanel.class.getSimpleName();
private static final int FADE_TIME = 150;
private EmojiToggle emojiToggle;
private EmojiEditText composeText;
private ComposeText composeText;
private View quickCameraToggle;
private View quickAudioToggle;
private View buttonToggle;
@@ -106,6 +110,10 @@ public class InputPanel extends LinearLayout
});
}
public void setMediaListener(@NonNull MediaListener listener) {
composeText.setMediaListener(listener);
}
@Override
public void onRecordPressed(float startPositionX) {
if (listener != null) listener.onRecorderStarted();
@@ -300,4 +308,8 @@ public class InputPanel extends LinearLayout
}
}
}
public interface MediaListener {
public void onMediaSelected(@NonNull Uri uri, String contentType);
}
}