Browse Source

Merge pull request #45 from ThmmyNoLife/editor_view

Editor view
pull/50/head
oogee 6 years ago
committed by GitHub
parent
commit
e9243b8e34
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      app/build.gradle
  2. 3
      app/src/main/AndroidManifest.xml
  3. 35
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
  4. 86
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
  5. 1
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java
  6. 55
      app/src/main/java/gr/thmmy/mthmmy/editorview/AutoFitGridLayout.java
  7. 283
      app/src/main/java/gr/thmmy/mthmmy/editorview/EditorView.java
  8. 241
      app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboard.java
  9. 64
      app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboardAdapter.java
  10. 6
      app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
  11. 240
      app/src/main/res/drawable/emoji_a_eatpaper.xml
  12. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f0.png
  13. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f1.png
  14. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f10.png
  15. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f11.png
  16. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f12.png
  17. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f13.png
  18. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f14.png
  19. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f15.png
  20. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f16.png
  21. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f17.png
  22. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f18.png
  23. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f19.png
  24. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f2.png
  25. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f20.png
  26. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f21.png
  27. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f22.png
  28. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f23.png
  29. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f24.png
  30. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f25.png
  31. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f26.png
  32. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f27.png
  33. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f28.png
  34. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f29.png
  35. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f3.png
  36. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f30.png
  37. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f31.png
  38. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f32.png
  39. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f33.png
  40. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f34.png
  41. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f35.png
  42. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f36.png
  43. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f37.png
  44. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f38.png
  45. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f39.png
  46. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f4.png
  47. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f40.png
  48. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f41.png
  49. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f42.png
  50. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f43.png
  51. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f44.png
  52. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f45.png
  53. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f46.png
  54. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f47.png
  55. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f48.png
  56. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f49.png
  57. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f5.png
  58. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f50.png
  59. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f51.png
  60. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f52.png
  61. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f53.png
  62. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f54.png
  63. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f55.png
  64. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f56.png
  65. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f57.png
  66. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f58.png
  67. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f59.png
  68. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f6.png
  69. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f60.png
  70. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f61.png
  71. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f62.png
  72. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f63.png
  73. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f64.png
  74. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f65.png
  75. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f66.png
  76. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f67.png
  77. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f68.png
  78. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f69.png
  79. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f7.png
  80. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f70.png
  81. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f71.png
  82. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f72.png
  83. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f73.png
  84. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f74.png
  85. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f75.png
  86. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f76.png
  87. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f77.png
  88. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f8.png
  89. BIN
      app/src/main/res/drawable/emoji_a_eatpaper_f9.png
  90. 18
      app/src/main/res/drawable/emoji_angry.xml
  91. 30
      app/src/main/res/drawable/emoji_angry4.xml
  92. BIN
      app/src/main/res/drawable/emoji_angry4_f0.png
  93. BIN
      app/src/main/res/drawable/emoji_angry4_f1.png
  94. BIN
      app/src/main/res/drawable/emoji_angry4_f2.png
  95. BIN
      app/src/main/res/drawable/emoji_angry4_f3.png
  96. BIN
      app/src/main/res/drawable/emoji_angry4_f4.png
  97. BIN
      app/src/main/res/drawable/emoji_angry4_f5.png
  98. BIN
      app/src/main/res/drawable/emoji_angry4_f6.png
  99. BIN
      app/src/main/res/drawable/emoji_angry4_f7.png
  100. BIN
      app/src/main/res/drawable/emoji_angry_f0.png

2
app/build.gradle

@ -55,7 +55,7 @@ dependencies {
}
implementation 'com.mikepenz:fontawesome-typeface:4.7.0.0@aar'
implementation 'com.mikepenz:google-material-typeface:3.0.1.2.original@aar'
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.12'
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.15'
implementation 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1'//TODO: deprecated!
implementation 'me.zhanghai.android.materialprogressbar:library:1.4.2'
implementation 'com.jakewharton.timber:timber:4.7.0'

3
app/src/main/AndroidManifest.xml

@ -40,15 +40,12 @@
<data
android:host="www.thmmy.gr"
android:scheme="http" />
<data
android:host="www.thmmy.gr"
android:scheme="https" />
<data
android:host="thmmy.gr"
android:scheme="https" />
<data android:host="thmmy.gr" />
</intent-filter>
</activity>

35
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java

@ -23,6 +23,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageButton;
import android.widget.LinearLayout;
@ -44,6 +45,7 @@ import gr.thmmy.mthmmy.model.Bookmark;
import gr.thmmy.mthmmy.model.Post;
import gr.thmmy.mthmmy.model.ThmmyPage;
import gr.thmmy.mthmmy.utils.CustomLinearLayoutManager;
import gr.thmmy.mthmmy.editorview.EmojiKeyboard;
import gr.thmmy.mthmmy.utils.HTMLUtils;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
import gr.thmmy.mthmmy.viewmodel.TopicViewModel;
@ -59,7 +61,8 @@ import static gr.thmmy.mthmmy.services.NotificationService.NEW_POST_TAG;
* key {@link #BUNDLE_TOPIC_TITLE} for faster title rendering.
*/
@SuppressWarnings("unchecked")
public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFocusChangeListener {
public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFocusChangeListener,
EmojiKeyboard.EmojiKeyboardOwner{
//Activity's variables
/**
* The key to use when putting topic's url String to {@link TopicActivity}'s Bundle.
@ -112,6 +115,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
private ImageButton lastPage;
private Snackbar snackbar;
private TopicViewModel viewModel;
private EmojiKeyboard emojiKeyboard;
//Fix for vector drawables on android <21
static {
@ -159,6 +163,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
createDrawer();
progressBar = findViewById(R.id.progressBar);
emojiKeyboard = findViewById(R.id.emoji_keyboard);
postsList = new ArrayList<>();
@ -255,6 +260,19 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
if (drawer.isDrawerOpen()) {
drawer.closeDrawer();
return;
} else if (emojiKeyboard.getVisibility() == View.VISIBLE) {
emojiKeyboard.setVisibility(View.GONE);
if (viewModel.isEditingPost()) {
TopicAdapter.EditMessageViewHolder vh = (TopicAdapter.EditMessageViewHolder)
recyclerView.findViewHolderForAdapterPosition(viewModel.getPostBeingEditedPosition());
vh.editEditor.updateEmojiKeyboardVisibility();
}
if (viewModel.isWritingReply()) {
TopicAdapter.QuickReplyViewHolder vh = (TopicAdapter.QuickReplyViewHolder)
recyclerView.findViewHolderForAdapterPosition(viewModel.postCount());
vh.replyEditor.updateEmojiKeyboardVisibility();
}
return;
} else if (viewModel.isWritingReply()) {
postsList.remove(postsList.size() - 1);
topicAdapter.notifyItemRemoved(postsList.size());
@ -294,6 +312,21 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
recyclerView.scrollToPosition(position);
}
@Override
public void setEmojiKeyboardVisible(boolean visible) {
emojiKeyboard.setVisibility(visible ? View.VISIBLE : View.GONE);
}
@Override
public boolean isEmojiKeyboardVisible() {
return emojiKeyboard.getVisibility() == View.VISIBLE;
}
@Override
public void setEmojiKeyboardInputConnection(InputConnection ic) {
emojiKeyboard.setInputConnection(ic);
}
//--------------------------------------BOTTOM NAV BAR METHODS----------------------------------
/**

86
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java

@ -15,12 +15,12 @@ import android.support.annotation.NonNull;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.content.res.AppCompatResources;
import android.support.v7.widget.AppCompatImageButton;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
@ -46,6 +46,8 @@ import gr.thmmy.mthmmy.model.Post;
import gr.thmmy.mthmmy.model.ThmmyFile;
import gr.thmmy.mthmmy.model.ThmmyPage;
import gr.thmmy.mthmmy.utils.CircleTransform;
import gr.thmmy.mthmmy.editorview.EditorView;
import gr.thmmy.mthmmy.editorview.EmojiKeyboard;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
import gr.thmmy.mthmmy.viewmodel.TopicViewModel;
import timber.log.Timber;
@ -71,6 +73,7 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static int THUMBNAIL_SIZE;
private final Context context;
private final OnPostFocusChangeListener postFocusListener;
private final EmojiKeyboard.EmojiKeyboardOwner emojiKeyboardOwner;
private final List<Post> postsList;
private TopicViewModel viewModel;
@ -82,6 +85,7 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
this.context = context;
this.postsList = postsList;
this.postFocusListener = context;
this.emojiKeyboardOwner = context;
viewModel = ViewModelProviders.of(context).get(TopicViewModel.class);
@ -103,9 +107,8 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
} else if (viewType == Post.TYPE_QUICK_REPLY) {
View view = LayoutInflater.from(parent.getContext()).
inflate(R.layout.activity_topic_quick_reply_row, parent, false);
view.findViewById(R.id.quick_reply_submit).setEnabled(true);
final EditText quickReplyText = view.findViewById(R.id.quick_reply_text);
final EditText quickReplyText = ((EditorView) view.findViewById(R.id.reply_editorview)).getEditText();
quickReplyText.setFocusableInTouchMode(true);
quickReplyText.setOnFocusChangeListener((v, hasFocus) -> quickReplyText.post(() -> {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
@ -117,9 +120,8 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
} else if (viewType == Post.TYPE_EDIT) {
View view = LayoutInflater.from(parent.getContext()).
inflate(R.layout.activity_topic_edit_row, parent, false);
view.findViewById(R.id.edit_message_submit).setEnabled(true);
final EditText editPostEdittext = view.findViewById(R.id.edit_message_text);
final EditText editPostEdittext = ((EditorView) view.findViewById(R.id.edit_editorview)).getEditText();
editPostEdittext.setFocusableInTouchMode(true);
editPostEdittext.setOnFocusChangeListener((v, hasFocus) -> editPostEdittext.post(() -> {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
@ -428,14 +430,14 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
if (viewModel.getToQuoteList().contains(currentPost.getPostIndex()))
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_checked_accent_24dp);
else
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_unchecked_grey_24dp);
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_unchecked_24dp);
//Sets graphics behavior
holder.quoteToggle.setOnClickListener(view -> {
viewModel.postIndexToggle(currentPost.getPostIndex());
if (viewModel.getToQuoteList().contains(currentPost.getPostIndex()))
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_checked_accent_24dp);
else
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_unchecked_grey_24dp);
holder.quoteToggle.setImageResource(R.drawable.ic_format_quote_unchecked_24dp);
});
}
} else if (currentHolder instanceof QuickReplyViewHolder) {
@ -455,24 +457,36 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
holder.username.setText(getSessionManager().getUsername());
holder.quickReplySubject.setText("Re: " + viewModel.getTopicTitle().getValue());
holder.quickReply.setText(viewModel.getBuildedQuotes());
holder.replyEditor.setEmojiKeyboardOwner(emojiKeyboardOwner);
InputConnection ic = holder.replyEditor.getInputConnection();
emojiKeyboardOwner.setEmojiKeyboardInputConnection(ic);
holder.replyEditor.updateEmojiKeyboardVisibility();
holder.replyEditor.getEditText().setOnFocusChangeListener((v, hasFocus) -> {
InputConnection ic12 = holder.replyEditor.getInputConnection();
emojiKeyboardOwner.setEmojiKeyboardInputConnection(ic12);
holder.replyEditor.updateEmojiKeyboardVisibility();
});
holder.submitButton.setOnClickListener(view -> {
holder.replyEditor.setText(viewModel.getBuildedQuotes());
holder.replyEditor.setOnSubmitListener(view -> {
if (holder.quickReplySubject.getText().toString().isEmpty()) return;
if (holder.quickReply.getText().toString().isEmpty()) return;
if (holder.replyEditor.getText().toString().isEmpty()) {
holder.replyEditor.setError("Required");
return;
}
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
holder.itemView.setAlpha(0.5f);
holder.itemView.setEnabled(false);
emojiKeyboardOwner.setEmojiKeyboardVisible(false);
viewModel.postReply(context, holder.quickReplySubject.getText().toString(),
holder.quickReply.getText().toString());
holder.replyEditor.getText().toString());
});
holder.replyEditor.setOnClickListener(view -> holder.replyEditor.setError(null));
if (backPressHidden) {
holder.quickReply.requestFocus();
holder.replyEditor.requestFocus();
backPressHidden = false;
}
} else if (currentHolder instanceof EditMessageViewHolder) {
@ -490,23 +504,37 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
.transform(new CircleTransform())
.into(holder.thumbnail);
holder.username.setText(getSessionManager().getUsername());
holder.editSubject.setText(postsList.get(position).getSubject());
holder.editMessage.setText(viewModel.getPostBeingEditedText());
holder.submitButton.setOnClickListener(view -> {
holder.editEditor.setEmojiKeyboardOwner(emojiKeyboardOwner);
InputConnection ic = holder.editEditor.getInputConnection();
emojiKeyboardOwner.setEmojiKeyboardInputConnection(ic);
holder.editEditor.updateEmojiKeyboardVisibility();
holder.editEditor.setText(viewModel.getPostBeingEditedText());
holder.editEditor.getEditText().setOnFocusChangeListener((v, hasFocus) -> {
if (hasFocus) {
InputConnection ic1 = holder.editEditor.getInputConnection();
emojiKeyboardOwner.setEmojiKeyboardInputConnection(ic1);
holder.editEditor.updateEmojiKeyboardVisibility();
}
});
holder.editEditor.setOnSubmitListener(view -> {
if (holder.editSubject.getText().toString().isEmpty()) return;
if (holder.editMessage.getText().toString().isEmpty()) return;
if (holder.editEditor.getText().toString().isEmpty()) {
holder.editEditor.setError("Required");
return;
}
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
holder.itemView.setAlpha(0.5f);
holder.itemView.setEnabled(false);
emojiKeyboardOwner.setEmojiKeyboardVisible(false);
viewModel.editPost(position, holder.editSubject.getText().toString(), holder.editMessage.getText().toString());
viewModel.editPost(position, holder.editSubject.getText().toString(), holder.editEditor.getText().toString());
});
if (backPressHidden) {
holder.editMessage.requestFocus();
holder.editEditor.requestFocus();
backPressHidden = false;
}
}
@ -572,36 +600,34 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
/**
* Custom {@link RecyclerView.ViewHolder} implementation
*/
private static class QuickReplyViewHolder extends RecyclerView.ViewHolder {
static class QuickReplyViewHolder extends RecyclerView.ViewHolder {
final ImageView thumbnail;
final TextView username;
final EditText quickReply, quickReplySubject;
final AppCompatImageButton submitButton;
final EditText quickReplySubject;
final EditorView replyEditor;
QuickReplyViewHolder(View quickReply) {
super(quickReply);
thumbnail = quickReply.findViewById(R.id.thumbnail);
username = quickReply.findViewById(R.id.username);
this.quickReply = quickReply.findViewById(R.id.quick_reply_text);
quickReplySubject = quickReply.findViewById(R.id.quick_reply_subject);
submitButton = quickReply.findViewById(R.id.quick_reply_submit);
replyEditor = quickReply.findViewById(R.id.reply_editorview);
}
}
private static class EditMessageViewHolder extends RecyclerView.ViewHolder {
static class EditMessageViewHolder extends RecyclerView.ViewHolder {
final ImageView thumbnail;
final TextView username;
final EditText editMessage, editSubject;
final AppCompatImageButton submitButton;
final EditText editSubject;
final EditorView editEditor;
EditMessageViewHolder(View editView) {
super(editView);
thumbnail = editView.findViewById(R.id.thumbnail);
username = editView.findViewById(R.id.username);
editMessage = editView.findViewById(R.id.edit_message_text);
editSubject = editView.findViewById(R.id.edit_message_subject);
submitButton = editView.findViewById(R.id.edit_message_submit);
editEditor = editView.findViewById(R.id.edit_editorview);
}
}

1
app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java

@ -139,7 +139,6 @@ public class TopicTask extends AsyncTask<String, Void, TopicTaskResult> {
public interface TopicTaskObserver {
void onTopicTaskStarted();
void onTopicTaskCancelled();
}

55
app/src/main/java/gr/thmmy/mthmmy/editorview/AutoFitGridLayout.java

@ -0,0 +1,55 @@
package gr.thmmy.mthmmy.editorview;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.widget.GridLayout;
import gr.thmmy.mthmmy.R;
public class AutoFitGridLayout extends GridLayout {
private int columnWidth;
private int defaultColumnCount;
public AutoFitGridLayout(Context context) {
super(context);
init(context, null, 0);
}
public AutoFitGridLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public AutoFitGridLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
public void init(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoFitGridLayout, 0, defStyleAttr);
try {
columnWidth = a.getDimensionPixelSize(R.styleable.AutoFitGridLayout_columnWidth, 0);
int[] set = {android.R.attr.columnCount};
a = context.obtainStyledAttributes(attrs, set, 0, defStyleAttr);
defaultColumnCount = a.getInt(0, 6);
} finally {
a.recycle();
}
setColumnCount(1);
}
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
super.onMeasure(widthSpec, heightSpec);
int width = MeasureSpec.getSize(widthSpec);
if (columnWidth > 0 && width > 0) {
int totalSpace = width - getPaddingRight() - getPaddingLeft();
int columnCount = Math.max(1, totalSpace / columnWidth);
setColumnCount(columnCount);
} else {
setColumnCount(defaultColumnCount);
}
}
}

283
app/src/main/java/gr/thmmy/mthmmy/editorview/EditorView.java

@ -0,0 +1,283 @@
package gr.thmmy.mthmmy.editorview;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputEditText;
import android.support.design.widget.TextInputLayout;
import android.support.v7.widget.AppCompatImageButton;
import android.text.Editable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.ScrollView;
import java.util.Objects;
import gr.thmmy.mthmmy.R;
public class EditorView extends LinearLayout {
private SparseArray<String> colors = new SparseArray<>();
private TextInputLayout edittextWrapper;
private TextInputEditText editText;
private AppCompatImageButton emojiButton;
private AppCompatImageButton submitButton;
private EmojiKeyboard.EmojiKeyboardOwner emojiKeyboardOwner;
public EditorView(Context context) {
super(context);
init(context, null);
}
public EditorView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public EditorView(Context context, AttributeSet attrs, int defStyleAttrs) {
super(context, attrs, defStyleAttrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
LayoutInflater.from(context).inflate(R.layout.editor_view, this, true);
setOrientation(VERTICAL);
edittextWrapper = findViewById(R.id.editor_edittext_wrapper);
editText = findViewById(R.id.editor_edittext);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.EditorView, 0, 0);
try {
editText.setHint(a.getString(R.styleable.EditorView_hint));
} finally {
a.recycle();
}
// without this, the editor gets default window background
Drawable background = getBackground();
for (int i = 0; i < getChildCount(); i++) {
getChildAt(i).setBackground(background);
}
emojiButton = findViewById(R.id.emoji_keyboard_button);
editText.setOnTouchListener((v, event) -> {
if (emojiKeyboardOwner.isEmojiKeyboardVisible()) return true;
return false;
});
emojiButton.setOnClickListener(view -> {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
assert imm != null;
if (emojiKeyboardOwner.isEmojiKeyboardVisible()) {
editText.requestFocus();
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
emojiButton.setImageResource(R.drawable.ic_tag_faces_24dp);
} else {
imm.hideSoftInputFromWindow(getWindowToken(), 0);
view.clearFocus();
emojiButton.setImageResource(R.drawable.ic_keyboard_24dp);
}
emojiKeyboardOwner.setEmojiKeyboardVisible(!emojiKeyboardOwner.isEmojiKeyboardVisible());
});
submitButton = findViewById(R.id.submit_button);
findViewById(R.id.bold_button).setOnClickListener(view -> {
boolean hadTextSelection = editText.hasSelection();
getText().insert(editText.getSelectionStart(), "[b]");
getText().insert(editText.getSelectionEnd(), "[/b]");
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 4);
});
findViewById(R.id.italic_button).setOnClickListener(view -> {
boolean hadTextSelection = editText.hasSelection();
getText().insert(editText.getSelectionStart(), "[i]");
getText().insert(editText.getSelectionEnd(), "[/i]");
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 4);
});
findViewById(R.id.underline_button).setOnClickListener(view -> {
boolean hadTextSelection = editText.hasSelection();
getText().insert(editText.getSelectionStart(), "[u]");
getText().insert(editText.getSelectionEnd(), "[/u]");
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 4);
});
findViewById(R.id.strikethrough_button).setOnClickListener(view -> {
boolean hadTextSelection = editText.hasSelection();
getText().insert(editText.getSelectionStart(), "[s]");
getText().insert(editText.getSelectionEnd(), "[/s]");
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 4);
});
colors.append(R.id.black, "black");
colors.append(R.id.red, "red");
colors.append(R.id.yellow, "yellow");
colors.append(R.id.pink, "pink");
colors.append(R.id.green, "green");
colors.append(R.id.orange, "orange");
colors.append(R.id.purple, "purple");
colors.append(R.id.blue, "blue");
colors.append(R.id.beige, "beige");
colors.append(R.id.brown, "brown");
colors.append(R.id.teal, "teal");
colors.append(R.id.navy, "navy");
colors.append(R.id.maroon, "maroon");
colors.append(R.id.lime_green, "limegreen");
findViewById(R.id.text_color_button).setOnClickListener(view -> {
PopupWindow popupWindow = new PopupWindow(view.getContext());
popupWindow.setHeight(LayoutParams.WRAP_CONTENT);
popupWindow.setWidth(LayoutParams.WRAP_CONTENT);
popupWindow.setFocusable(true);
ScrollView colorPickerScrollview = (ScrollView) LayoutInflater.from(context).inflate(R.layout.editor_view_color_picker, null);
LinearLayout colorPicker = (LinearLayout) colorPickerScrollview.getChildAt(0);
popupWindow.setContentView(colorPickerScrollview);
for (int i = 0; i < colorPicker.getChildCount(); i++) {
colorPicker.getChildAt(i).setOnClickListener(v -> {
boolean hadTextSelection = editText.hasSelection();
getText().insert(editText.getSelectionStart(), "[color=" + colors.get(v.getId()) + "]");
getText().insert(editText.getSelectionEnd(), "[/color]");
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 8);
popupWindow.dismiss();
});
}
popupWindow.showAsDropDown(view);
});
findViewById(R.id.text_size_button).setOnClickListener(view -> {
boolean hadTextSelection = editText.hasSelection();
getText().insert(editText.getSelectionStart(), "[size=10pt]");
getText().insert(editText.getSelectionEnd(), "[/size]");
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 7);
});
findViewById(R.id.font_button).setOnClickListener(view -> {
boolean hadTextSelection = editText.hasSelection();
getText().insert(editText.getSelectionStart(), "[font=Verdana]");
getText().insert(editText.getSelectionEnd(), "[/font]");
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 7);
});
findViewById(R.id.unordered_list_button).setOnClickListener(view -> {
boolean hadTextSelection = editText.hasSelection();
getText().insert(editText.getSelectionStart(), "[list]\n[li]");
getText().insert(editText.getSelectionEnd(), "[/li]\n[li][/li]\n[/list]");
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() - 13 : editText.getSelectionStart() - 23);
});
findViewById(R.id.align_left_button).setOnClickListener(view -> {
boolean hadTextSelection = editText.hasSelection();
getText().insert(editText.getSelectionStart(), "[left]");
getText().insert(editText.getSelectionEnd(), "[/left]");
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 7);
});
findViewById(R.id.align_center_button).setOnClickListener(view -> {
boolean hadTextSelection = editText.hasSelection();
getText().insert(editText.getSelectionStart(), "[center]");
getText().insert(editText.getSelectionEnd(), "[/center]");
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 9);
});
findViewById(R.id.align_right_button).setOnClickListener(view -> {
boolean hadTextSelection = editText.hasSelection();
getText().insert(editText.getSelectionStart(), "[right]");
getText().insert(editText.getSelectionEnd(), "[/right]");
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 8);
});
findViewById(R.id.link_button).setOnClickListener(view -> {
LinearLayout dialogBody = (LinearLayout) LayoutInflater.from(context)
.inflate(R.layout.dialog_create_link, null);
TextInputLayout linkUrl = dialogBody.findViewById(R.id.link_url_input);
linkUrl.setOnClickListener(view1 -> linkUrl.setError(null));
TextInputLayout linkText = dialogBody.findViewById(R.id.link_text_input);
linkText.setOnClickListener(view2 -> linkText.setError(null));
boolean hadTextSelection = editText.hasSelection();
int start = editText.getSelectionStart(), end = editText.getSelectionEnd();
if (editText.hasSelection()) {
linkText.getEditText().setText(
editText.getText().toString().substring(editText.getSelectionStart(), editText.getSelectionEnd()));
}
new AlertDialog.Builder(context, R.style.AppCompatAlertDialogStyleAccent)
.setTitle(R.string.dialog_create_link_title)
.setView(dialogBody)
.setPositiveButton(R.string.ok, (dialog, which) -> {
if (TextUtils.isEmpty(Objects.requireNonNull(linkUrl.getEditText()).getText().toString())) {
linkUrl.setError(context.getString(R.string.input_field_required));
return;
}
if (TextUtils.isEmpty(Objects.requireNonNull(linkText.getEditText()).getText().toString())) {
linkUrl.setError(context.getString(R.string.input_field_required));
return;
}
if (hadTextSelection) editText.getText().delete(start, end);
getText().insert(editText.getSelectionStart(), "[url=" +
Objects.requireNonNull(linkUrl.getEditText()).getText().toString() + "]" +
Objects.requireNonNull(linkText.getEditText()).getText().toString() + "[/url]");
})
.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss())
.show();
});
findViewById(R.id.quote_button).setOnClickListener(view -> {
boolean hadTextSelection = editText.hasSelection();
getText().insert(editText.getSelectionStart(), "[quote]");
getText().insert(editText.getSelectionEnd(), "[/quote]");
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 8);
});
findViewById(R.id.code_button).setOnClickListener(view -> {
boolean hadTextSelection = editText.hasSelection();
getText().insert(editText.getSelectionStart(), "[code]");
getText().insert(editText.getSelectionEnd(), "[/code]");
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 7);
});
findViewById(R.id.math_button).setOnClickListener(view -> {
boolean hadTextSelection = editText.hasSelection();
getText().insert(editText.getSelectionStart(), "[tex]");
getText().insert(editText.getSelectionEnd(), "[/tex]");
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 6);
});
}
public TextInputEditText getEditText() {
return editText;
}
public Editable getText() {
return editText.getText();
}
public void setText(Editable text) {
editText.setText(text);
}
public void setText(CharSequence text) {
editText.setText(text);
}
public void setError(@Nullable CharSequence text) {
edittextWrapper.setError(text);
}
public void setOnSubmitListener(OnClickListener onSubmitListener) {
submitButton.setOnClickListener(onSubmitListener);
}
public void setEmojiKeyboardOwner(EmojiKeyboard.EmojiKeyboardOwner emojiKeyboardOwner) {
this.emojiKeyboardOwner = emojiKeyboardOwner;
}
public InputConnection getInputConnection() {
return editText.onCreateInputConnection(new EditorInfo());
}
public void updateEmojiKeyboardVisibility() {
if (emojiKeyboardOwner.isEmojiKeyboardVisible())
emojiButton.setImageResource(R.drawable.ic_keyboard_24dp);
else
emojiButton.setImageResource(R.drawable.ic_tag_faces_24dp);
}
}

241
app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboard.java

@ -0,0 +1,241 @@
package gr.thmmy.mthmmy.editorview;
import android.content.Context;
import android.os.Handler;
import android.support.v7.widget.AppCompatImageButton;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.inputmethod.InputConnection;
import android.widget.LinearLayout;
import gr.thmmy.mthmmy.R;
public class EmojiKeyboard extends LinearLayout {
// TODO: Sort emojis in a way that makes sense
private final Emoji[] emojis = {new Emoji(R.drawable.emoji_smiley, ":)"),
new Emoji(R.drawable.emoji_wink, ";)"),
new Emoji(R.drawable.emoji_cheesy, ":D"),
new Emoji(R.drawable.emoji_grin, ";D"),
// removed repeated angry emoji
new Emoji(R.drawable.emoji_angry, ">:("),
new Emoji(R.drawable.emoji_sad, ":("),
new Emoji(R.drawable.emoji_shocked, ":o"),
new Emoji(R.drawable.emoji_cool, "8))"),
new Emoji(R.drawable.emoji_huh, ":???:"),
new Emoji(R.drawable.emoji_rolleyes, "::)"),
new Emoji(R.drawable.emoji_tongue, ":P"),
new Emoji(R.drawable.emoji_embarrassed, ":-["),
new Emoji(R.drawable.emoji_lipsrsealed, ":-X"),
new Emoji(R.drawable.emoji_undecided, ":-\\\\"),
new Emoji(R.drawable.emoji_kiss, ":-*"),
new Emoji(R.drawable.emoji_cry, ":'("),
new Emoji(R.drawable.emoji_heart, "<3"),
// removed repeated lock emoji
new Emoji(R.drawable.emoji_locked, "^lock^"),
new Emoji(R.drawable.emoji_roll_over, "^rollover^"),
new Emoji(R.drawable.emoji_redface, "^redface^"),
new Emoji(R.drawable.emoji_confused, "^confused^"),
new Emoji(R.drawable.emoji_innocent, "^innocent^"),
new Emoji(R.drawable.emoji_sleep, "^sleep^"),
new Emoji(R.drawable.emoji_lips_sealed, "^sealed^"),
new Emoji(R.drawable.emoji_cool2, "^cool^"),
new Emoji(R.drawable.emoji_monster, "^monster^"),
new Emoji(R.drawable.emoji_crazy, "^crazy^"),
new Emoji(R.drawable.emoji_mad, "^mad^"),
new Emoji(R.drawable.emoji_wav, "^wav^"),
new Emoji(R.drawable.emoji_binkybaby, "^binkybaby^"),
new Emoji(R.drawable.emoji_police, "^police^"),
new Emoji(R.drawable.emoji_dontknow, "^dontknow^"),
//removed repeated angry hot emoji
new Emoji(R.drawable.emoji_angry_hot, "^angryhot^"),
new Emoji(R.drawable.emoji_foyska, "^fouska^"),
new Emoji(R.drawable.emoji_e10_7_3e, "^sfinaki^"),
new Emoji(R.drawable.emoji_bang_head, "^banghead^"),
new Emoji(R.drawable.emoji_crybaby, "^crybaby^"),
new Emoji(R.drawable.emoji_hello, "^hello^"),
new Emoji(R.drawable.emoji_jerk, "^jerk^"),
new Emoji(R.drawable.emoji_nono, "^nono^"),
new Emoji(R.drawable.emoji_notworthy, "^notworthy^"),
new Emoji(R.drawable.emoji_off_topic, "^off-topic^"),
new Emoji(R.drawable.emoji_puke, "^puke^"),
new Emoji(R.drawable.emoji_shout, "^shout^"),
new Emoji(R.drawable.emoji_slurp, "^slurp^"),
new Emoji(R.drawable.emoji_superconfused, "^superconfused^"),
new Emoji(R.drawable.emoji_superinnocent, "^superinnocent^"),
new Emoji(R.drawable.emoji_cell_phone, "^cellPhone^"),
new Emoji(R.drawable.emoji_idiot, "^idiot^"),
new Emoji(R.drawable.emoji_knuppel, "^knuppel^"),
new Emoji(R.drawable.emoji_tickedoff, "^tickedOff^"),
new Emoji(R.drawable.emoji_peace, "^peace^"),
new Emoji(R.drawable.emoji_suspicious, "^suspicious^"),
new Emoji(R.drawable.emoji_caffine, "^caffine^"),
new Emoji(R.drawable.emoji_argue, "^argue^"),
new Emoji(R.drawable.emoji_banned2, "^banned2^"),
new Emoji(R.drawable.emoji_banned, "^banned^"),
new Emoji(R.drawable.emoji_bath, "^bath^"),
new Emoji(R.drawable.emoji_beg, "^beg^"),
new Emoji(R.drawable.emoji_bluescreen, "^bluescreen^"),
new Emoji(R.drawable.emoji_boil, "^boil^"),
new Emoji(R.drawable.emoji_bye, "^bye^"),
new Emoji(R.drawable.emoji_callmerip, "^callmerip^"),
new Emoji(R.drawable.emoji_carnaval, "^carnaval^"),
new Emoji(R.drawable.emoji_clap, "^clap^"),
new Emoji(R.drawable.emoji_coffeepot, "^coffepot^"),
new Emoji(R.drawable.emoji_crap, "^crap^"),
new Emoji(R.drawable.emoji_curses, "^curses^"),
new Emoji(R.drawable.emoji_funny, "^funny^"),
new Emoji(R.drawable.emoji_guitar1, "^guitar^"),
new Emoji(R.drawable.emoji_icon_kissy, "^kissy^"),
new Emoji(R.drawable.emoji_band, "^band^"),
new Emoji(R.drawable.emoji_ivres, "^ivres^"),
new Emoji(R.drawable.emoji_kaloe, "^kaloe^"),
new Emoji(R.drawable.emoji_kremala, "^kremala^"),
new Emoji(R.drawable.emoji_moon, "^moon^"),
new Emoji(R.drawable.emoji_mopping, "^mopping^"),
new Emoji(R.drawable.emoji_mountza, "^mountza^"),
new Emoji(R.drawable.emoji_pcsleep, "^pcsleep^"),
new Emoji(R.drawable.emoji_pinokio, "^pinokio^"),
new Emoji(R.drawable.emoji_poke, "^poke^"),
new Emoji(R.drawable.emoji_seestars, "^seestars^"),
new Emoji(R.drawable.emoji_sfyri, "^sfyri^"),
new Emoji(R.drawable.emoji_spam2, "^spam^"),
new Emoji(R.drawable.emoji_esuper, "^super^"),
new Emoji(R.drawable.emoji_tafos, "^tafos^"),
new Emoji(R.drawable.emoji_tomatomourh, "^tomato^"),
new Emoji(R.drawable.emoji_ytold, "^ytold^"),
new Emoji(R.drawable.emoji_beer2, "^beer^"),
new Emoji(R.drawable.emoji_yu, "^yue^"),
new Emoji(R.drawable.emoji_a_eatpaper, "^eatpaper^"),
new Emoji(R.drawable.emoji_fritz, "^fritz^"),
new Emoji(R.drawable.emoji_wade, "^wade^"),
new Emoji(R.drawable.emoji_lypi, "^lypi^"),
new Emoji(R.drawable.emoji_megashok1wq, "^aytoxeir^"),
new Emoji(R.drawable.emoji_victory, "^victory^"),
new Emoji(R.drawable.emoji_filarakia, "^filarakia^"),
new Emoji(R.drawable.emoji_bonjour_97213, "^hat^"),
new Emoji(R.drawable.emoji_curtseyqi9, "^miss^"),
new Emoji(R.drawable.emoji_rofl, "^rolfmao^"),
new Emoji(R.drawable.emoji_question, "^que^"),
new Emoji(R.drawable.emoji_shifty, "^shifty^"),
new Emoji(R.drawable.emoji_shy, "^shy^"),
new Emoji(R.drawable.emoji_music, "^music_listen^"),
new Emoji(R.drawable.emoji_shamed_bag, "^bagface^"),
new Emoji(R.drawable.emoji_rotfl, "^rotate^"),
new Emoji(R.drawable.emoji_love, "^love^"),
new Emoji(R.drawable.emoji_speech, "^speech^"),
new Emoji(R.drawable.emoji_facepalm, "^facepalm^"),
new Emoji(R.drawable.emoji_shocked2, "^shocked^"),
new Emoji(R.drawable.emoji_extremely_shocked, "^ex_shocked^"),
new Emoji(R.drawable.emoji_smurf, "^smurf^")
};
InputConnection inputConnection;
public EmojiKeyboard(Context context) {
this(context, null, 0);
}
public EmojiKeyboard(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public EmojiKeyboard(Context context, AttributeSet attrs, int defStyleAttrs) {
super(context, attrs, defStyleAttrs);
init(context, attrs);
}
public void init(Context context, AttributeSet attrs) {
LayoutInflater.from(context).inflate(R.layout.emoji_keyboard, this, true);
setOrientation(VERTICAL);
RecyclerView emojiRecyclerview = findViewById(R.id.emoji_recyclerview);
emojiRecyclerview.setHasFixedSize(true);
GridLayoutManager emojiLayoutManager = new GridLayoutManager(context, 6);
emojiLayoutManager.setSpanSizeLookup(new EmojiColumnSpanLookup());
emojiRecyclerview.setLayoutManager(emojiLayoutManager);
EmojiKeyboardAdapter emojiKeyboardAdapter = new EmojiKeyboardAdapter(emojis);
emojiKeyboardAdapter.setOnEmojiClickListener((view, position) -> {
if (inputConnection == null) return;
String bbcode = emojis[position].getBbcode();
inputConnection.commitText(" " + bbcode, 1);
});
emojiRecyclerview.setAdapter(emojiKeyboardAdapter);
AppCompatImageButton backspaceButton = findViewById(R.id.backspace_button);
// backspace behavior
final Handler handler = new Handler();
Runnable longPressed = new Runnable() {
@Override
public void run() {
inputConnection.deleteSurroundingText(1, 0);
handler.postDelayed(this, 50);
}
};
backspaceButton.setOnTouchListener((v, event) -> {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
CharSequence selectedText = inputConnection.getSelectedText(0);
if (TextUtils.isEmpty(selectedText))
inputConnection.deleteSurroundingText(1, 0);
else
inputConnection.commitText("", 1);
handler.postDelayed(longPressed, 400);
break;
case MotionEvent.ACTION_UP:
handler.removeCallbacks(longPressed);
break;
}
return true;
});
}
public void setInputConnection(InputConnection inputConnection) {
this.inputConnection = inputConnection;
}
public interface EmojiKeyboardOwner {
void setEmojiKeyboardVisible(boolean visible);
boolean isEmojiKeyboardVisible();
void setEmojiKeyboardInputConnection(InputConnection ic);
}
class Emoji {
final int src;
final String bbcode;
public Emoji(int src, String bbcode) {
this.src = src;
this.bbcode = bbcode;
}
public int getSrc() {
return src;
}
public String getBbcode() {
return bbcode;
}
}
class EmojiColumnSpanLookup extends GridLayoutManager.SpanSizeLookup {
@Override
public int getSpanSize(int position) {
switch (emojis[position].getSrc()) {
case R.drawable.emoji_wav:
return 4;
case R.drawable.emoji_band:
return 3;
case R.drawable.emoji_pcsleep:
return 2;
default:
return 1;
}
}
}
}

64
app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboardAdapter.java

@ -0,0 +1,64 @@
package gr.thmmy.mthmmy.editorview;
import android.graphics.drawable.AnimationDrawable;
import android.support.annotation.NonNull;
import android.support.v7.widget.AppCompatImageButton;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import gr.thmmy.mthmmy.R;
public class EmojiKeyboardAdapter extends RecyclerView.Adapter<EmojiKeyboardAdapter.EmojiViewHolder> {
private EmojiKeyboard.Emoji[] emojiIds;
private OnEmojiClickListener listener;
public EmojiKeyboardAdapter(EmojiKeyboard.Emoji[] emojiIds) {
this.emojiIds = emojiIds;
}
public void setOnEmojiClickListener(OnEmojiClickListener listener) {
this.listener = listener;
}
@NonNull
@Override
public EmojiViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
AppCompatImageButton emojiButton = (AppCompatImageButton) LayoutInflater.from(parent.getContext())
.inflate(R.layout.emoji_keyboard_grid_cell, parent, false);
return new EmojiViewHolder(emojiButton);
}
@Override
public void onBindViewHolder(@NonNull EmojiViewHolder holder, int position) {
holder.emojiButton.setOnClickListener(view -> listener.onEmojiClick(view, position));
}
@Override
public void onViewAttachedToWindow(@NonNull EmojiViewHolder holder) {
holder.emojiButton.setImageResource(emojiIds[holder.getAdapterPosition()].getSrc());
if (holder.emojiButton.getDrawable() instanceof AnimationDrawable) {
AnimationDrawable emojiAnimation = (AnimationDrawable) holder.emojiButton.getDrawable();
emojiAnimation.start();
}
}
@Override
public int getItemCount() {
return emojiIds.length;
}
static class EmojiViewHolder extends RecyclerView.ViewHolder {
AppCompatImageButton emojiButton;
EmojiViewHolder(AppCompatImageButton emojiButton) {
super(emojiButton);
this.emojiButton = emojiButton;
}
}
interface OnEmojiClickListener {
void onEmojiClick(View view, int position);
}
}

6
app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java

@ -386,4 +386,10 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
throw new NullPointerException("Reply preparation was not found");
return prepareForReplyResult.getValue().getBuildedQuotes();
}
public int postCount() {
if (postsList.getValue() == null)
throw new NullPointerException("No page has been loaded yet!");
return postsList.getValue().size();
}
}

240
app/src/main/res/drawable/emoji_a_eatpaper.xml

@ -0,0 +1,240 @@
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false" >
<item
android:drawable="@drawable/emoji_a_eatpaper_f0"
android:duration="500" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f1"
android:duration="500" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f2"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f3"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f4"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f5"
android:duration="500" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f6"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f7"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f8"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f9"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f10"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f11"
android:duration="500" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f12"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f13"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f14"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f15"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f16"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f17"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f18"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f19"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f20"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f21"
android:duration="500" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f22"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f23"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f24"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f25"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f26"
android:duration="400" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f27"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f28"
android:duration="400" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f29"
android:duration="300" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f30"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f31"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f32"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f33"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f34"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f35"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f36"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f37"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f38"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f39"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f40"
android:duration="300" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f41"
android:duration="50" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f42"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f43"
android:duration="10" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f44"
android:duration="10" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f45"
android:duration="300" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f46"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f47"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f48"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f49"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f50"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f51"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f52"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f53"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f54"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f55"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f56"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f57"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f58"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f59"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f60"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f61"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f62"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f63"
android:duration="200" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f64"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f65"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f66"
android:duration="300" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f67"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f68"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f69"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f70"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f71"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f72"
android:duration="150" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f73"
android:duration="700" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f74"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f75"
android:duration="700" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f76"
android:duration="100" />
<item
android:drawable="@drawable/emoji_a_eatpaper_f77"
android:duration="1000" />
</animation-list>

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f0.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f13.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f14.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f15.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f17.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f18.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f19.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f20.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f21.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f22.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f23.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f24.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f25.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f26.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f27.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f28.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f29.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f30.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f31.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f32.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f33.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f34.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f35.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f36.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f37.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f38.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f39.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f40.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f41.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f42.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f43.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f44.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f45.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f46.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f47.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f48.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f49.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f50.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f51.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f52.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f53.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f54.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f55.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f56.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f57.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f58.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f59.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f60.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f61.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f62.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f63.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f64.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f65.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f66.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f67.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f68.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f69.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f70.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f71.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f72.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f73.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f74.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f75.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f76.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f77.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

BIN
app/src/main/res/drawable/emoji_a_eatpaper_f9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

18
app/src/main/res/drawable/emoji_angry.xml

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false" >
<item
android:drawable="@drawable/emoji_angry_f0"
android:duration="100" />
<item
android:drawable="@drawable/emoji_angry_f1"
android:duration="100" />
<item
android:drawable="@drawable/emoji_angry_f2"
android:duration="100" />
<item
android:drawable="@drawable/emoji_angry_f3"
android:duration="100" />
</animation-list>

30
app/src/main/res/drawable/emoji_angry4.xml

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false" >
<item
android:drawable="@drawable/emoji_angry4_f0"
android:duration="100" />
<item
android:drawable="@drawable/emoji_angry4_f1"
android:duration="100" />
<item
android:drawable="@drawable/emoji_angry4_f2"
android:duration="100" />
<item
android:drawable="@drawable/emoji_angry4_f3"
android:duration="100" />
<item
android:drawable="@drawable/emoji_angry4_f4"
android:duration="100" />
<item
android:drawable="@drawable/emoji_angry4_f5"
android:duration="100" />
<item
android:drawable="@drawable/emoji_angry4_f6"
android:duration="100" />
<item
android:drawable="@drawable/emoji_angry4_f7"
android:duration="100" />
</animation-list>

BIN
app/src/main/res/drawable/emoji_angry4_f0.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

BIN
app/src/main/res/drawable/emoji_angry4_f1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

BIN
app/src/main/res/drawable/emoji_angry4_f2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 B

BIN
app/src/main/res/drawable/emoji_angry4_f3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

BIN
app/src/main/res/drawable/emoji_angry4_f4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

BIN
app/src/main/res/drawable/emoji_angry4_f5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

BIN
app/src/main/res/drawable/emoji_angry4_f6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

BIN
app/src/main/res/drawable/emoji_angry4_f7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

BIN
app/src/main/res/drawable/emoji_angry_f0.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save