diff options
author | Thomas <tschneider.ac@gmail.com> | 2023-12-22 17:55:28 +0100 |
---|---|---|
committer | Thomas <tschneider.ac@gmail.com> | 2023-12-22 17:55:28 +0100 |
commit | f7714fa73899903f5f5a0ccbe917ebdae35108e0 (patch) | |
tree | fc897ddd6a034583bd1241295f734fca2a8ed27c | |
parent | fadf3fb78892bc6918de7d74b123bb10cd9d8236 (diff) |
Fix issue #894 - Add a search bar for custom emojis
3 files changed, 127 insertions, 15 deletions
diff --git a/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/EmojiInstance.java b/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/EmojiInstance.java index 5cc9b4076..ce672178f 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/EmojiInstance.java +++ b/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/EmojiInstance.java @@ -14,12 +14,17 @@ package app.fedilab.android.mastodon.client.entities.api; * You should have received a copy of the GNU General Public License along with Fedilab; if not, * see <http://www.gnu.org/licenses>. */ +import static app.fedilab.android.BaseMainActivity.emojis; + import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteBlobTooBigException; import android.database.sqlite.SQLiteDatabase; +import android.os.Handler; +import android.os.Looper; +import androidx.annotation.NonNull; import androidx.lifecycle.ViewModelProvider; import com.google.gson.Gson; @@ -225,6 +230,61 @@ public class EmojiInstance implements Serializable { } } + public interface EmojiFilteredCallBack{ + void get(List<Emoji> emojiList); + } + + /** + * Returns the emojis for an instance + * + * @param instance String + * @param filter String + * @param callBack EmojiFilteredCallBack - Get filtered emojis + * + * @return List<Emoji> - List of {@link Emoji} + */ + public void getEmojiListFiltered(@NonNull String instance, @NonNull String filter, EmojiFilteredCallBack callBack) throws DBException { + if (db == null) { + throw new DBException("db is null. Wrong initialization."); + } + new Thread(() -> { + List<Emoji> emojiArrayList= new ArrayList<>(); + List<Emoji> emojiFiltered= new ArrayList<>(); + if (emojis == null || !emojis.containsKey(BaseMainActivity.currentInstance) || emojis.get(BaseMainActivity.currentInstance) == null) { + try { + Cursor c = db.query(Sqlite.TABLE_EMOJI_INSTANCE, null, Sqlite.COL_INSTANCE + " = '" + instance + "'", null, null, null, null, "1"); + emojiArrayList = cursorToEmojiList(c); + } catch (Exception e) { + MastodonInstanceService mastodonInstanceService = init(instance); + Call<List<Emoji>> emojiCall = mastodonInstanceService.customEmoji(); + if (emojiCall != null) { + try { + Response<List<Emoji>> emojiResponse = emojiCall.execute(); + if (emojiResponse.isSuccessful()) { + emojiArrayList = emojiResponse.body(); + } + } catch (Exception err) { + err.printStackTrace(); + } + } + } + } else { + emojiArrayList = emojis.get(instance); + } + if(emojiArrayList != null && emojiArrayList.size() > 0 ) { + for(Emoji emoji: emojiArrayList) { + if(emoji.shortcode.contains(filter)) { + emojiFiltered.add(emoji); + } + } + } + Handler mainHandler = new Handler(Looper.getMainLooper()); + Runnable myRunnable = () -> callBack.get(emojiFiltered); + mainHandler.post(myRunnable); + }).start(); + + } + /** * Restore emoji list from db * diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/ComposeAdapter.java b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/ComposeAdapter.java index 9620e1bf4..97bd72f23 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/ComposeAdapter.java +++ b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/ComposeAdapter.java @@ -59,6 +59,7 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.AppCompatEditText; import androidx.appcompat.widget.LinearLayoutCompat; +import androidx.appcompat.widget.SearchView; import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityOptionsCompat; import androidx.core.content.ContextCompat; @@ -103,11 +104,13 @@ import app.fedilab.android.activities.MainActivity; import app.fedilab.android.databinding.ComposeAttachmentItemBinding; import app.fedilab.android.databinding.ComposePollBinding; import app.fedilab.android.databinding.ComposePollItemBinding; +import app.fedilab.android.databinding.CustomEmojiPickerBinding; import app.fedilab.android.databinding.DrawerMediaListBinding; import app.fedilab.android.databinding.DrawerStatusComposeBinding; import app.fedilab.android.databinding.DrawerStatusSimpleBinding; import app.fedilab.android.mastodon.activities.ComposeActivity; import app.fedilab.android.mastodon.activities.MediaActivity; +import app.fedilab.android.mastodon.activities.SearchResultTabActivity; import app.fedilab.android.mastodon.client.entities.api.Account; import app.fedilab.android.mastodon.client.entities.api.Attachment; import app.fedilab.android.mastodon.client.entities.api.Emoji; @@ -2119,29 +2122,57 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder * @param holder - view for the message {@link ComposeViewHolder} */ private void displayEmojiPicker(ComposeViewHolder holder, String instance) throws DBException { - final AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context); - int paddingPixel = 15; - float density = context.getResources().getDisplayMetrics().density; - int paddingDp = (int) (paddingPixel * density); builder.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); builder.setTitle(R.string.insert_emoji); + CustomEmojiPickerBinding customEmojiPickerBinding = CustomEmojiPickerBinding.inflate(LayoutInflater.from(context), new LinearLayout(context), false); if (emojis != null && emojis.size() > 0) { - GridView gridView = new GridView(context); - gridView.setAdapter(new EmojiAdapter(emojis.get(instance))); - gridView.setNumColumns(5); - gridView.setOnItemClickListener((parent, view, position, id) -> { + customEmojiPickerBinding.gridview.setAdapter(new EmojiAdapter(emojis.get(instance))); + customEmojiPickerBinding.gridview.setOnItemClickListener((parent, view, position, id) -> { holder.binding.content.getText().insert(holder.binding.content.getSelectionStart(), " :" + Objects.requireNonNull(emojis.get(instance)).get(position).shortcode + ": "); alertDialogEmoji.dismiss(); }); - gridView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp); - builder.setView(gridView); - } else { - TextView textView = new TextView(context); - textView.setText(context.getString(R.string.no_emoji)); - textView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp); - builder.setView(textView); } + customEmojiPickerBinding.toolbarSearch.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + InputMethodManager imm = (InputMethodManager) context.getSystemService(INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(customEmojiPickerBinding.toolbarSearch.getWindowToken(), 0); + try { + new EmojiInstance(context).getEmojiListFiltered(instance, query.trim(), emojiList -> { + if (emojiList != null && emojiList.size() > 0) { + customEmojiPickerBinding.gridview.setAdapter(new EmojiAdapter(emojiList)); + customEmojiPickerBinding.gridview.setOnItemClickListener((parent, view, position, id) -> { + holder.binding.content.getText().insert(holder.binding.content.getSelectionStart(), " :" + emojiList.get(position).shortcode + ": "); + alertDialogEmoji.dismiss(); + }); + } + }); + } catch (DBException e) { + throw new RuntimeException(e); + } + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + try { + new EmojiInstance(context).getEmojiListFiltered(instance, newText.trim(), emojiList -> { + if (emojiList != null && emojiList.size() > 0) { + customEmojiPickerBinding.gridview.setAdapter(new EmojiAdapter(emojiList)); + customEmojiPickerBinding.gridview.setOnItemClickListener((parent, view, position, id) -> { + holder.binding.content.getText().insert(holder.binding.content.getSelectionStart(), " :" + emojiList.get(position).shortcode + ": "); + alertDialogEmoji.dismiss(); + }); + } + }); + } catch (DBException e) { + throw new RuntimeException(e); + } + return false; + } + }); + builder.setView(customEmojiPickerBinding.getRoot()); alertDialogEmoji = builder.show(); } diff --git a/app/src/main/res/layouts/mastodon/layout/custom_emoji_picker.xml b/app/src/main/res/layouts/mastodon/layout/custom_emoji_picker.xml new file mode 100644 index 000000000..46d565c30 --- /dev/null +++ b/app/src/main/res/layouts/mastodon/layout/custom_emoji_picker.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:padding="15dp" + android:orientation="vertical"> + <androidx.appcompat.widget.SearchView + android:id="@+id/toolbar_search" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:iconifiedByDefault="false" + android:layout_gravity="center_vertical" + android:gravity="center" /> + <GridView + android:id="@+id/gridview" + android:layout_width="match_parent" + android:numColumns="5" + android:layout_height="0dp" + android:layout_weight="1"/> +</androidx.appcompat.widget.LinearLayoutCompat>
\ No newline at end of file |