Emojis support
This commit is contained in:
parent
a22d61c63d
commit
f36ddba6f9
|
@ -1502,18 +1502,23 @@ public class API {
|
|||
|
||||
//Retrieves emjis
|
||||
List<Emojis> emojiList = new ArrayList<>();
|
||||
JSONArray emojisTag = resobj.getJSONArray("emojis");
|
||||
if( arrayTag != null){
|
||||
for(int j = 0 ; j < emojisTag.length() ; j++){
|
||||
JSONObject emojisObj = emojisTag.getJSONObject(j);
|
||||
Emojis emojis = new Emojis();
|
||||
emojis.setShortcode(emojisObj.get("shortcode").toString());
|
||||
emojis.setStatic_url(emojisObj.get("static_url").toString());
|
||||
emojis.setUrl(emojisObj.get("url").toString());
|
||||
emojiList.add(emojis);
|
||||
try {
|
||||
JSONArray emojisTag = resobj.getJSONArray("emojis");
|
||||
if( arrayTag != null){
|
||||
for(int j = 0 ; j < emojisTag.length() ; j++){
|
||||
JSONObject emojisObj = emojisTag.getJSONObject(j);
|
||||
Emojis emojis = new Emojis();
|
||||
emojis.setShortcode(emojisObj.get("shortcode").toString());
|
||||
emojis.setStatic_url(emojisObj.get("static_url").toString());
|
||||
emojis.setUrl(emojisObj.get("url").toString());
|
||||
emojiList.add(emojis);
|
||||
}
|
||||
}
|
||||
status.setEmojis(emojiList);
|
||||
}catch (Exception e){
|
||||
status.setEmojis(new ArrayList<Emojis>());
|
||||
}
|
||||
status.setEmojis(emojiList);
|
||||
|
||||
|
||||
status.setAccount(parseAccountResponse(context, resobj.getJSONObject("account")));
|
||||
status.setContent(resobj.get("content").toString());
|
||||
|
|
|
@ -17,6 +17,8 @@ package fr.gouv.etalab.mastodon.client.Entities;
|
|||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.SpannableString;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
@ -37,6 +39,8 @@ public class Status implements Parcelable {
|
|||
private Status reblog;
|
||||
private String content;
|
||||
private String content_translated;
|
||||
private SpannableString contents;
|
||||
private SpannableString content_translateds;
|
||||
private Date created_at;
|
||||
private int reblogs_count;
|
||||
private int favourites_count;
|
||||
|
@ -56,6 +60,7 @@ public class Status implements Parcelable {
|
|||
private Application application;
|
||||
private String language;
|
||||
private boolean isTranslated = false;
|
||||
private boolean isEmojiFound = false;
|
||||
private boolean isTranslationShown = false;
|
||||
private boolean isNew = false;
|
||||
private boolean isTakingScreenShot = false;
|
||||
|
@ -388,4 +393,28 @@ public class Status implements Parcelable {
|
|||
public void setEmojis(List<Emojis> emojis) {
|
||||
this.emojis = emojis;
|
||||
}
|
||||
|
||||
public SpannableString getContents() {
|
||||
return contents;
|
||||
}
|
||||
|
||||
public void setContents(SpannableString contents) {
|
||||
this.contents = contents;
|
||||
}
|
||||
|
||||
public SpannableString getContent_translateds() {
|
||||
return content_translateds;
|
||||
}
|
||||
|
||||
public void setContent_translateds(SpannableString content_translateds) {
|
||||
this.content_translateds = content_translateds;
|
||||
}
|
||||
|
||||
public boolean isEmojiFound() {
|
||||
return isEmojiFound;
|
||||
}
|
||||
|
||||
public void setEmojiFound(boolean emojiFound) {
|
||||
isEmojiFound = emojiFound;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ import fr.gouv.etalab.mastodon.client.Entities.Error;
|
|||
import fr.gouv.etalab.mastodon.helper.CrossActions;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnPostNotificationsActionInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiInterface;
|
||||
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
|
@ -84,7 +85,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
|
|||
* Created by Thomas on 24/04/2017.
|
||||
* Adapter for Status
|
||||
*/
|
||||
public class NotificationsListAdapter extends BaseAdapter implements OnPostActionInterface, OnPostNotificationsActionInterface {
|
||||
public class NotificationsListAdapter extends BaseAdapter implements OnPostActionInterface, OnPostNotificationsActionInterface, OnRetrieveEmojiInterface {
|
||||
|
||||
private Context context;
|
||||
private List<Notification> notifications;
|
||||
|
@ -295,8 +296,12 @@ public class NotificationsListAdapter extends BaseAdapter implements OnPostActio
|
|||
content = content.substring(0, content.length() - 10);
|
||||
}
|
||||
|
||||
SpannableString spannableString = Helper.clickableElements(context, content,
|
||||
status.getReblog() != null?status.getReblog().getMentions():status.getMentions(), status.getEmojis(), true);
|
||||
SpannableString spannableString = Helper.clickableElements(context, status.getContent(),
|
||||
status.getReblog() != null?status.getReblog().getMentions():status.getMentions(),
|
||||
status.getReblog() != null?status.getReblog().getEmojis():status.getEmojis(),
|
||||
position,
|
||||
true, NotificationsListAdapter.this);
|
||||
|
||||
Typeface tf = Typeface.createFromAsset(context.getAssets(), "fonts/DroidSans-Regular.ttf");
|
||||
holder.notification_status_content.setTypeface(tf);
|
||||
holder.notification_status_content.setText(spannableString, TextView.BufferType.SPANNABLE);
|
||||
|
@ -908,6 +913,15 @@ public class NotificationsListAdapter extends BaseAdapter implements OnPostActio
|
|||
holder.status_show_more.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveEmoji(int position, SpannableString spannableString, Boolean error) {
|
||||
notifications.get(position).getStatus().setContents(spannableString);
|
||||
if( !notifications.get(position).getStatus().isEmojiFound()) {
|
||||
notifications.get(position).getStatus().setEmojiFound(true);
|
||||
notificationsListAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class ViewHolder {
|
||||
CardView card_status_container;
|
||||
|
|
|
@ -15,7 +15,6 @@ package fr.gouv.etalab.mastodon.drawers;
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Handler;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
|
@ -39,11 +38,8 @@ import android.text.Html;
|
|||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextPaint;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.util.Log;
|
||||
import android.util.Patterns;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -83,7 +79,6 @@ import java.util.Map;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import fr.gouv.etalab.mastodon.activities.HashTagActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.MediaActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.ShowAccountActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.ShowConversationActivity;
|
||||
|
@ -93,12 +88,14 @@ 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.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
|
||||
import fr.gouv.etalab.mastodon.helper.CrossActions;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnTranslatedInterface;
|
||||
import fr.gouv.etalab.mastodon.translation.GoogleTranslateQuery;
|
||||
|
@ -114,7 +111,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
|
|||
* Created by Thomas on 24/04/2017.
|
||||
* Adapter for Status
|
||||
*/
|
||||
public class StatusListAdapter extends BaseAdapter implements OnPostActionInterface, OnTranslatedInterface, OnRetrieveFeedsInterface {
|
||||
public class StatusListAdapter extends BaseAdapter implements OnPostActionInterface, OnTranslatedInterface, OnRetrieveFeedsInterface, OnRetrieveEmojiInterface {
|
||||
|
||||
private Context context;
|
||||
private List<Status> statuses;
|
||||
|
@ -444,8 +441,11 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
|
||||
if( status.getContent_translated() != null && status.getContent_translated().length() > 0){
|
||||
holder.status_content_translated.setMovementMethod(null);
|
||||
SpannableString spannableStringTrans = Helper.clickableElements(context, status.getContent_translated(),
|
||||
status.getReblog() != null?status.getReblog().getMentions():status.getMentions(), status.getEmojis(), false);
|
||||
SpannableString spannableStringTrans = Helper.clickableElements(context,status.getContent_translated(),
|
||||
status.getReblog() != null?status.getReblog().getMentions():status.getMentions(),
|
||||
status.getReblog() != null?status.getReblog().getEmojis():status.getEmojis(),
|
||||
position,
|
||||
true, StatusListAdapter.this);
|
||||
holder.status_content_translated.setText(spannableStringTrans, TextView.BufferType.SPANNABLE);
|
||||
holder.status_content_translated.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
|
@ -472,8 +472,14 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
content = content.substring(0,content.length() -10);
|
||||
holder.status_content.setMovementMethod(null);
|
||||
final SpannableString spannableString = Helper.clickableElements(context,content,
|
||||
status.getReblog() != null?status.getReblog().getMentions():status.getMentions(), status.getEmojis(), true);
|
||||
status.getReblog() != null?status.getReblog().getMentions():status.getMentions(),
|
||||
status.getReblog() != null?status.getReblog().getEmojis():status.getEmojis(),
|
||||
position,
|
||||
true, StatusListAdapter.this);
|
||||
holder.status_content.setText(spannableString, TextView.BufferType.SPANNABLE);
|
||||
if( status.getContents() != null){
|
||||
holder.status_content.setText(status.getContents(), TextView.BufferType.SPANNABLE);
|
||||
}
|
||||
holder.status_content.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
|
@ -481,6 +487,8 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
return false;
|
||||
}
|
||||
});
|
||||
List<Emojis> emojis = status.getReblog() != null ? status.getReblog().getEmojis() : status.getEmojis();
|
||||
|
||||
holder.status_content.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
|
@ -1317,6 +1325,16 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRetrieveEmoji(int position, SpannableString spannableString, Boolean error) {
|
||||
statuses.get(position).setContents(spannableString);
|
||||
if( !statuses.get(position).isEmojiFound()) {
|
||||
statuses.get(position).setEmojiFound(true);
|
||||
statusListAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTranslatedTextview(int position, String translatedResult, Boolean error) {
|
||||
if( error){
|
||||
|
@ -1408,6 +1426,8 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private class ViewHolder {
|
||||
LinearLayout status_content_container;
|
||||
LinearLayout status_spoiler_container;
|
||||
|
|
|
@ -23,7 +23,6 @@ import android.graphics.PorterDuffXfermode;
|
|||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.app.DownloadManager;
|
||||
import android.app.PendingIntent;
|
||||
|
@ -57,20 +56,20 @@ import android.support.design.widget.NavigationView;
|
|||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.NotificationManagerCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.Html;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextPaint;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.text.style.ImageSpan;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.Patterns;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SubMenu;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.webkit.CookieManager;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
@ -90,7 +89,10 @@ import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
|||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.assist.ImageSize;
|
||||
import com.nostra13.universalimageloader.core.assist.ViewScaleType;
|
||||
import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
|
||||
import com.nostra13.universalimageloader.core.imageaware.NonViewAware;
|
||||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||
|
||||
|
@ -108,7 +110,6 @@ import java.security.MessageDigest;
|
|||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
@ -125,7 +126,6 @@ import fr.gouv.etalab.mastodon.activities.HashTagActivity;
|
|||
import fr.gouv.etalab.mastodon.activities.LoginActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.ShowAccountActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.TootActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.WebviewActivity;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RemoveAccountAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
|
@ -134,8 +134,7 @@ import fr.gouv.etalab.mastodon.client.Entities.Emojis;
|
|||
import fr.gouv.etalab.mastodon.client.Entities.Mention;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
|
||||
import fr.gouv.etalab.mastodon.fragments.DisplayNotificationsFragment;
|
||||
import fr.gouv.etalab.mastodon.fragments.DisplayStatusFragment;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiInterface;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||
|
@ -1125,6 +1124,7 @@ public class Helper {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check if the status contents mentions & tags and fills the content with ClickableSpan
|
||||
* Click on account => ShowAccountActivity
|
||||
|
@ -1134,21 +1134,9 @@ public class Helper {
|
|||
* @param mentions List<Mention>
|
||||
* @return TextView
|
||||
*/
|
||||
public static SpannableString clickableElements(final Context context, String fullContent, List<Mention> mentions, List<Emojis> emojis, boolean useHTML) {
|
||||
SpannableString spannableString;
|
||||
public static SpannableString clickableElements(final Context context, String fullContent, List<Mention> mentions, List<Emojis> emojis, final int position, boolean useHTML, final OnRetrieveEmojiInterface listener) {
|
||||
final SpannableString spannableString;
|
||||
|
||||
|
||||
//Deals with custom emojis to change them in image
|
||||
if( emojis != null && emojis.size() > 0 ) {
|
||||
//Looping through accounts which are mentioned
|
||||
for (final Emojis emoji : emojis) {
|
||||
String targetedEmoji = ":" + emoji + ":";
|
||||
if (fullContent.contains(targetedEmoji)) {
|
||||
fullContent = fullContent.replace(targetedEmoji, "<img src=\""+ emoji.getUrl()+"\" />");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if( useHTML) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
spannableString = new SpannableString(Html.fromHtml(fullContent, Html.FROM_HTML_MODE_LEGACY));
|
||||
|
@ -1193,6 +1181,37 @@ public class Helper {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
if( emoji != null && emojis.size() > 0 ) {
|
||||
for (final Emojis emoji : emojis) {
|
||||
final String targetedEmoji = ":" + emoji.getShortcode() + ":";
|
||||
if (spannableString.toString().contains(targetedEmoji)) {
|
||||
//emojis can be used several times so we have to loop
|
||||
for(int startPosition = -1 ; (startPosition = spannableString.toString().indexOf(targetedEmoji, startPosition + 1)) != -1 ; startPosition++){
|
||||
final int endPosition = startPosition + targetedEmoji.length();
|
||||
final int finalStartPosition = startPosition;
|
||||
ImageLoader imageLoader = ImageLoader.getInstance();
|
||||
NonViewAware imageAware = new NonViewAware(new ImageSize(50, 50), ViewScaleType.CROP);
|
||||
imageLoader.displayImage(emoji.getUrl(), imageAware, new SimpleImageLoadingListener() {
|
||||
@Override
|
||||
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
||||
super.onLoadingComplete(imageUri, view, loadedImage);
|
||||
spannableString.setSpan(
|
||||
new ImageSpan(context,
|
||||
Bitmap.createScaledBitmap(loadedImage, (int)Helper.convertDpToPixel(20, context),
|
||||
(int)Helper.convertDpToPixel(20, context), false)), finalStartPosition,
|
||||
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
listener.onRetrieveEmoji(position, spannableString, false);
|
||||
}
|
||||
@Override
|
||||
public void onLoadingFailed(java.lang.String imageUri, android.view.View view, FailReason failReason) {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Deals with mention to make them clickable
|
||||
if( mentions != null && mentions.size() > 0 ) {
|
||||
//Looping through accounts which are mentioned
|
||||
|
@ -1224,7 +1243,6 @@ public class Helper {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
Matcher matcher = hashtagPattern.matcher(spannableString);
|
||||
while (matcher.find()){
|
||||
int matchStart = matcher.start(1);
|
||||
|
@ -1245,6 +1263,7 @@ public class Helper {
|
|||
}
|
||||
}, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
|
||||
return spannableString;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/* 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 <http://www.gnu.org/licenses>. */
|
||||
package fr.gouv.etalab.mastodon.interfaces;
|
||||
|
||||
import android.text.SpannableString;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 19/10/2017.
|
||||
* Interface when retrieving emojis
|
||||
*/
|
||||
public interface OnRetrieveEmojiInterface {
|
||||
void onRetrieveEmoji(int position, SpannableString spannableString, Boolean error);
|
||||
}
|
Loading…
Reference in New Issue