diff --git a/app/src/main/java/app/fedilab/android/helper/CustomTextView.java b/app/src/fdroid/java/app/fedilab/android/helper/CustomTextView.java similarity index 100% rename from app/src/main/java/app/fedilab/android/helper/CustomTextView.java rename to app/src/fdroid/java/app/fedilab/android/helper/CustomTextView.java diff --git a/app/src/main/java/app/fedilab/android/helper/EmojiEditTextInterface.java b/app/src/fdroid/java/app/fedilab/android/helper/EmojiEditTextInterface.java similarity index 100% rename from app/src/main/java/app/fedilab/android/helper/EmojiEditTextInterface.java rename to app/src/fdroid/java/app/fedilab/android/helper/EmojiEditTextInterface.java diff --git a/app/src/fdroid/java/app/fedilab/android/helper/Helper.java b/app/src/fdroid/java/app/fedilab/android/helper/Helper.java new file mode 100644 index 000000000..776adac7e --- /dev/null +++ b/app/src/fdroid/java/app/fedilab/android/helper/Helper.java @@ -0,0 +1,4 @@ +package app.fedilab.android.helper; + +public class Helper extends BaseHelper { +} diff --git a/app/src/main/java/app/fedilab/android/helper/MastalabAutoCompleteTextView.java b/app/src/fdroid/java/app/fedilab/android/helper/MastalabAutoCompleteTextView.java similarity index 100% rename from app/src/main/java/app/fedilab/android/helper/MastalabAutoCompleteTextView.java rename to app/src/fdroid/java/app/fedilab/android/helper/MastalabAutoCompleteTextView.java diff --git a/app/src/lite/java/app/fedilab/android/helper/CustomTextView.java b/app/src/lite/java/app/fedilab/android/helper/CustomTextView.java new file mode 100644 index 000000000..bc058a6bf --- /dev/null +++ b/app/src/lite/java/app/fedilab/android/helper/CustomTextView.java @@ -0,0 +1,120 @@ +package app.fedilab.android.helper; + +/* Copyright 2018 Thomas Schneider + * + * This file is a part of Fedilab + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Fedilab; if not, + * see . */ + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.TypedArray; +import android.graphics.Paint; +import android.text.SpannableStringBuilder; +import android.util.AttributeSet; + +import androidx.annotation.DimenRes; +import androidx.annotation.Px; +import androidx.appcompat.widget.AppCompatTextView; + +import com.vanniktech.emoji.EmojiManager; + +import app.fedilab.android.R; + + +/** + * Created by Thomas on 12/05/2018. + * Allows to fix crashes with selection see: https://stackoverflow.com/a/36740247 + */ + +public class CustomTextView extends AppCompatTextView { + + private float emojiSize; + private boolean emoji; + + public CustomTextView(Context context) { + super(context); + final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + emoji = sharedpreferences.getBoolean(Helper.SET_DISPLAY_EMOJI, false); + } + + public CustomTextView(Context context, AttributeSet attrs) { + super(context, attrs); + final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + emoji = sharedpreferences.getBoolean(Helper.SET_DISPLAY_EMOJI, false); + + final Paint.FontMetrics fontMetrics = getPaint().getFontMetrics(); + final float defaultEmojiSize = fontMetrics.descent - fontMetrics.ascent; + + if (attrs == null) { + emojiSize = defaultEmojiSize; + } else { + @SuppressLint("CustomViewStyleable") final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.EmojiTextView); + + try { + emojiSize = a.getDimension(R.styleable.EmojiTextView_emojiSize, defaultEmojiSize); + } finally { + a.recycle(); + } + } + setText(getText()); + } + + @Override + public void setText(final CharSequence rawText, final BufferType type) { + if (emoji) { + final CharSequence text = rawText == null ? "" : rawText; + final SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text); + final Paint.FontMetrics fontMetrics = getPaint().getFontMetrics(); + final float defaultEmojiSize = fontMetrics.descent - fontMetrics.ascent; + EmojiManager.getInstance().replaceWithImages(getContext(), spannableStringBuilder, emojiSize, defaultEmojiSize); + super.setText(spannableStringBuilder, type); + } else { + super.setText(rawText, type); + } + + } + + /** + * sets the emoji size in pixels and automatically invalidates the text and renders it with the new size + */ + public final void setEmojiSize(@Px final int pixels) { + setEmojiSize(pixels, true); + } + + /** + * sets the emoji size in pixels and automatically invalidates the text and renders it with the new size when {@code shouldInvalidate} is true + */ + public final void setEmojiSize(@Px final int pixels, final boolean shouldInvalidate) { + emojiSize = pixels; + + if (shouldInvalidate) { + setText(getText()); + } + } + + /** + * sets the emoji size in pixels with the provided resource and automatically invalidates the text and renders it with the new size + */ + public final void setEmojiSizeRes(@DimenRes final int res) { + setEmojiSizeRes(res, true); + } + + /** + * sets the emoji size in pixels with the provided resource and invalidates the text and renders it with the new size when {@code shouldInvalidate} is true + */ + public final void setEmojiSizeRes(@DimenRes final int res, final boolean shouldInvalidate) { + setEmojiSize(getResources().getDimensionPixelSize(res), shouldInvalidate); + } + +} diff --git a/app/src/lite/java/app/fedilab/android/helper/Helper.java b/app/src/lite/java/app/fedilab/android/helper/Helper.java new file mode 100644 index 000000000..3522318cd --- /dev/null +++ b/app/src/lite/java/app/fedilab/android/helper/Helper.java @@ -0,0 +1,4 @@ +package app.fedilab.android.helper; + +public class Helper { +} diff --git a/app/src/lite/java/app/fedilab/android/helper/MastalabAutoCompleteTextView.java b/app/src/lite/java/app/fedilab/android/helper/MastalabAutoCompleteTextView.java new file mode 100644 index 000000000..7df1fac3a --- /dev/null +++ b/app/src/lite/java/app/fedilab/android/helper/MastalabAutoCompleteTextView.java @@ -0,0 +1,195 @@ +package app.fedilab.android.helper; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.TypedArray; +import android.graphics.Paint; +import android.os.Build; +import android.os.Bundle; +import android.util.AttributeSet; +import android.view.KeyEvent; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputConnection; + +import androidx.annotation.CallSuper; +import androidx.annotation.DimenRes; +import androidx.annotation.Px; +import androidx.core.view.inputmethod.EditorInfoCompat; +import androidx.core.view.inputmethod.InputConnectionCompat; +import androidx.core.view.inputmethod.InputContentInfoCompat; + +import com.vanniktech.emoji.EmojiManager; +import com.vanniktech.emoji.emoji.Emoji; + +import app.fedilab.android.R; + +import static app.fedilab.android.activities.TootActivity.autocomplete; + +public class MastalabAutoCompleteTextView extends androidx.appcompat.widget.AppCompatAutoCompleteTextView implements EmojiEditTextInterface { + + private float emojiSize; + private boolean emoji; + private String[] imgTypeString; + private KeyBoardInputCallbackListener keyBoardInputCallbackListener; + final InputConnectionCompat.OnCommitContentListener callback = + new InputConnectionCompat.OnCommitContentListener() { + @Override + public boolean onCommitContent(InputContentInfoCompat inputContentInfo, + int flags, Bundle opts) { + + // read and display inputContentInfo asynchronously + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1 && (flags & + InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) { + try { + inputContentInfo.requestPermission(); + } catch (Exception e) { + return false; // return false if failed + } + } + boolean supported = false; + for (final String mimeType : imgTypeString) { + if (inputContentInfo.getDescription().hasMimeType(mimeType)) { + supported = true; + break; + } + } + if (!supported) { + return false; + } + + if (keyBoardInputCallbackListener != null) { + keyBoardInputCallbackListener.onCommitContent(inputContentInfo, flags, opts); + } + return true; // return true if succeeded + } + }; + + + public MastalabAutoCompleteTextView(Context context) { + super(context); + initView(); + } + + public MastalabAutoCompleteTextView(Context context, AttributeSet attrs) { + super(context, attrs); + + final Paint.FontMetrics fontMetrics = getPaint().getFontMetrics(); + final float defaultEmojiSize = fontMetrics.descent - fontMetrics.ascent; + final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + emoji = sharedpreferences.getBoolean(Helper.SET_DISPLAY_EMOJI, false); + if (attrs == null) { + emojiSize = defaultEmojiSize; + } else { + @SuppressLint("CustomViewStyleable") final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.EmojiMultiAutoCompleteTextView); + + try { + emojiSize = a.getDimension(R.styleable.EmojiMultiAutoCompleteTextView_emojiSize, defaultEmojiSize); + } finally { + a.recycle(); + } + } + + setText(getText()); + initView(); + } + + public MastalabAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initView(); + } + + @Override + public InputConnection onCreateInputConnection(EditorInfo outAttrs) { + final InputConnection ic = super.onCreateInputConnection(outAttrs); + EditorInfoCompat.setContentMimeTypes(outAttrs, + imgTypeString); + return InputConnectionCompat.createWrapper(ic, outAttrs, callback); + } + + private void initView() { + imgTypeString = new String[]{"image/png", + "image/gif", + "image/jpeg", + "image/webp"}; + } + + public void setKeyBoardInputCallbackListener(KeyBoardInputCallbackListener keyBoardInputCallbackListener) { + this.keyBoardInputCallbackListener = keyBoardInputCallbackListener; + } + + @SuppressWarnings("unused") + public String[] getImgTypeString() { + return imgTypeString; + } + + @SuppressWarnings("unused") + public void setImgTypeString(String[] imgTypeString) { + this.imgTypeString = imgTypeString; + } + + @Override + @CallSuper + protected void onTextChanged(final CharSequence text, final int start, final int lengthBefore, final int lengthAfter) { + final Paint.FontMetrics fontMetrics = getPaint().getFontMetrics(); + final float defaultEmojiSize = fontMetrics.descent - fontMetrics.ascent; + if (emoji && !autocomplete) { + EmojiManager.getInstance().replaceWithImages(getContext(), getText(), emojiSize, defaultEmojiSize); + } + } + + @Override + public void backspace() { + final KeyEvent event = new KeyEvent(0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL); + dispatchKeyEvent(event); + } + + @Override + public float getEmojiSize() { + return emojiSize; + } + + @Override + public final void setEmojiSize(@Px final int pixels) { + setEmojiSize(pixels, true); + } + + @Override + @CallSuper + public void input(final Emoji emoji) { + if (emoji != null && !autocomplete) { + final int start = getSelectionStart(); + final int end = getSelectionEnd(); + + if (start < 0) { + append(emoji.getUnicode()); + } else { + getText().replace(Math.min(start, end), Math.max(start, end), emoji.getUnicode(), 0, emoji.getUnicode().length()); + } + } + } + + @Override + public final void setEmojiSize(@Px final int pixels, final boolean shouldInvalidate) { + emojiSize = pixels; + + if (shouldInvalidate && !autocomplete) { + setText(getText()); + } + } + + @Override + public final void setEmojiSizeRes(@DimenRes final int res) { + setEmojiSizeRes(res, true); + } + + @Override + public final void setEmojiSizeRes(@DimenRes final int res, final boolean shouldInvalidate) { + setEmojiSize(getResources().getDimensionPixelSize(res), shouldInvalidate); + } + + public interface KeyBoardInputCallbackListener { + void onCommitContent(InputContentInfoCompat inputContentInfo, + int flags, Bundle opts); + } +} diff --git a/app/src/main/java/app/fedilab/android/helper/Helper.java b/app/src/main/java/app/fedilab/android/helper/BaseHelper.java similarity index 100% rename from app/src/main/java/app/fedilab/android/helper/Helper.java rename to app/src/main/java/app/fedilab/android/helper/BaseHelper.java diff --git a/app/src/playstore/java/app/fedilab/android/helper/CustomTextView.java b/app/src/playstore/java/app/fedilab/android/helper/CustomTextView.java new file mode 100644 index 000000000..cf160e78c --- /dev/null +++ b/app/src/playstore/java/app/fedilab/android/helper/CustomTextView.java @@ -0,0 +1,120 @@ +package app.fedilab.android.helper; + +/* Copyright 2018 Thomas Schneider + * + * This file is a part of Fedilab + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Fedilab; if not, + * see . */ + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.TypedArray; +import android.graphics.Paint; +import android.text.SpannableStringBuilder; +import android.util.AttributeSet; + +import androidx.annotation.DimenRes; +import androidx.annotation.Px; +import androidx.appcompat.widget.AppCompatTextView; + +import com.vanniktech.emoji.EmojiManager; + +import app.fedilab.android.R; + + +/** + * Created by Thomas on 12/05/2018. + * Allows to fix crashes with selection see: https://stackoverflow.com/a/36740247 + */ + +public class CustomTextView extends AppCompatTextView { + + private float emojiSize; + private boolean emoji; + + public CustomTextView(Context context) { + super(context); + final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE); + emoji = sharedpreferences.getBoolean(Helper.SET_DISPLAY_EMOJI, false); + } + + public CustomTextView(Context context, AttributeSet attrs) { + super(context, attrs); + final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE); + emoji = sharedpreferences.getBoolean(Helper.SET_DISPLAY_EMOJI, false); + + final Paint.FontMetrics fontMetrics = getPaint().getFontMetrics(); + final float defaultEmojiSize = fontMetrics.descent - fontMetrics.ascent; + + if (attrs == null) { + emojiSize = defaultEmojiSize; + } else { + @SuppressLint("CustomViewStyleable") final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.EmojiTextView); + + try { + emojiSize = a.getDimension(R.styleable.EmojiTextView_emojiSize, defaultEmojiSize); + } finally { + a.recycle(); + } + } + setText(getText()); + } + + @Override + public void setText(final CharSequence rawText, final BufferType type) { + if (emoji) { + final CharSequence text = rawText == null ? "" : rawText; + final SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text); + final Paint.FontMetrics fontMetrics = getPaint().getFontMetrics(); + final float defaultEmojiSize = fontMetrics.descent - fontMetrics.ascent; + EmojiManager.getInstance().replaceWithImages(getContext(), spannableStringBuilder, emojiSize, defaultEmojiSize); + super.setText(spannableStringBuilder, type); + } else { + super.setText(rawText, type); + } + + } + + /** + * sets the emoji size in pixels and automatically invalidates the text and renders it with the new size + */ + public final void setEmojiSize(@Px final int pixels) { + setEmojiSize(pixels, true); + } + + /** + * sets the emoji size in pixels and automatically invalidates the text and renders it with the new size when {@code shouldInvalidate} is true + */ + public final void setEmojiSize(@Px final int pixels, final boolean shouldInvalidate) { + emojiSize = pixels; + + if (shouldInvalidate) { + setText(getText()); + } + } + + /** + * sets the emoji size in pixels with the provided resource and automatically invalidates the text and renders it with the new size + */ + public final void setEmojiSizeRes(@DimenRes final int res) { + setEmojiSizeRes(res, true); + } + + /** + * sets the emoji size in pixels with the provided resource and invalidates the text and renders it with the new size when {@code shouldInvalidate} is true + */ + public final void setEmojiSizeRes(@DimenRes final int res, final boolean shouldInvalidate) { + setEmojiSize(getResources().getDimensionPixelSize(res), shouldInvalidate); + } + +} diff --git a/app/src/playstore/java/app/fedilab/android/helper/Helper.java b/app/src/playstore/java/app/fedilab/android/helper/Helper.java new file mode 100644 index 000000000..8d473cf82 --- /dev/null +++ b/app/src/playstore/java/app/fedilab/android/helper/Helper.java @@ -0,0 +1,36 @@ +package app.fedilab.android.helper; +/* Copyright 2020 Thomas Schneider + * + * This file is a part of Fedilab + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Fedilab; if not, + * see . */ +import org.conscrypt.Conscrypt; +import java.security.Security; + +public class Helper extends BaseHelper { + public static void installProvider() { + + boolean patch_provider = true; + try { + Context ctx = MainApplication.getApp(); + SharedPreferences sharedpreferences = ctx.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE); + patch_provider = sharedpreferences.getBoolean(Helper.SET_SECURITY_PROVIDER, true); + } catch (Exception ignored) { + } + if (patch_provider) { + try { + Security.insertProviderAt(Conscrypt.newProvider(), 1); + } catch (Exception ignored) { + } + } + } +} diff --git a/app/src/playstore/java/app/fedilab/android/helper/MastalabAutoCompleteTextView.java b/app/src/playstore/java/app/fedilab/android/helper/MastalabAutoCompleteTextView.java new file mode 100644 index 000000000..dc3b50865 --- /dev/null +++ b/app/src/playstore/java/app/fedilab/android/helper/MastalabAutoCompleteTextView.java @@ -0,0 +1,195 @@ +package app.fedilab.android.helper; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.TypedArray; +import android.graphics.Paint; +import android.os.Build; +import android.os.Bundle; +import android.util.AttributeSet; +import android.view.KeyEvent; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputConnection; + +import androidx.annotation.CallSuper; +import androidx.annotation.DimenRes; +import androidx.annotation.Px; +import androidx.core.view.inputmethod.EditorInfoCompat; +import androidx.core.view.inputmethod.InputConnectionCompat; +import androidx.core.view.inputmethod.InputContentInfoCompat; + +import com.vanniktech.emoji.EmojiManager; +import com.vanniktech.emoji.emoji.Emoji; + +import app.fedilab.android.R; + +import static app.fedilab.android.activities.TootActivity.autocomplete; + +public class MastalabAutoCompleteTextView extends androidx.appcompat.widget.AppCompatAutoCompleteTextView implements EmojiEditTextInterface { + + private float emojiSize; + private boolean emoji; + private String[] imgTypeString; + private KeyBoardInputCallbackListener keyBoardInputCallbackListener; + final InputConnectionCompat.OnCommitContentListener callback = + new InputConnectionCompat.OnCommitContentListener() { + @Override + public boolean onCommitContent(InputContentInfoCompat inputContentInfo, + int flags, Bundle opts) { + + // read and display inputContentInfo asynchronously + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1 && (flags & + InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) { + try { + inputContentInfo.requestPermission(); + } catch (Exception e) { + return false; // return false if failed + } + } + boolean supported = false; + for (final String mimeType : imgTypeString) { + if (inputContentInfo.getDescription().hasMimeType(mimeType)) { + supported = true; + break; + } + } + if (!supported) { + return false; + } + + if (keyBoardInputCallbackListener != null) { + keyBoardInputCallbackListener.onCommitContent(inputContentInfo, flags, opts); + } + return true; // return true if succeeded + } + }; + + + public MastalabAutoCompleteTextView(Context context) { + super(context); + initView(); + } + + public MastalabAutoCompleteTextView(Context context, AttributeSet attrs) { + super(context, attrs); + + final Paint.FontMetrics fontMetrics = getPaint().getFontMetrics(); + final float defaultEmojiSize = fontMetrics.descent - fontMetrics.ascent; + final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE); + emoji = sharedpreferences.getBoolean(Helper.SET_DISPLAY_EMOJI, false); + if (attrs == null) { + emojiSize = defaultEmojiSize; + } else { + @SuppressLint("CustomViewStyleable") final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.EmojiMultiAutoCompleteTextView); + + try { + emojiSize = a.getDimension(R.styleable.EmojiMultiAutoCompleteTextView_emojiSize, defaultEmojiSize); + } finally { + a.recycle(); + } + } + + setText(getText()); + initView(); + } + + public MastalabAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initView(); + } + + @Override + public InputConnection onCreateInputConnection(EditorInfo outAttrs) { + final InputConnection ic = super.onCreateInputConnection(outAttrs); + EditorInfoCompat.setContentMimeTypes(outAttrs, + imgTypeString); + return InputConnectionCompat.createWrapper(ic, outAttrs, callback); + } + + private void initView() { + imgTypeString = new String[]{"image/png", + "image/gif", + "image/jpeg", + "image/webp"}; + } + + public void setKeyBoardInputCallbackListener(KeyBoardInputCallbackListener keyBoardInputCallbackListener) { + this.keyBoardInputCallbackListener = keyBoardInputCallbackListener; + } + + @SuppressWarnings("unused") + public String[] getImgTypeString() { + return imgTypeString; + } + + @SuppressWarnings("unused") + public void setImgTypeString(String[] imgTypeString) { + this.imgTypeString = imgTypeString; + } + + @Override + @CallSuper + protected void onTextChanged(final CharSequence text, final int start, final int lengthBefore, final int lengthAfter) { + final Paint.FontMetrics fontMetrics = getPaint().getFontMetrics(); + final float defaultEmojiSize = fontMetrics.descent - fontMetrics.ascent; + if (emoji && !autocomplete) { + EmojiManager.getInstance().replaceWithImages(getContext(), getText(), emojiSize, defaultEmojiSize); + } + } + + @Override + public void backspace() { + final KeyEvent event = new KeyEvent(0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL); + dispatchKeyEvent(event); + } + + @Override + public float getEmojiSize() { + return emojiSize; + } + + @Override + public final void setEmojiSize(@Px final int pixels) { + setEmojiSize(pixels, true); + } + + @Override + @CallSuper + public void input(final Emoji emoji) { + if (emoji != null && !autocomplete) { + final int start = getSelectionStart(); + final int end = getSelectionEnd(); + + if (start < 0) { + append(emoji.getUnicode()); + } else { + getText().replace(Math.min(start, end), Math.max(start, end), emoji.getUnicode(), 0, emoji.getUnicode().length()); + } + } + } + + @Override + public final void setEmojiSize(@Px final int pixels, final boolean shouldInvalidate) { + emojiSize = pixels; + + if (shouldInvalidate && !autocomplete) { + setText(getText()); + } + } + + @Override + public final void setEmojiSizeRes(@DimenRes final int res) { + setEmojiSizeRes(res, true); + } + + @Override + public final void setEmojiSizeRes(@DimenRes final int res, final boolean shouldInvalidate) { + setEmojiSize(getResources().getDimensionPixelSize(res), shouldInvalidate); + } + + public interface KeyBoardInputCallbackListener { + void onCommitContent(InputContentInfoCompat inputContentInfo, + int flags, Bundle opts); + } +}