diff --git a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java index 04b94eb8e..c72c63861 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java +++ b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java @@ -39,6 +39,9 @@ public class GlobalUserPreferences{ private final static Type recentLanguagesType = new TypeToken>>() {}.getType(); public static Map> recentLanguages; + private final static Type recentEmojisType = new TypeToken>() {}.getType(); + public static Map recentEmojis; + private static SharedPreferences getPrefs(){ return MastodonApp.context.getSharedPreferences("global", Context.MODE_PRIVATE); } @@ -68,6 +71,7 @@ public class GlobalUserPreferences{ enableDeleteNotifications=prefs.getBoolean("enableDeleteNotifications", true); theme=ThemePreference.values()[prefs.getInt("theme", 0)]; recentLanguages=fromJson(prefs.getString("recentLanguages", "{}"), recentLanguagesType, new HashMap<>()); + recentEmojis=fromJson(prefs.getString("recentEmojis", "{}"), recentEmojisType, new HashMap<>()); publishButtonText=prefs.getString("publishButtonText", ""); try { @@ -104,6 +108,7 @@ public class GlobalUserPreferences{ .putInt("theme", theme.ordinal()) .putString("color", color.name()) .putString("recentLanguages", gson.toJson(recentLanguages)) + .putString("recentEmojis", gson.toJson(recentEmojis)) .apply(); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java index 92dbca76c..d64d291f5 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java @@ -273,6 +273,10 @@ public class SettingsFragment extends MastodonToolbarFragment{ GlobalUserPreferences.recentLanguages.remove(accountID); GlobalUserPreferences.save(); }))); + items.add(new TextItem(R.string.sk_clear_recent_emoji, ()-> { + GlobalUserPreferences.recentEmojis.clear(); + GlobalUserPreferences.save(); + })); // items.add(new TextItem(R.string.log_out, this::confirmLogOut)); items.add(new FooterItem(getString(R.string.sk_settings_app_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE))); diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/CustomEmojiPopupKeyboard.java b/mastodon/src/main/java/org/joinmastodon/android/ui/CustomEmojiPopupKeyboard.java index 995a1c924..ad469ea87 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/CustomEmojiPopupKeyboard.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/CustomEmojiPopupKeyboard.java @@ -1,8 +1,9 @@ package org.joinmastodon.android.ui; +import static org.joinmastodon.android.GlobalUserPreferences.recentEmojis; + import android.annotation.SuppressLint; import android.app.Activity; -import android.content.res.TypedArray; import android.graphics.Rect; import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; @@ -12,8 +13,13 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + import com.squareup.otto.Subscribe; +import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.R; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.events.EmojiUpdatedEvent; @@ -21,13 +27,13 @@ import org.joinmastodon.android.model.Emoji; import org.joinmastodon.android.model.EmojiCategory; import org.joinmastodon.android.ui.utils.UiUtils; +import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.Optional; import java.util.function.Consumer; import java.util.stream.Collectors; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.RecyclerView; import me.grishka.appkit.imageloader.ImageLoaderRecyclerAdapter; import me.grishka.appkit.imageloader.ImageLoaderViewHolder; import me.grishka.appkit.imageloader.ListImageLoaderWrapper; @@ -40,6 +46,9 @@ import me.grishka.appkit.utils.V; import me.grishka.appkit.views.UsableRecyclerView; public class CustomEmojiPopupKeyboard extends PopupKeyboard{ + //determines how many emoji need to be clicked, before it disappears from the recent emojis + private static final int NEW_RECENT_VALUE=15; + private List emojis; private UsableRecyclerView list; private ListImageLoaderWrapper imgLoader; @@ -82,6 +91,17 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard{ list.setLayoutManager(lm); imgLoader=new ListImageLoaderWrapper(activity, list, new RecyclerViewDelegate(list), null); + // inject category with last used emojis + if (!recentEmojis.isEmpty()) { + List allAvailableEmojis = emojis.stream().flatMap(category -> category.emojis.stream()).collect(Collectors.toList()); + List recentEmojiList = new ArrayList<>(); + for (String emojiCode : recentEmojis.keySet().stream().sorted(Comparator.comparingInt(GlobalUserPreferences.recentEmojis::get).reversed()).collect(Collectors.toList())) { + Optional element = allAvailableEmojis.stream().filter(e -> e.shortcode.equals(emojiCode)).findFirst(); + element.ifPresent(recentEmojiList::add); + } + emojis.add(0, new EmojiCategory(activity.getString(R.string.sk_emoji_recent), recentEmojiList)); + } + for(EmojiCategory category:emojis) adapter.addAdapter(new SingleCategoryAdapter(category)); list.setAdapter(adapter); @@ -100,6 +120,11 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard{ list.setBackgroundColor(UiUtils.getThemeColor(activity, android.R.attr.colorBackground)); list.setSelector(null); + //remove recently used afterwards, it would get duplicated otherwise + if (!recentEmojis.isEmpty()) { + emojis.remove(0); + } + return list; } @@ -107,6 +132,19 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard{ this.listener=listener; } + private void increaseEmojiCount(Emoji emoji) { + Integer usageCount = recentEmojis.get(emoji.shortcode); + if (usageCount != null) { + recentEmojis.put(emoji.shortcode, usageCount + 1); + } else { + recentEmojis.put(emoji.shortcode, NEW_RECENT_VALUE); + } + + recentEmojis.entrySet().removeIf(e -> e.getValue() <= 0); + recentEmojis.replaceAll((k, v) -> v - 1); + GlobalUserPreferences.save(); + } + @SuppressLint("NotifyDataSetChanged") @Subscribe public void onEmojiUpdated(EmojiUpdatedEvent ev){ @@ -203,6 +241,7 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard{ @Override public void onClick(){ + increaseEmojiCount(item); listener.accept(item); } } diff --git a/mastodon/src/main/res/values/strings_sk.xml b/mastodon/src/main/res/values/strings_sk.xml index fefd28928..5a213ef14 100644 --- a/mastodon/src/main/res/values/strings_sk.xml +++ b/mastodon/src/main/res/values/strings_sk.xml @@ -133,4 +133,6 @@ This is a bot account No Image description The included images have no description. Please consider adding one, to allow visually impaired people to participate. + Recently used + Clear recently used emoji \ No newline at end of file