Improves custom emoji on profiles

This commit is contained in:
stom79 2018-08-15 14:31:15 +02:00
parent c7ebdc50c2
commit 90d1c4e5ae
5 changed files with 194 additions and 27 deletions

View File

@ -82,6 +82,7 @@ import fr.gouv.etalab.mastodon.fragments.DisplayStatusFragment;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAccountInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiAccountInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsAccountInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveRelationshipInterface;
@ -101,7 +102,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.withSuffix;
* Show account activity class
*/
public class ShowAccountActivity extends BaseActivity implements OnPostActionInterface, OnRetrieveAccountInterface, OnRetrieveFeedsAccountInterface, OnRetrieveRelationshipInterface, OnRetrieveFeedsInterface {
public class ShowAccountActivity extends BaseActivity implements OnPostActionInterface, OnRetrieveAccountInterface, OnRetrieveFeedsAccountInterface, OnRetrieveRelationshipInterface, OnRetrieveFeedsInterface, OnRetrieveEmojiAccountInterface {
private List<Status> statuses;
@ -129,6 +130,8 @@ public class ShowAccountActivity extends BaseActivity implements OnPostActionInt
private Account account;
private boolean show_boosts, show_replies;
public enum action{
FOLLOW,
UNFOLLOW,
@ -582,6 +585,8 @@ public class ShowAccountActivity extends BaseActivity implements OnPostActionInt
}
});
if ( account.getFields() != null && account.getFields().size() > 0){
HashMap<String, String> fields = account.getFields();
Iterator it = fields.entrySet().iterator();
@ -642,23 +647,22 @@ public class ShowAccountActivity extends BaseActivity implements OnPostActionInt
valueView.setBackgroundColor(ContextCompat.getColor(ShowAccountActivity.this, R.color.notif_dark_4));
}
field.setVisibility(View.VISIBLE);
SpannableString spannableValueString = Helper.clickableElementsDescription(ShowAccountActivity.this, value);
SpannableString spannableValueString = Helper.clickableElementsDescription(ShowAccountActivity.this, value, account.getEmojis());
valueView.setText(spannableValueString, TextView.BufferType.SPANNABLE);
valueView.setMovementMethod(LinkMovementMethod.getInstance());
labelView.setText(label);
}
i++;
it.remove();
// it.remove();
}
}
account_dn.setText(Helper.shortnameToUnicode(account.getDisplay_name(), true));
account_un.setText(String.format("@%s", account.getAcct()));
SpannableString spannableString = Helper.clickableElementsDescription(ShowAccountActivity.this, account.getNote());
SpannableString spannableString = Helper.clickableElementsDescription(ShowAccountActivity.this, account.getNote(), account.getEmojis());
account.setNoteSpan(spannableString);
account.makeEmojis(ShowAccountActivity.this);
spannableString = account.getNoteSpan();
account_note.setText(spannableString, TextView.BufferType.SPANNABLE);
account.makeEmojisAccount(ShowAccountActivity.this, ShowAccountActivity.this);
account_note.setText(account.getNoteSpan(), TextView.BufferType.SPANNABLE);
account_note.setMovementMethod(LinkMovementMethod.getInstance());
if (tabLayout.getTabAt(0) != null && tabLayout.getTabAt(1) != null && tabLayout.getTabAt(2) != null) {
//noinspection ConstantConditions
@ -906,6 +910,62 @@ public class ShowAccountActivity extends BaseActivity implements OnPostActionInt
}
}
@Override
public void onRetrieveEmojiAccount(Account account) {
account_note.setText(account.getNoteSpan(), TextView.BufferType.SPANNABLE);
if ( account.getFieldsSpan() != null && account.getFieldsSpan().size() > 0){
HashMap<String, SpannableString> fieldsSpan = account.getFieldsSpan();
Iterator it = fieldsSpan.entrySet().iterator();
int i = 1;
LinearLayout fields_container = findViewById(R.id.fields_container);
if( fields_container != null)
fields_container.setVisibility(View.VISIBLE);
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
String label = (String)pair.getKey();
String value = (String)pair.getValue();
LinearLayout field;
TextView labelView;
TextView valueView;
switch(i){
case 1:
field = findViewById(R.id.field1);
labelView = findViewById(R.id.label1);
valueView = findViewById(R.id.value1);
break;
case 2:
field = findViewById(R.id.field2);
labelView = findViewById(R.id.label2);
valueView = findViewById(R.id.value2);
break;
case 3:
field = findViewById(R.id.field3);
labelView = findViewById(R.id.label3);
valueView = findViewById(R.id.value3);
break;
case 4:
field = findViewById(R.id.field4);
labelView = findViewById(R.id.label4);
valueView = findViewById(R.id.value4);
break;
default:
field = findViewById(R.id.field1);
labelView = findViewById(R.id.label1);
valueView = findViewById(R.id.value1);
break;
}
if( field != null && labelView != null && valueView != null) {
field.setVisibility(View.VISIBLE);
valueView.setText(value, TextView.BufferType.SPANNABLE);
valueView.setMovementMethod(LinkMovementMethod.getInstance());
labelView.setText(label);
}
i++;
// it.remove();
}
}
}
public boolean showReplies(){
return show_replies;
}

View File

@ -1668,7 +1668,7 @@ public class API {
List<Emojis> emojiList = new ArrayList<>();
try {
JSONArray emojisTag = resobj.getJSONArray("emojis");
if( arrayTag != null){
if( emojisTag != null){
for(int j = 0 ; j < emojisTag.length() ; j++){
JSONObject emojisObj = emojisTag.getJSONObject(j);
Emojis emojis = parseEmojis(emojisObj);
@ -1859,6 +1859,22 @@ public class API {
}
account.setFields(fieldsMap);
}catch (Exception ignored){}
//Retrieves emjis
List<Emojis> emojiList = new ArrayList<>();
try {
JSONArray emojisTag = resobj.getJSONArray("emojis");
if( emojisTag != null){
for(int j = 0 ; j < emojisTag.length() ; j++){
JSONObject emojisObj = emojisTag.getJSONObject(j);
Emojis emojis = parseEmojis(emojisObj);
emojiList.add(emojis);
}
}
account.setEmojis(emojiList);
}catch (Exception e){
account.setEmojis(new ArrayList<>());
}
} catch (JSONException ignored) {}
return account;
}

View File

@ -18,11 +18,12 @@ import android.app.Activity;
import android.content.*;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
@ -32,23 +33,21 @@ import android.text.style.ImageSpan;
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.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import fr.gouv.etalab.mastodon.R;
import fr.gouv.etalab.mastodon.activities.ShowAccountActivity;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiAccountInterface;
import static android.text.Html.FROM_HTML_MODE_LEGACY;
/**
* Created by Thomas on 23/04/2017.
@ -85,6 +84,7 @@ public class Account implements Parcelable {
private boolean muting_notifications;
private int metaDataSize;
private HashMap<String, String> fields = new HashMap<>();
private HashMap<String, SpannableString> fieldsSpan = new HashMap<>();
private List<Emojis> emojis;
private Account account;
@ -122,14 +122,25 @@ public class Account implements Parcelable {
this.muting_notifications = muting_notifications;
}
public void setFields(HashMap<String, String> fields) {
this.fields = fields;
}
public HashMap<String, String> getFields() {
return fields;
}
public void setFields(HashMap<String, String> fields) {
this.fields = fields;
public void setFieldsSpan(HashMap<String, SpannableString> fieldsSpan) {
this.fieldsSpan = fieldsSpan;
}
public HashMap<String, SpannableString> getFieldsSpan() {
return fieldsSpan;
}
public enum followAction{
FOLLOW,
NOT_FOLLOW,
@ -431,37 +442,88 @@ public class Account implements Parcelable {
}
public void makeEmojis(final Context context){
public void makeEmojisAccount(final Context context, final OnRetrieveEmojiAccountInterface listener){
if( ((Activity)context).isFinishing() )
return;
SpannableString spannableStringNote = null;
if( account.getNote() != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
spannableStringNote = new SpannableString(Html.fromHtml(account.getNote(), FROM_HTML_MODE_LEGACY));
else
//noinspection deprecation
spannableStringNote = new SpannableString(Html.fromHtml(account.getNote()));
}
final List<Emojis> emojis = account.getEmojis();
if( noteSpan == null)
noteSpan = new SpannableString(account.getNote());
if( emojis != null && emojis.size() > 0 ) {
final int[] i = {0};
for (final Emojis emoji : emojis) {
final SpannableString finalSpannableStringNote = spannableStringNote;
fields = account.getFields();
Glide.with(context)
.asBitmap()
.load(emoji.getUrl())
/*.listener(new RequestListener<Bitmap>() {
@Override
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> 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())) {
if( finalSpannableStringNote != null)
account.setNoteSpan(finalSpannableStringNote);
listener.onRetrieveEmojiAccount(account);
}
return false;
}
})*/
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
final String targetedEmoji = ":" + emoji.getShortcode() + ":";
if (account.getNote().contains(targetedEmoji)) {
if (finalSpannableStringNote != null && finalSpannableStringNote.toString().contains(targetedEmoji)) {
//emojis can be used several times so we have to loop
for (int startPosition = -1; (startPosition = account.getNote().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
for (int startPosition = -1; (startPosition = finalSpannableStringNote.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
final int endPosition = startPosition + targetedEmoji.length();
if( endPosition <= account.getNote().length() && endPosition >= startPosition)
noteSpan.setSpan(
if(endPosition <= finalSpannableStringNote.toString().length() && endPosition >= startPosition)
finalSpannableStringNote.setSpan(
new ImageSpan(context,
Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
(int) Helper.convertDpToPixel(20, context), false)), startPosition,
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
Iterator it = account.getFields().entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
SpannableString fieldSpan = new SpannableString((String)pair.getValue());
if (fieldSpan.toString().contains(targetedEmoji)) {
//emojis can be used several times so we have to loop
for (int startPosition = -1; (startPosition = fieldSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
final int endPosition = startPosition + targetedEmoji.length();
if(endPosition <= fieldSpan.toString().length() && endPosition >= startPosition)
fieldSpan.setSpan(
new ImageSpan(context,
Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
(int) Helper.convertDpToPixel(20, context), false)), startPosition,
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
fieldsSpan.put((String)pair.getKey(), fieldSpan);
}
it.remove();
}
i[0]++;
if( i[0] == (emojis.size())) {
if( finalSpannableStringNote != null)
account.setNoteSpan(finalSpannableStringNote);
listener.onRetrieveEmojiAccount(account);
}
}
});
@ -469,4 +531,5 @@ public class Account implements Parcelable {
}
}
}

View File

@ -67,10 +67,12 @@ import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.content.ContextCompat;
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;
@ -1325,7 +1327,7 @@ public class Helper {
* @param fullContent String, should be the st
* @return TextView
*/
public static SpannableString clickableElementsDescription(final Context context, String fullContent) {
public static SpannableString clickableElementsDescription(final Context context, String fullContent, List<Emojis> emojis) {
SpannableString spannableString;
fullContent = Helper.shortnameToUnicode(fullContent, true);

View File

@ -0,0 +1,26 @@
/* Copyright 2018 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 fr.gouv.etalab.mastodon.client.Entities.Account;
/**
* Created by Thomas on 15/08/2018.
* Interface when retrieving emojis for accounts
*/
public interface OnRetrieveEmojiAccountInterface {
void onRetrieveEmojiAccount(Account account);
}