Custom emoji in more places
This commit is contained in:
@@ -6,6 +6,8 @@ import android.graphics.Outline;
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
@@ -16,6 +18,8 @@ import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.ui.text.CustomEmojiSpan;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.parceler.Parcels;
|
||||
|
||||
@@ -34,6 +38,9 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
private ImageLoaderRequest avaRequest;
|
||||
private Fragment parentFragment;
|
||||
private String accountID;
|
||||
private ImageLoaderRequest[] emojiRequests;
|
||||
private CustomEmojiSpan[] emojiSpans;
|
||||
private SpannableStringBuilder parsedName;
|
||||
|
||||
public HeaderStatusDisplayItem(String parentID, Account user, Instant createdAt, BaseStatusListFragment parentFragment, String accountID){
|
||||
super(parentID, parentFragment);
|
||||
@@ -42,6 +49,13 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
avaRequest=new UrlImageLoaderRequest(user.avatar);
|
||||
this.parentFragment=parentFragment;
|
||||
this.accountID=accountID;
|
||||
parsedName=new SpannableStringBuilder(user.displayName);
|
||||
HtmlParser.parseCustomEmoji(parsedName, user.emojis);
|
||||
emojiSpans=parsedName.getSpans(0, parsedName.length(), CustomEmojiSpan.class);
|
||||
emojiRequests=new ImageLoaderRequest[emojiSpans.length];
|
||||
for(int i=0; i<emojiSpans.length; i++){
|
||||
emojiRequests[i]=emojiSpans[i].createImageLoaderRequest();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,11 +65,14 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
|
||||
@Override
|
||||
public int getImageCount(){
|
||||
return 1;
|
||||
return 1+emojiRequests.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageLoaderRequest getImageRequest(int index){
|
||||
if(index>0){
|
||||
return emojiRequests[index-1];
|
||||
}
|
||||
return avaRequest;
|
||||
}
|
||||
|
||||
@@ -85,21 +102,25 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||
|
||||
@Override
|
||||
public void onBind(HeaderStatusDisplayItem item){
|
||||
name.setText(item.user.displayName);
|
||||
name.setText(item.parsedName);
|
||||
username.setText('@'+item.user.acct);
|
||||
timestamp.setText(UiUtils.formatRelativeTimestamp(itemView.getContext(), item.createdAt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(int index, Drawable drawable){
|
||||
avatar.setImageDrawable(drawable);
|
||||
if(index>0){
|
||||
item.emojiSpans[index-1].setDrawable(drawable);
|
||||
}else{
|
||||
avatar.setImageDrawable(drawable);
|
||||
}
|
||||
if(drawable instanceof Animatable)
|
||||
((Animatable) drawable).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearImage(int index){
|
||||
avatar.setImageBitmap(null);
|
||||
setImage(index, null);
|
||||
}
|
||||
|
||||
private void onAvaClick(View v){
|
||||
|
||||
@@ -33,9 +33,8 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
|
||||
if(text instanceof Spanned){
|
||||
CustomEmojiSpan[] emojiSpans=((Spanned) text).getSpans(0, text.length(), CustomEmojiSpan.class);
|
||||
emojiRequests=new ImageLoaderRequest[emojiSpans.length];
|
||||
int emojiSize=V.dp(20);
|
||||
for(int i=0; i<emojiSpans.length; i++){
|
||||
emojiRequests[i]=new UrlImageLoaderRequest(emojiSpans[i].emoji.url, emojiSize, emojiSize);
|
||||
emojiRequests[i]=emojiSpans[i].createImageLoaderRequest();
|
||||
}
|
||||
}else{
|
||||
emojiRequests=new ImageLoaderRequest[0];
|
||||
|
||||
@@ -10,6 +10,8 @@ import org.joinmastodon.android.model.Emoji;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class CustomEmojiSpan extends ReplacementSpan{
|
||||
public final Emoji emoji;
|
||||
@@ -48,4 +50,9 @@ public class CustomEmojiSpan extends ReplacementSpan{
|
||||
public void setDrawable(Drawable drawable){
|
||||
this.drawable=drawable;
|
||||
}
|
||||
|
||||
public UrlImageLoaderRequest createImageLoaderRequest(){
|
||||
int size=V.dp(20);
|
||||
return new UrlImageLoaderRequest(emoji.url, size, size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,23 +2,34 @@ package org.joinmastodon.android.ui.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.text.Spanned;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.MastodonApp;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.model.Emoji;
|
||||
import org.joinmastodon.android.ui.text.CustomEmojiSpan;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import androidx.annotation.ColorRes;
|
||||
import androidx.browser.customtabs.CustomTabsIntent;
|
||||
import me.grishka.appkit.imageloader.ViewImageLoader;
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class UiUtils{
|
||||
private static Handler mainHandler=new Handler(Looper.getMainLooper());
|
||||
@@ -93,4 +104,34 @@ public class UiUtils{
|
||||
}
|
||||
return uri.getLastPathSegment();
|
||||
}
|
||||
|
||||
public static void loadCustomEmojiInTextView(TextView view){
|
||||
CharSequence _text=view.getText();
|
||||
if(!(_text instanceof Spanned))
|
||||
return;
|
||||
Spanned text=(Spanned)_text;
|
||||
CustomEmojiSpan[] spans=text.getSpans(0, text.length(), CustomEmojiSpan.class);
|
||||
if(spans.length==0)
|
||||
return;
|
||||
int emojiSize=V.dp(20);
|
||||
Map<Emoji, List<CustomEmojiSpan>> spansByEmoji=Arrays.stream(spans).collect(Collectors.groupingBy(s->s.emoji));
|
||||
for(Map.Entry<Emoji, List<CustomEmojiSpan>> emoji:spansByEmoji.entrySet()){
|
||||
ViewImageLoader.load(new ViewImageLoader.Target(){
|
||||
@Override
|
||||
public void setImageDrawable(Drawable d){
|
||||
if(d==null)
|
||||
return;
|
||||
for(CustomEmojiSpan span:emoji.getValue()){
|
||||
span.setDrawable(d);
|
||||
}
|
||||
view.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(){
|
||||
return view;
|
||||
}
|
||||
}, null, new UrlImageLoaderRequest(emoji.getKey().url, emojiSize, emojiSize), null, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user