2015-03-11 14:23:45 -07:00
|
|
|
package org.thoughtcrime.securesms.components;
|
|
|
|
|
|
|
|
import android.content.Context;
|
2015-07-20 19:25:54 -07:00
|
|
|
import android.content.res.Configuration;
|
2016-12-26 15:14:23 -08:00
|
|
|
import android.os.Build;
|
|
|
|
import android.os.Bundle;
|
2020-08-19 10:06:26 +10:00
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
import androidx.annotation.RequiresApi;
|
|
|
|
import androidx.core.view.inputmethod.EditorInfoCompat;
|
|
|
|
import androidx.core.view.inputmethod.InputConnectionCompat;
|
|
|
|
import androidx.core.view.inputmethod.InputContentInfoCompat;
|
|
|
|
import androidx.core.os.BuildCompat;
|
2015-07-20 19:25:54 -07:00
|
|
|
import android.text.InputType;
|
2016-03-02 17:38:48 -08:00
|
|
|
import android.text.Spannable;
|
|
|
|
import android.text.SpannableString;
|
2016-02-05 16:10:33 -08:00
|
|
|
import android.text.SpannableStringBuilder;
|
2015-03-25 10:49:12 -07:00
|
|
|
import android.text.TextUtils;
|
2015-07-16 11:53:57 -07:00
|
|
|
import android.text.TextUtils.TruncateAt;
|
2016-03-02 17:38:48 -08:00
|
|
|
import android.text.style.RelativeSizeSpan;
|
2015-03-11 14:23:45 -07:00
|
|
|
import android.util.AttributeSet;
|
2015-07-20 19:25:54 -07:00
|
|
|
import android.view.inputmethod.EditorInfo;
|
2016-10-16 21:09:44 -04:00
|
|
|
import android.view.inputmethod.InputConnection;
|
2015-03-11 14:23:45 -07:00
|
|
|
|
2015-07-20 19:25:54 -07:00
|
|
|
import org.thoughtcrime.securesms.TransportOption;
|
2015-05-14 13:59:48 -07:00
|
|
|
import org.thoughtcrime.securesms.components.emoji.EmojiEditText;
|
2019-06-25 11:48:39 +10:00
|
|
|
import org.thoughtcrime.securesms.logging.Log;
|
2015-07-20 19:25:54 -07:00
|
|
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
2015-05-14 13:59:48 -07:00
|
|
|
|
2015-05-06 13:53:55 -07:00
|
|
|
public class ComposeText extends EmojiEditText {
|
2016-02-05 16:10:33 -08:00
|
|
|
|
2017-04-15 10:12:00 -07:00
|
|
|
private CharSequence hint;
|
2016-03-02 17:38:48 -08:00
|
|
|
private SpannableString subHint;
|
2015-07-21 14:21:22 -07:00
|
|
|
|
2019-02-14 13:55:48 -08:00
|
|
|
@Nullable private InputPanel.MediaListener mediaListener;
|
|
|
|
@Nullable private CursorPositionChangedListener cursorPositionChangedListener;
|
2016-12-26 15:14:23 -08:00
|
|
|
|
2015-03-11 14:23:45 -07:00
|
|
|
public ComposeText(Context context) {
|
|
|
|
super(context);
|
2017-10-03 18:57:23 -07:00
|
|
|
initialize();
|
2015-03-11 14:23:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
public ComposeText(Context context, AttributeSet attrs) {
|
|
|
|
super(context, attrs);
|
2017-10-03 18:57:23 -07:00
|
|
|
initialize();
|
2015-03-11 14:23:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
public ComposeText(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
|
|
super(context, attrs, defStyleAttr);
|
2017-10-03 18:57:23 -07:00
|
|
|
initialize();
|
2015-03-11 14:23:45 -07:00
|
|
|
}
|
|
|
|
|
2017-07-04 19:09:36 +02:00
|
|
|
public String getTextTrimmed(){
|
|
|
|
return getText().toString().trim();
|
|
|
|
}
|
|
|
|
|
2016-02-05 16:10:33 -08:00
|
|
|
@Override
|
|
|
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
2015-07-16 11:53:57 -07:00
|
|
|
super.onLayout(changed, left, top, right, bottom);
|
2016-02-05 16:10:33 -08:00
|
|
|
|
2015-07-21 14:21:22 -07:00
|
|
|
if (!TextUtils.isEmpty(hint)) {
|
2016-02-05 16:10:33 -08:00
|
|
|
if (!TextUtils.isEmpty(subHint)) {
|
|
|
|
setHint(new SpannableStringBuilder().append(ellipsizeToWidth(hint))
|
|
|
|
.append("\n")
|
|
|
|
.append(ellipsizeToWidth(subHint)));
|
|
|
|
} else {
|
|
|
|
setHint(ellipsizeToWidth(hint));
|
|
|
|
}
|
2015-07-16 11:53:57 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-14 13:55:48 -08:00
|
|
|
@Override
|
|
|
|
protected void onSelectionChanged(int selStart, int selEnd) {
|
|
|
|
super.onSelectionChanged(selStart, selEnd);
|
|
|
|
|
|
|
|
if (cursorPositionChangedListener != null) {
|
|
|
|
cursorPositionChangedListener.onCursorPositionChanged(selStart, selEnd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-21 14:21:22 -07:00
|
|
|
private CharSequence ellipsizeToWidth(CharSequence text) {
|
|
|
|
return TextUtils.ellipsize(text,
|
|
|
|
getPaint(),
|
|
|
|
getWidth() - getPaddingLeft() - getPaddingRight(),
|
|
|
|
TruncateAt.END);
|
|
|
|
}
|
|
|
|
|
2016-02-05 16:10:33 -08:00
|
|
|
public void setHint(@NonNull String hint, @Nullable CharSequence subHint) {
|
2017-04-15 10:12:00 -07:00
|
|
|
this.hint = hint;
|
2016-03-02 17:38:48 -08:00
|
|
|
|
|
|
|
if (subHint != null) {
|
|
|
|
this.subHint = new SpannableString(subHint);
|
2017-04-15 10:12:00 -07:00
|
|
|
this.subHint.setSpan(new RelativeSizeSpan(0.5f), 0, subHint.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
|
2016-03-02 17:38:48 -08:00
|
|
|
} else {
|
|
|
|
this.subHint = null;
|
|
|
|
}
|
2016-02-05 16:10:33 -08:00
|
|
|
|
|
|
|
if (this.subHint != null) {
|
|
|
|
super.setHint(new SpannableStringBuilder().append(ellipsizeToWidth(this.hint))
|
|
|
|
.append("\n")
|
|
|
|
.append(ellipsizeToWidth(this.subHint)));
|
|
|
|
} else {
|
|
|
|
super.setHint(ellipsizeToWidth(this.hint));
|
|
|
|
}
|
2015-03-11 14:23:45 -07:00
|
|
|
}
|
2015-03-25 10:49:12 -07:00
|
|
|
|
|
|
|
public void appendInvite(String invite) {
|
|
|
|
if (!TextUtils.isEmpty(getText()) && !getText().toString().equals(" ")) {
|
|
|
|
append(" ");
|
|
|
|
}
|
|
|
|
|
|
|
|
append(invite);
|
2015-10-13 21:44:01 -07:00
|
|
|
setSelection(getText().length());
|
2015-03-25 10:49:12 -07:00
|
|
|
}
|
2015-07-20 19:25:54 -07:00
|
|
|
|
2019-02-14 13:55:48 -08:00
|
|
|
public void setCursorPositionChangedListener(@Nullable CursorPositionChangedListener listener) {
|
|
|
|
this.cursorPositionChangedListener = listener;
|
|
|
|
}
|
|
|
|
|
2015-07-20 19:25:54 -07:00
|
|
|
private boolean isLandscape() {
|
|
|
|
return getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setTransport(TransportOption transport) {
|
2015-09-07 16:21:17 -10:00
|
|
|
final boolean useSystemEmoji = TextSecurePreferences.isSystemEmojiPreferred(getContext());
|
2017-10-03 18:57:23 -07:00
|
|
|
final boolean isIncognito = TextSecurePreferences.isIncognitoKeyboardEnabled(getContext());
|
2015-07-20 19:25:54 -07:00
|
|
|
|
|
|
|
int imeOptions = (getImeOptions() & ~EditorInfo.IME_MASK_ACTION) | EditorInfo.IME_ACTION_SEND;
|
|
|
|
int inputType = getInputType();
|
|
|
|
|
|
|
|
if (isLandscape()) setImeActionLabel(transport.getComposeHint(), EditorInfo.IME_ACTION_SEND);
|
|
|
|
else setImeActionLabel(null, 0);
|
|
|
|
|
2015-09-07 16:21:17 -10:00
|
|
|
if (useSystemEmoji) {
|
|
|
|
inputType = (inputType & ~InputType.TYPE_MASK_VARIATION) | InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE;
|
|
|
|
}
|
|
|
|
|
2015-07-20 19:25:54 -07:00
|
|
|
setInputType(inputType);
|
2019-10-24 10:38:51 +11:00
|
|
|
if (isIncognito) {
|
|
|
|
setImeOptions(imeOptions | 16777216);
|
|
|
|
} else {
|
|
|
|
setImeOptions(imeOptions);
|
|
|
|
}
|
2019-06-25 11:48:39 +10:00
|
|
|
/*
|
2016-03-01 11:15:03 +09:00
|
|
|
setHint(transport.getComposeHint(),
|
|
|
|
transport.getSimName().isPresent()
|
|
|
|
? getContext().getString(R.string.conversation_activity__from_sim_name, transport.getSimName().get())
|
|
|
|
: null);
|
2019-06-25 11:48:39 +10:00
|
|
|
*/
|
2015-07-20 19:25:54 -07:00
|
|
|
}
|
2016-10-16 21:09:44 -04:00
|
|
|
|
|
|
|
@Override
|
2016-12-26 15:14:23 -08:00
|
|
|
public InputConnection onCreateInputConnection(EditorInfo editorInfo) {
|
|
|
|
InputConnection inputConnection = super.onCreateInputConnection(editorInfo);
|
|
|
|
|
2016-10-16 21:09:44 -04:00
|
|
|
if(TextSecurePreferences.isEnterSendsEnabled(getContext())) {
|
2016-12-26 15:14:23 -08:00
|
|
|
editorInfo.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
|
2016-10-16 21:09:44 -04:00
|
|
|
}
|
2016-12-26 15:14:23 -08:00
|
|
|
|
2017-01-17 20:46:20 -08:00
|
|
|
if (Build.VERSION.SDK_INT < 21) return inputConnection;
|
|
|
|
if (mediaListener == null) return inputConnection;
|
|
|
|
if (inputConnection == null) return null;
|
2016-12-26 15:14:23 -08:00
|
|
|
|
|
|
|
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;
|
2016-10-16 21:09:44 -04:00
|
|
|
}
|
2016-12-26 15:14:23 -08:00
|
|
|
|
2017-10-03 18:57:23 -07:00
|
|
|
private void initialize() {
|
|
|
|
if (TextSecurePreferences.isIncognitoKeyboardEnabled(getContext())) {
|
|
|
|
setImeOptions(getImeOptions() | 16777216);
|
|
|
|
}
|
|
|
|
}
|
2016-12-26 15:14:23 -08:00
|
|
|
|
|
|
|
@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB_MR2)
|
|
|
|
private static class CommitContentListener implements InputConnectionCompat.OnCommitContentListener {
|
|
|
|
|
2018-12-06 12:14:20 -08:00
|
|
|
private static final String TAG = CommitContentListener.class.getSimpleName();
|
2016-12-26 15:14:23 -08:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-14 13:55:48 -08:00
|
|
|
public interface CursorPositionChangedListener {
|
|
|
|
void onCursorPositionChanged(int start, int end);
|
|
|
|
}
|
2015-03-11 14:23:45 -07:00
|
|
|
}
|