From 9c1a4e91f3bc7435a60b6d4595d074b353f5910f Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Sun, 3 May 2020 02:48:44 +0300 Subject: [PATCH] EmojiKeyboard: add recents --- .../tusky/adapter/UnicodeEmojiAdapter.java | 65 +++++++++++++----- .../tusky/view/EmojiKeyboard.java | 67 ++++++++++++++++--- 2 files changed, 106 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/UnicodeEmojiAdapter.java b/app/src/main/java/com/keylesspalace/tusky/adapter/UnicodeEmojiAdapter.java index 47adfad3..776fa145 100644 --- a/app/src/main/java/com/keylesspalace/tusky/adapter/UnicodeEmojiAdapter.java +++ b/app/src/main/java/com/keylesspalace/tusky/adapter/UnicodeEmojiAdapter.java @@ -12,13 +12,16 @@ import androidx.emoji.text.EmojiCompat; import com.keylesspalace.tusky.R; import com.keylesspalace.tusky.view.EmojiKeyboard; import com.keylesspalace.tusky.util.Emojis; +import java.util.*; public class UnicodeEmojiAdapter extends RecyclerView.Adapter - implements TabLayoutMediator.TabConfigurationStrategy { + implements TabLayoutMediator.TabConfigurationStrategy, EmojiKeyboard.EmojiKeyboardAdapter { private String id; + private List recents; private EmojiKeyboard.OnEmojiSelectedListener listener; + private RecyclerView recentsView; private final static float BUTTON_WIDTH_DP = 65.0f; // empirically found value :( @@ -30,17 +33,27 @@ public class UnicodeEmojiAdapter @Override public void onConfigureTab(TabLayout.Tab tab, int position) { - tab.setText(Emojis.EMOJIS[position][0]); + if(position == 0) { + tab.setIcon(R.drawable.ic_access_time); + } else { + tab.setText(Emojis.EMOJIS[position - 1][0]); + } } @Override public int getItemCount() { - return Emojis.EMOJIS.length; + return Emojis.EMOJIS.length + 1; } @Override public void onBindViewHolder(SingleViewHolder holder, int position) { - ((RecyclerView)holder.itemView).setAdapter(new UnicodeEmojiPageAdapter(Emojis.EMOJIS[position], id, listener)); + if(position == 0) { + recentsView = ((RecyclerView)holder.itemView); + recentsView.setAdapter(new UnicodeEmojiPageAdapter(recents, id, listener)); + } else { + ((RecyclerView)holder.itemView).setAdapter( + new UnicodeEmojiPageAdapter(Arrays.asList(Emojis.EMOJIS[position - 1]), id, listener)); + } } @Override @@ -56,26 +69,29 @@ public class UnicodeEmojiAdapter ((RecyclerView)view).setLayoutManager(new GridLayoutManager(view.getContext(), rows)); return holder; } - - private class UnicodeEmojiPageAdapter extends RecyclerView.Adapter { - private final String[] emojis; - private final String id; + + @Override + public void onRecentsUpdate(Set set) { + recents = new ArrayList(set); + Collections.reverse(recents); + if(recentsView != null) + recentsView.getAdapter().notifyDataSetChanged(); + } + + private abstract class UnicodeEmojiBasePageAdapter extends RecyclerView.Adapter { private final EmojiKeyboard.OnEmojiSelectedListener listener; + private final String id; - public UnicodeEmojiPageAdapter(String[] emojis, String id, EmojiKeyboard.OnEmojiSelectedListener listener) { - this.emojis = emojis; + public UnicodeEmojiBasePageAdapter(String id, EmojiKeyboard.OnEmojiSelectedListener listener) { this.id = id; this.listener = listener; } - @Override - public int getItemCount() { - return emojis.length; - } + abstract public String getEmoji(int position); @Override public void onBindViewHolder(SingleViewHolder holder, int position) { - String emoji = emojis[position]; + String emoji = getEmoji(position); EmojiAppCompatButton btn = (EmojiAppCompatButton)holder.itemView; btn.setText(emoji); @@ -90,5 +106,24 @@ public class UnicodeEmojiAdapter } } + private class UnicodeEmojiPageAdapter extends UnicodeEmojiBasePageAdapter { + private final List emojis; + + public UnicodeEmojiPageAdapter(List emojis, String id, EmojiKeyboard.OnEmojiSelectedListener listener) { + super(id, listener); + this.emojis = emojis; + } + + @Override + public int getItemCount() { + return emojis.size(); + } + + @Override + public String getEmoji(int position) { + return emojis.get(position); + } + } + } diff --git a/app/src/main/java/com/keylesspalace/tusky/view/EmojiKeyboard.java b/app/src/main/java/com/keylesspalace/tusky/view/EmojiKeyboard.java index 45a1209d..afe3c8b5 100644 --- a/app/src/main/java/com/keylesspalace/tusky/view/EmojiKeyboard.java +++ b/app/src/main/java/com/keylesspalace/tusky/view/EmojiKeyboard.java @@ -9,13 +9,22 @@ import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayoutMediator; import androidx.viewpager2.widget.ViewPager2; import androidx.recyclerview.widget.RecyclerView; +import androidx.preference.PreferenceManager; import com.keylesspalace.tusky.R; import com.keylesspalace.tusky.adapter.UnicodeEmojiAdapter; +import java.util.*; public class EmojiKeyboard extends LinearLayout { private TabLayout tabs; private ViewPager2 pager; private TabLayoutMediator currentMediator; + private String preferenceKey; + private SharedPreferences pref; + private Set recents; + private boolean isSticky = false; // TODO + private String RECENTS_DELIM = "; "; + private int MAX_RECENTS_ITEMS = 50; + private RecyclerView.Adapter adapter; public EmojiKeyboard(Context context) { super(context); @@ -31,10 +40,11 @@ public class EmojiKeyboard extends LinearLayout { super(context, attrs, defStyleAttr); init(context); } - + void init(Context context) { inflate(context, R.layout.item_emoji_picker, this); + pref = PreferenceManager.getDefaultSharedPreferences(context); tabs = findViewById(R.id.picker_tabs); pager = findViewById(R.id.picker_pager); } @@ -44,34 +54,67 @@ public class EmojiKeyboard extends LinearLayout { public static final int STICKER_MODE = 2; void setupKeyboard(String id, int mode, OnEmojiSelectedListener listener) { - RecyclerView.Adapter adapter; - switch(mode) { - case CUSTOM_MODE: - // UNDONE - //break; + case CUSTOM_MODE: + preferenceKey = "CUSTOM_RECENTS"; + break; case STICKER_MODE: - // UNDONE - //break; + preferenceKey = "STICKER_RECENTS"; + break; default: case UNICODE_MODE: + preferenceKey = "UNICODE_RECENTS"; adapter = new UnicodeEmojiAdapter(id, listener); - break; + break; } + List list = Arrays.asList(pref.getString(preferenceKey, "").split(RECENTS_DELIM)); + recents = new LinkedHashSet(list); + ((EmojiKeyboardAdapter)adapter).onRecentsUpdate(recents); + pager.setAdapter(adapter); if(currentMediator != null) - currentMediator.detach(); + currentMediator.detach(); currentMediator = new TabLayoutMediator(tabs, pager, (TabLayoutMediator.TabConfigurationStrategy)adapter); currentMediator.attach(); } + void appendToRecents(String id) { + recents.remove(id); + recents.add(id); + int size = recents.size(); + String joined; + final SharedPreferences.Editor editor = pref.edit(); + if(size > MAX_RECENTS_ITEMS) { + List list = new ArrayList(recents); + list = list.subList(size - MAX_RECENTS_ITEMS, size); + joined = String.join(RECENTS_DELIM, list); + if(isSticky) { + recents = new LinkedHashSet(list); + } + } else { + joined = String.join(RECENTS_DELIM, recents); + } + + editor.putString(preferenceKey, joined); + editor.apply(); + + // no point on updating view if we are will be closed + if(isSticky) { + ((EmojiKeyboardAdapter)adapter).onRecentsUpdate(recents); + } + } + public interface OnEmojiSelectedListener { void onEmojiSelected(String id, String emoji); } + public interface EmojiKeyboardAdapter { + void onRecentsUpdate(Set set); + } + public static void show(Context ctx, String id, int mode, OnEmojiSelectedListener listener) { final Dialog dialog = new Dialog(ctx); @@ -81,7 +124,9 @@ public class EmojiKeyboard extends LinearLayout { EmojiKeyboard kbd = (EmojiKeyboard)dialog.findViewById(R.id.dialog_emoji_keyboard); kbd.setupKeyboard(id, mode, (_id, _emoji) -> { listener.onEmojiSelected(_id, _emoji); - dialog.dismiss(); + kbd.appendToRecents(_emoji); + if(!kbd.isSticky) + dialog.dismiss(); }); dialog.show();