Custom emoji in more places

This commit is contained in:
Grishka
2022-02-10 22:10:16 +03:00
parent 82a8d0cc29
commit c9078ca8d7
7 changed files with 140 additions and 16 deletions

View File

@@ -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){

View File

@@ -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];

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}