diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Status.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Status.java
index 6616ed655..2bb6b4fe9 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Status.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Status.java
@@ -15,13 +15,44 @@
package fr.gouv.etalab.mastodon.client.Entities;
+import android.content.*;
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Bitmap;
+import android.os.Build;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.support.annotation.Nullable;
+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.Patterns;
+import android.view.View;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.DataSource;
+import com.bumptech.glide.load.engine.GlideException;
+import com.bumptech.glide.request.RequestListener;
+import com.bumptech.glide.request.target.SimpleTarget;
+import com.bumptech.glide.request.target.Target;
+import com.bumptech.glide.request.transition.Transition;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import java.util.regex.Matcher;
+
+import fr.gouv.etalab.mastodon.activities.HashTagActivity;
+import fr.gouv.etalab.mastodon.activities.ShowAccountActivity;
+import fr.gouv.etalab.mastodon.activities.WebviewActivity;
+import fr.gouv.etalab.mastodon.helper.Helper;
+import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiInterface;
+import fr.gouv.etalab.mastodon.sqlite.Sqlite;
/**
* Created by Thomas on 23/04/2017.
@@ -39,8 +70,6 @@ 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;
@@ -61,10 +90,18 @@ public class Status implements Parcelable {
private String language;
private boolean isTranslated = false;
private boolean isEmojiFound = false;
+ private boolean isClickable = false;
private boolean isTranslationShown = false;
private boolean isNew = false;
private boolean isTakingScreenShot = false;
private boolean isVisible = true;
+ private Status status;
+ private SpannableString contentSpan, contentSpanCW, contentSpanTranslated;
+
+
+ public Status(){
+ this.status = this;
+ }
protected Status(Parcel in) {
id = in.readString();
@@ -93,7 +130,7 @@ public class Status implements Parcelable {
pinned = in.readByte() != 0;
}
- public Status(){}
+
public static final Creator CREATOR = new Creator() {
@Override
@@ -394,21 +431,6 @@ public class Status implements Parcelable {
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;
@@ -417,4 +439,251 @@ public class Status implements Parcelable {
public void setEmojiFound(boolean emojiFound) {
isEmojiFound = emojiFound;
}
+
+
+ public void makeClickable(Context context){
+
+ SpannableString spannableStringContent, spannableStringCW, spannableStringTranslated;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ spannableStringContent = new SpannableString(Html.fromHtml(status.getReblog() != null ?status.getReblog().getContent():status.getContent(), Html.FROM_HTML_MODE_LEGACY));
+ else
+ //noinspection deprecation
+ spannableStringContent = new SpannableString(Html.fromHtml(status.getReblog() != null ?status.getReblog().getContent():status.getContent()));
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ spannableStringCW = new SpannableString(Html.fromHtml(status.getReblog() != null ?status.getReblog().getSpoiler_text():status.getSpoiler_text(), Html.FROM_HTML_MODE_LEGACY));
+ else
+ //noinspection deprecation
+ spannableStringCW = new SpannableString(Html.fromHtml(status.getReblog() != null ?status.getReblog().getSpoiler_text():status.getSpoiler_text()));
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ spannableStringTranslated = new SpannableString(Html.fromHtml(status.getContent_translated(), Html.FROM_HTML_MODE_LEGACY));
+ else
+ //noinspection deprecation
+ spannableStringTranslated = new SpannableString(Html.fromHtml(status.getContent_translated()));
+
+ status.setContentSpan(treatment(context, spannableStringContent));
+ status.setContentSpanCW(treatment(context, spannableStringCW));
+ status.setContentSpanTranslated(treatment(context, spannableStringTranslated));
+ isClickable = true;
+ }
+
+
+ public void makeEmojis(final Context context, final OnRetrieveEmojiInterface listener){
+
+ final SpannableString spannableStringContent, spannableStringCW, spannableStringTranslated;
+
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ spannableStringContent = new SpannableString(Html.fromHtml(status.getReblog() != null ?status.getReblog().getContent():status.getContent(), Html.FROM_HTML_MODE_LEGACY));
+ else
+ //noinspection deprecation
+ spannableStringContent = new SpannableString(Html.fromHtml(status.getReblog() != null ?status.getReblog().getContent():status.getContent()));
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ spannableStringCW = new SpannableString(Html.fromHtml(status.getReblog() != null ?status.getReblog().getSpoiler_text():status.getSpoiler_text(), Html.FROM_HTML_MODE_LEGACY));
+ else
+ //noinspection deprecation
+ spannableStringCW = new SpannableString(Html.fromHtml(status.getReblog() != null ?status.getReblog().getSpoiler_text():status.getSpoiler_text()));
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ spannableStringTranslated = new SpannableString(Html.fromHtml(status.getContent_translated(), Html.FROM_HTML_MODE_LEGACY));
+ else
+ //noinspection deprecation
+ spannableStringTranslated = new SpannableString(Html.fromHtml(status.getContent_translated()));
+
+ final List emojis = status.getReblog() != null ? status.getReblog().getEmojis() : status.getEmojis();
+ if( emojis != null && emojis.size() > 0 ) {
+ final int[] i = {0};
+ for (final Emojis emoji : emojis) {
+ Glide.with(context)
+ .asBitmap()
+ .load(emoji.getUrl())
+ .listener(new RequestListener() {
+ @Override
+ public boolean onResourceReady(Bitmap resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
+ return false;
+ }
+
+ @Override
+ public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
+ i[0]++;
+ if( i[0] == (emojis.size())) {
+ status.setContentSpan(spannableStringContent);
+ status.setContentSpanCW(spannableStringCW);
+ status.setContentSpanTranslated(spannableStringTranslated);
+ listener.onRetrieveEmoji(status);
+ }
+ return false;
+ }
+ })
+ .into(new SimpleTarget() {
+ @Override
+ public void onResourceReady(Bitmap resource, Transition super Bitmap> transition) {
+ final String targetedEmoji = ":" + emoji.getShortcode() + ":";
+ if (spannableStringContent.toString().contains(targetedEmoji)) {
+ //emojis can be used several times so we have to loop
+ for (int startPosition = -1; (startPosition = spannableStringContent.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
+ final int endPosition = startPosition + targetedEmoji.length();
+ spannableStringContent.setSpan(
+ new ImageSpan(context,
+ Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
+ (int) Helper.convertDpToPixel(20, context), false)), startPosition,
+ endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+ }
+ }
+ if (spannableStringCW.toString().contains(targetedEmoji)) {
+ //emojis can be used several times so we have to loop
+ for (int startPosition = -1; (startPosition = spannableStringCW.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
+ final int endPosition = startPosition + targetedEmoji.length();
+ spannableStringCW.setSpan(
+ new ImageSpan(context,
+ Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
+ (int) Helper.convertDpToPixel(20, context), false)), startPosition,
+ endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+ }
+ }
+ if (spannableStringTranslated.toString().contains(targetedEmoji)) {
+ //emojis can be used several times so we have to loop
+ for (int startPosition = -1; (startPosition = spannableStringTranslated.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
+ final int endPosition = startPosition + targetedEmoji.length();
+ spannableStringTranslated.setSpan(
+ new ImageSpan(context,
+ Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
+ (int) Helper.convertDpToPixel(20, context), false)), startPosition,
+ endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+ }
+ }
+ i[0]++;
+ if( i[0] == (emojis.size())) {
+ status.setContentSpan(spannableStringContent);
+ status.setContentSpanCW(spannableStringCW);
+ status.setContentSpanTranslated(spannableStringTranslated);
+ listener.onRetrieveEmoji(status);
+ }
+ }
+ });
+
+ }
+ }
+ }
+
+
+
+ private SpannableString treatment(final Context context, final SpannableString spannableString){
+
+ List mentions = status.getReblog() != null ? status.getReblog().getMentions() : status.getMentions();
+ SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
+ boolean embedded_browser = sharedpreferences.getBoolean(Helper.SET_EMBEDDED_BROWSER, true);
+ if( embedded_browser){
+ Matcher matcher;
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)
+ matcher = Patterns.WEB_URL.matcher(spannableString);
+ else
+ matcher = Helper.urlPattern.matcher(spannableString);
+ while (matcher.find()){
+ int matchStart = matcher.start(1);
+ int matchEnd = matcher.end();
+ final String url = spannableString.toString().substring(matchStart, matchEnd);
+ spannableString.setSpan(new ClickableSpan() {
+ @Override
+ public void onClick(View textView) {
+ Intent intent = new Intent(context, WebviewActivity.class);
+ Bundle b = new Bundle();
+ String finalUrl = url;
+ if( !url.startsWith("http://") && ! url.startsWith("https://"))
+ finalUrl = "http://" + url;
+ b.putString("url", finalUrl);
+ intent.putExtras(b);
+ context.startActivity(intent);
+ }
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ super.updateDrawState(ds);
+ }
+ },
+ matchStart, matchEnd,
+ Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+
+ }
+ }
+ //Deals with mention to make them clickable
+ if( mentions != null && mentions.size() > 0 ) {
+ //Looping through accounts which are mentioned
+ for (final Mention mention : mentions) {
+ String targetedAccount = "@" + mention.getUsername();
+ if (spannableString.toString().contains(targetedAccount)) {
+
+ //Accounts can be mentioned several times so we have to loop
+ for(int startPosition = -1 ; (startPosition = spannableString.toString().indexOf(targetedAccount, startPosition + 1)) != -1 ; startPosition++){
+ int endPosition = startPosition + targetedAccount.length();
+ spannableString.setSpan(new ClickableSpan() {
+ @Override
+ public void onClick(View textView) {
+ Intent intent = new Intent(context, ShowAccountActivity.class);
+ Bundle b = new Bundle();
+ b.putString("accountId", mention.getId());
+ intent.putExtras(b);
+ context.startActivity(intent);
+ }
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ super.updateDrawState(ds);
+ }
+ },
+ startPosition, endPosition,
+ Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+ }
+ }
+
+ }
+ }
+ Matcher matcher = Helper.hashtagPattern.matcher(spannableString);
+ while (matcher.find()){
+ int matchStart = matcher.start(1);
+ int matchEnd = matcher.end();
+ final String tag = spannableString.toString().substring(matchStart, matchEnd);
+ spannableString.setSpan(new ClickableSpan() {
+ @Override
+ public void onClick(View textView) {
+ Intent intent = new Intent(context, HashTagActivity.class);
+ Bundle b = new Bundle();
+ b.putString("tag", tag.substring(1));
+ intent.putExtras(b);
+ context.startActivity(intent);
+ }
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ super.updateDrawState(ds);
+ }
+ }, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+ }
+ return spannableString;
+ }
+
+ public SpannableString getContentSpan() {
+ return contentSpan;
+ }
+
+ public void setContentSpan(SpannableString contentSpan) {
+ this.contentSpan = contentSpan;
+ }
+
+ public SpannableString getContentSpanCW() {
+ return contentSpanCW;
+ }
+
+ public void setContentSpanCW(SpannableString contentSpanCW) {
+ this.contentSpanCW = contentSpanCW;
+ }
+
+ public SpannableString getContentSpanTranslated() {
+ return contentSpanTranslated;
+ }
+
+ public void setContentSpanTranslated(SpannableString contentSpanTranslated) {
+ this.contentSpanTranslated = contentSpanTranslated;
+ }
+
+ public boolean isClickable() {
+ return isClickable;
+ }
}
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 1aeb55935..dae6750ce 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
@@ -317,48 +317,6 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
return new ViewHolderEmpty(layoutInflater.inflate(R.layout.drawer_empty, parent, false));
}
- /*
- @Override
- public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, int position, List
","
");
content = content.replaceAll("","");
@@ -567,7 +535,9 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
final SpannableString spannableString = Helper.clickableElements(context,content,
status, true, StatusListAdapter.this);
holder.status_content.setText(spannableString, TextView.BufferType.SPANNABLE);
- }
+ }*/
+
+
holder.status_content.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
@@ -655,8 +625,6 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
}
if( status.getReblog() == null) {
- if( status.getSpoiler_text() != null)
- holder.status_spoiler.setText(status.getSpoiler_text());
if (status.getMedia_attachments().size() < 1) {
holder.status_document_container.setVisibility(View.GONE);
holder.status_show_more.setVisibility(View.GONE);
@@ -679,8 +647,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
}
}
}else { //Attachments for reblogs
- if( status.getReblog().getSpoiler_text() != null)
- holder.status_spoiler.setText(status.getReblog().getSpoiler_text());
+
if (status.getReblog().getMedia_attachments().size() < 1) {
holder.status_document_container.setVisibility(View.GONE);
holder.status_show_more.setVisibility(View.GONE);
@@ -1391,8 +1358,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
@Override
- public void onRetrieveEmoji(Status status, SpannableString spannableString, Boolean error) {
- status.setContents(spannableString);
+ public void onRetrieveEmoji(Status status) {
if( !status.isEmojiFound()) {
for (int i = 0; i < statusListAdapter.getItemCount(); i++) {
if (statusListAdapter.getItemAt(i) != null && statusListAdapter.getItemAt(i).getId().equals(status.getId())) {
@@ -1404,7 +1370,6 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
}
}
}
-
}
}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java
index 5cc607092..7f4caaa45 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java
@@ -1128,11 +1128,10 @@ public class Helper {
* Click on tag => HashTagActivity
* @param context Context
* @param fullContent String, should be the st
- * @param status Status
* @return TextView
*/
@SuppressWarnings("SameParameterValue")
- public static SpannableString clickableElements(final Context context, String fullContent, final Status status, boolean useHTML, final OnRetrieveEmojiInterface listener) {
+ /*public static SpannableString clickableElements(final Context context, String fullContent, final Status status, boolean useHTML, final OnRetrieveEmojiInterface listener) {
List mentions = status.getReblog() != null ? status.getReblog().getMentions() : status.getMentions();
final List emojis = status.getReblog() != null ? status.getReblog().getEmojis() : status.getEmojis();
final SpannableString spannableString;
@@ -1284,7 +1283,7 @@ public class Helper {
}
return spannableString;
- }
+ }*/
/**
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 76a566d0a..93db54d18 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
@@ -27,6 +27,6 @@ import fr.gouv.etalab.mastodon.client.Entities.Status;
* Interface when retrieving emojis
*/
public interface OnRetrieveEmojiInterface {
- void onRetrieveEmoji(Status status, SpannableString spannableString, Boolean error);
+ void onRetrieveEmoji(Status status);
void onRetrieveSearchEmoji(List emojis);
}