diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java index 0f80c42db..2798d7406 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java @@ -45,6 +45,7 @@ import android.text.Editable; import android.text.Html; import android.text.InputFilter; import android.text.InputType; +import android.text.SpannableString; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.Menu; @@ -105,6 +106,7 @@ import java.util.regex.Pattern; import cz.msebera.android.httpclient.Header; import fr.gouv.etalab.mastodon.asynctasks.PostStatusAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.RetrieveAccountsForReplyAsyncTask; +import fr.gouv.etalab.mastodon.asynctasks.RetrieveEmojiAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.RetrieveSearchAccountsAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.RetrieveSearchAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.UpdateDescriptionAttachmentAsyncTask; @@ -112,11 +114,14 @@ import fr.gouv.etalab.mastodon.client.API; import fr.gouv.etalab.mastodon.client.APIResponse; import fr.gouv.etalab.mastodon.client.Entities.Account; import fr.gouv.etalab.mastodon.client.Entities.Attachment; +import fr.gouv.etalab.mastodon.client.Entities.Emojis; import fr.gouv.etalab.mastodon.client.Entities.Error; import fr.gouv.etalab.mastodon.client.Entities.Mention; import fr.gouv.etalab.mastodon.client.Entities.Results; import fr.gouv.etalab.mastodon.client.Entities.Status; import fr.gouv.etalab.mastodon.client.Entities.StoredStatus; +import fr.gouv.etalab.mastodon.drawers.EmojisSearchAdapter; +import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiInterface; import fr.gouv.etalab.mastodon.translation.Translate; import fr.gouv.etalab.mastodon.client.Entities.Version; import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader; @@ -146,7 +151,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor; * Toot activity class */ -public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAccountshInterface, OnRetrieveAttachmentInterface, OnPostStatusActionInterface, OnRetrieveSearchInterface, OnRetrieveAccountsReplyInterface, OnTranslatedInterface { +public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAccountshInterface, OnRetrieveAttachmentInterface, OnPostStatusActionInterface, OnRetrieveSearchInterface, OnRetrieveAccountsReplyInterface, OnTranslatedInterface, OnRetrieveEmojiInterface { private String visibility; @@ -553,6 +558,9 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc String patternTag = "^(.|\\s)*(#([\\w-]{2,}))$"; final Pattern tPattern = Pattern.compile(patternTag); + String patternEmoji = "^(.|\\s)*(:([\\w_]{1,}))$"; + final Pattern ePattern = Pattern.compile(patternEmoji); + toot_cw_content.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @@ -614,7 +622,22 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc pp_actionBar.setVisibility(View.GONE); } new RetrieveSearchAsyncTask(getApplicationContext(),search,TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - }else{toot_content.dismissDropDown();} + }else{ + if( s.toString().charAt(0) == ':') + mt = ePattern.matcher(s.toString().substring(currentCursorPosition- searchLength, currentCursorPosition)); + else + mt = ePattern.matcher(s.toString().substring(currentCursorPosition- (searchLength-1), currentCursorPosition)); + if(mt.matches()) { + String shortcode = mt.group(3); + if (pp_progress != null && pp_actionBar != null) { + pp_progress.setVisibility(View.VISIBLE); + pp_actionBar.setVisibility(View.GONE); + } + new RetrieveEmojiAsyncTask(getApplicationContext(),shortcode,TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }else { + toot_content.dismissDropDown(); + } + } } @@ -1394,6 +1417,22 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc } } + @Override + public void onRetrieveEmoji(int position, SpannableString spannableString, Boolean error) { + + } + + @Override + public void onRetrieveSearchEmoji(List emojis) { + if( pp_progress != null && pp_actionBar != null) { + pp_progress.setVisibility(View.GONE); + pp_actionBar.setVisibility(View.VISIBLE); + } + if( emojis != null && emojis.size() > 0){ + EmojisSearchAdapter tagsSearchAdapter = new EmojisSearchAdapter(TootActivity.this, emojis); + } + } + @Override public void onRetrieveSearch(Results results, Error error) { if( pp_progress != null && pp_actionBar != null) { @@ -1745,4 +1784,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc } } + + } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveEmojiAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveEmojiAsyncTask.java new file mode 100644 index 000000000..ca536b594 --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveEmojiAsyncTask.java @@ -0,0 +1,61 @@ +/* Copyright 2017 Thomas Schneider + * + * This file is a part of Mastalab + * + * 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. + * + * Mastalab 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 Mastalab; if not, + * see . */ +package fr.gouv.etalab.mastodon.asynctasks; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.os.AsyncTask; + +import java.lang.ref.WeakReference; +import java.util.List; + +import fr.gouv.etalab.mastodon.client.Entities.Emojis; +import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiInterface; +import fr.gouv.etalab.mastodon.sqlite.CustomEmojiDAO; +import fr.gouv.etalab.mastodon.sqlite.Sqlite; + + +/** + * Created by Thomas on 01/11/2017. + * Retrieves emojis + */ + +public class RetrieveEmojiAsyncTask extends AsyncTask { + + private String shortcode; + private List emojis; + private OnRetrieveEmojiInterface listener; + private WeakReference contextReference; + + public RetrieveEmojiAsyncTask(Context context, String shortcode, OnRetrieveEmojiInterface onRetrieveEmojiInterface){ + this.contextReference = new WeakReference<>(context); + this.shortcode = shortcode; + this.listener = onRetrieveEmojiInterface; + } + + + @Override + protected Void doInBackground(Void... params) { + SQLiteDatabase db = Sqlite.getInstance(contextReference.get(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + emojis = new CustomEmojiDAO(contextReference.get(), db).getEmojiStartingBy(shortcode); + return null; + } + + @Override + protected void onPostExecute(Void result) { + listener.onRetrieveSearchEmoji(emojis); + } + +} diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/EmojisSearchAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/EmojisSearchAdapter.java new file mode 100644 index 000000000..79d738b96 --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/EmojisSearchAdapter.java @@ -0,0 +1,156 @@ +package fr.gouv.etalab.mastodon.drawers; +/* Copyright 2017 Thomas Schneider + * + * This file is a part of Mastalab + * + * 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. + * + * Mastalab 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 Mastalab; if not, + * see . */ + + +import android.content.Context; +import android.support.annotation.NonNull; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.Filter; +import android.widget.Filterable; +import android.widget.ImageView; +import android.widget.TextView; + +import com.nostra13.universalimageloader.core.DisplayImageOptions; +import com.nostra13.universalimageloader.core.ImageLoader; +import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer; + +import java.util.ArrayList; +import java.util.List; + +import fr.gouv.etalab.mastodon.client.Entities.Emojis; +import mastodon.etalab.gouv.fr.mastodon.R; + + +/** + * Created by Thomas on 01/11/2017. + * Adapter for emojis when searching + */ +public class EmojisSearchAdapter extends ArrayAdapter implements Filterable { + + private List emojis, tempEmojis, suggestions ; + private LayoutInflater layoutInflater; + private ImageLoader imageLoader; + private DisplayImageOptions options; + private Context context; + + public EmojisSearchAdapter(Context context, List emojis){ + super(context, android.R.layout.simple_list_item_1, emojis); + this.emojis = emojis; + this.context = context; + this.tempEmojis = new ArrayList<>(emojis); + this.suggestions = new ArrayList<>(emojis); + layoutInflater = LayoutInflater.from(context); + imageLoader = ImageLoader.getInstance(); + options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false) + .cacheOnDisk(true).resetViewBeforeLoading(true).build(); + } + + + @Override + public int getCount() { + return emojis.size(); + } + + @Override + public Emojis getItem(int position) { + return emojis.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + + @NonNull + @Override + public View getView(final int position, View convertView, @NonNull ViewGroup parent) { + + final Emojis emoji = emojis.get(position); + final ViewHolder holder; + if (convertView == null) { + convertView = layoutInflater.inflate(R.layout.drawer_emoji_search, parent, false); + holder = new ViewHolder(); + holder.emoji_icon = convertView.findViewById(R.id.emoji_icon); + holder.emoji_shortcode = convertView.findViewById(R.id.emoji_shortcode); + convertView.setTag(holder); + } else { + holder = (ViewHolder) convertView.getTag(); + } + + holder.emoji_shortcode.setText(String.format("%s", emoji.getShortcode())); + //Profile picture + imageLoader.displayImage(emoji.getUrl(), holder.emoji_icon, options); + + return convertView; + } + + @NonNull + @Override + public Filter getFilter() { + return emojiFilter; + } + + + private Filter emojiFilter = new Filter() { + @Override + public CharSequence convertResultToString(Object resultValue) { + Emojis emoji = (Emojis) resultValue; + return emoji.getShortcode(); + } + + @Override + protected FilterResults performFiltering(CharSequence constraint) { + if (constraint != null) { + suggestions.clear(); + for (Emojis emoji : tempEmojis) { + suggestions.add(emoji); + } + FilterResults filterResults = new FilterResults(); + filterResults.values = suggestions; + filterResults.count = suggestions.size(); + return filterResults; + } else { + return new FilterResults(); + } + } + + @Override + protected void publishResults(CharSequence constraint, FilterResults results) { + ArrayList c = (ArrayList) results.values; + if (results.count > 0) { + clear(); + for (Emojis cust : c) { + add(cust); + notifyDataSetChanged(); + } + } else{ + clear(); + notifyDataSetChanged(); + } + } + }; + + private class ViewHolder { + ImageView emoji_icon; + TextView emoji_shortcode; + } + + +} \ No newline at end of file diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/NotificationsListAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/NotificationsListAdapter.java index f58c1084a..519226444 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/NotificationsListAdapter.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/NotificationsListAdapter.java @@ -67,6 +67,7 @@ import fr.gouv.etalab.mastodon.asynctasks.RetrieveFeedsAsyncTask; import fr.gouv.etalab.mastodon.client.API; import fr.gouv.etalab.mastodon.client.APIResponse; import fr.gouv.etalab.mastodon.client.Entities.Attachment; +import fr.gouv.etalab.mastodon.client.Entities.Emojis; import fr.gouv.etalab.mastodon.client.Entities.Error; import fr.gouv.etalab.mastodon.helper.CrossActions; import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface; @@ -894,6 +895,11 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On } } + @Override + public void onRetrieveSearchEmoji(List emojis) { + + } + class ViewHolder extends RecyclerView.ViewHolder { diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java index 3cb1338b5..730d3587b 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java @@ -81,6 +81,7 @@ import fr.gouv.etalab.mastodon.asynctasks.RetrieveRepliesAsyncTask; import fr.gouv.etalab.mastodon.client.API; import fr.gouv.etalab.mastodon.client.APIResponse; import fr.gouv.etalab.mastodon.client.Entities.Attachment; +import fr.gouv.etalab.mastodon.client.Entities.Emojis; import fr.gouv.etalab.mastodon.client.Entities.Error; import fr.gouv.etalab.mastodon.client.Entities.Status; import fr.gouv.etalab.mastodon.translation.Translate; @@ -1364,6 +1365,11 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct } } + @Override + public void onRetrieveSearchEmoji(List emojis) { + + } + @Override public void onTranslatedTextview(Translate translate, Status status, String translatedResult, Boolean error) { if( error){ diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveEmojiInterface.java b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveEmojiInterface.java index 5bc39ba7c..fda492252 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveEmojiInterface.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveEmojiInterface.java @@ -16,6 +16,10 @@ package fr.gouv.etalab.mastodon.interfaces; import android.text.SpannableString; +import java.util.List; + +import fr.gouv.etalab.mastodon.client.Entities.Emojis; + /** * Created by Thomas on 19/10/2017. @@ -23,4 +27,5 @@ import android.text.SpannableString; */ public interface OnRetrieveEmojiInterface { void onRetrieveEmoji(int position, SpannableString spannableString, Boolean error); + void onRetrieveSearchEmoji(List emojis); } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/CustomEmojiDAO.java b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/CustomEmojiDAO.java index 1d186dd65..756794ce1 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/CustomEmojiDAO.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/CustomEmojiDAO.java @@ -127,6 +127,20 @@ public class CustomEmojiDAO { } + /** + * Returns an emoji by its shortcode in db + * @return emoji Emojis + */ + public List getEmojiStartingBy(String shortCode){ + try { + String instance = Helper.getLiveInstance(context); + Cursor c = db.query(Sqlite.TABLE_CUSTOM_EMOJI, null, Sqlite.COL_SHORTCODE + " LIKE \"%" + shortCode + "%\" AND " + Sqlite.COL_INSTANCE + " = \"" + instance+ "\"", null, null, null, null, null); + return cursorToListEmojis(c); + } catch (Exception e) { + return null; + } + } + /*** * Method to hydrate emoji from database * @param c Cursor diff --git a/app/src/main/res/layout/drawer_emoji_search.xml b/app/src/main/res/layout/drawer_emoji_search.xml new file mode 100644 index 000000000..e9ee582dc --- /dev/null +++ b/app/src/main/res/layout/drawer_emoji_search.xml @@ -0,0 +1,42 @@ + + + + + + \ No newline at end of file