mirror of
				https://codeberg.org/tom79/Fedilab.git
				synced 2025-10-20 11:20:16 +03:00 
			
		
		
		
	Some tries
This commit is contained in:
		
							parent
							
								
									941dd21561
								
							
						
					
					
						commit
						0bdee201e7
					
				
					 5 changed files with 144 additions and 232 deletions
				
			
		| 
						 | 
				
			
			@ -99,8 +99,7 @@ dependencies {
 | 
			
		|||
    implementation project(path: ':cropper')
 | 
			
		||||
    annotationProcessor "com.github.bumptech.glide:compiler:4.12.0"
 | 
			
		||||
    implementation 'jp.wasabeef:glide-transformations:4.3.0'
 | 
			
		||||
    implementation 'com.github.penfeizhou.android.animation:apng:2.22.0'
 | 
			
		||||
    implementation 'com.github.penfeizhou.android.animation:gif:2.22.0'
 | 
			
		||||
    implementation 'com.github.penfeizhou.android.animation:glide-plugin:2.22.0'
 | 
			
		||||
    implementation 'com.google.android.exoplayer:exoplayer:2.16.1'
 | 
			
		||||
    implementation "androidx.viewpager2:viewpager2:1.0.0"
 | 
			
		||||
    implementation 'com.github.piasy:rxandroidaudio:1.7.0'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										130
									
								
								app/src/main/java/app/fedilab/android/helper/CustomEmoji.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								app/src/main/java/app/fedilab/android/helper/CustomEmoji.java
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,130 @@
 | 
			
		|||
package app.fedilab.android.helper;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.SharedPreferences;
 | 
			
		||||
import android.graphics.Canvas;
 | 
			
		||||
import android.graphics.Paint;
 | 
			
		||||
import android.graphics.drawable.Drawable;
 | 
			
		||||
import android.text.Spannable;
 | 
			
		||||
import android.text.style.ReplacementSpan;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.preference.PreferenceManager;
 | 
			
		||||
 | 
			
		||||
import com.bumptech.glide.Glide;
 | 
			
		||||
import com.bumptech.glide.request.target.CustomTarget;
 | 
			
		||||
import com.bumptech.glide.request.target.Target;
 | 
			
		||||
import com.bumptech.glide.request.transition.Transition;
 | 
			
		||||
 | 
			
		||||
import java.lang.ref.WeakReference;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.regex.Matcher;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
 | 
			
		||||
import app.fedilab.android.R;
 | 
			
		||||
import app.fedilab.android.client.entities.api.Emoji;
 | 
			
		||||
 | 
			
		||||
public class CustomEmoji extends ReplacementSpan {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private final View view;
 | 
			
		||||
    private final float scale;
 | 
			
		||||
    private Drawable imageDrawable;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    CustomEmoji(WeakReference<View> viewWeakReference) {
 | 
			
		||||
        Context mContext = viewWeakReference.get().getContext();
 | 
			
		||||
        view = viewWeakReference.get();
 | 
			
		||||
        SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
 | 
			
		||||
        scale = sharedpreferences.getFloat(mContext.getString(R.string.SET_FONT_SCALE), 1.0f);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void displayEmoji(List<Emoji> emojis, Spannable spannableString, WeakReference<View> viewWeakReference) {
 | 
			
		||||
        View view = viewWeakReference.get();
 | 
			
		||||
        SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(view.getContext());
 | 
			
		||||
        boolean animate = !sharedpreferences.getBoolean(view.getContext().getString(R.string.SET_DISABLE_GIF), false);
 | 
			
		||||
        for (Emoji emoji : emojis) {
 | 
			
		||||
            Matcher matcher = Pattern.compile(":" + emoji.shortcode + ":", Pattern.LITERAL)
 | 
			
		||||
                    .matcher(spannableString);
 | 
			
		||||
            while (matcher.find()) {
 | 
			
		||||
                CustomEmoji customEmoji = new CustomEmoji(viewWeakReference);
 | 
			
		||||
                spannableString.setSpan(customEmoji, matcher.start(), matcher.end(), 0);
 | 
			
		||||
                Glide.with(view)
 | 
			
		||||
                        .asDrawable()
 | 
			
		||||
                        .load(animate ? emoji.url : emoji.static_url)
 | 
			
		||||
                        .into(customEmoji.getTarget(animate));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getSize(@NonNull Paint paint, CharSequence charSequence, int i, int i1, @Nullable Paint.FontMetricsInt fontMetricsInt) {
 | 
			
		||||
        Log.v(Helper.TAG, "fontMetricsInt: " + fontMetricsInt);
 | 
			
		||||
        if (fontMetricsInt != null) {
 | 
			
		||||
            Paint.FontMetrics fontMetrics = paint.getFontMetrics();
 | 
			
		||||
            fontMetricsInt.top = (int) fontMetrics.top;
 | 
			
		||||
            fontMetricsInt.ascent = (int) fontMetrics.ascent;
 | 
			
		||||
            fontMetricsInt.descent = (int) fontMetrics.descent;
 | 
			
		||||
            fontMetricsInt.bottom = (int) fontMetrics.bottom;
 | 
			
		||||
        }
 | 
			
		||||
        return (int) (paint.getTextSize() * scale);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void draw(@NonNull Canvas canvas, CharSequence charSequence, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
 | 
			
		||||
        
 | 
			
		||||
        if (imageDrawable != null) {
 | 
			
		||||
            canvas.save();
 | 
			
		||||
            int emojiSize = (int) (paint.getTextSize() * scale);
 | 
			
		||||
            Drawable drawable = imageDrawable;
 | 
			
		||||
            drawable.setBounds(0, 0, emojiSize, emojiSize);
 | 
			
		||||
            int transY = bottom - drawable.getBounds().bottom;
 | 
			
		||||
            Log.v(Helper.TAG, "transY: " + transY);
 | 
			
		||||
            transY -= paint.getFontMetrics().descent / 2;
 | 
			
		||||
            Log.v(Helper.TAG, "transY: " + transY);
 | 
			
		||||
            canvas.translate(x, (float) transY);
 | 
			
		||||
            Log.v(Helper.TAG, "x: " + x);
 | 
			
		||||
            drawable.draw(canvas);
 | 
			
		||||
            canvas.restore();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Target<Drawable> getTarget(boolean animate) {
 | 
			
		||||
        return new CustomTarget<Drawable>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
 | 
			
		||||
                if (animate) {
 | 
			
		||||
                    Drawable.Callback callback = resource.getCallback();
 | 
			
		||||
                    resource.setCallback(new Drawable.Callback() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void invalidateDrawable(@NonNull Drawable drawable) {
 | 
			
		||||
                            callback.invalidateDrawable(drawable);
 | 
			
		||||
                            view.invalidate();
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void scheduleDrawable(@NonNull Drawable drawable, @NonNull Runnable runnable, long l) {
 | 
			
		||||
                            callback.scheduleDrawable(drawable, runnable, l);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void unscheduleDrawable(@NonNull Drawable drawable, @NonNull Runnable runnable) {
 | 
			
		||||
                            callback.unscheduleDrawable(drawable, runnable);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
                Log.v(Helper.TAG, "imageDrawable2: " + imageDrawable);
 | 
			
		||||
                imageDrawable = resource;
 | 
			
		||||
                view.invalidate();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onLoadCleared(@Nullable Drawable placeholder) {
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -17,7 +17,6 @@ package app.fedilab.android.helper;
 | 
			
		|||
 | 
			
		||||
import static app.fedilab.android.BaseMainActivity.currentAccount;
 | 
			
		||||
import static app.fedilab.android.helper.Helper.USER_AGENT;
 | 
			
		||||
import static app.fedilab.android.helper.Helper.convertDpToPixel;
 | 
			
		||||
import static app.fedilab.android.helper.Helper.urlPattern;
 | 
			
		||||
import static app.fedilab.android.helper.ThemeHelper.linkColor;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -25,8 +24,6 @@ import android.content.ClipData;
 | 
			
		|||
import android.content.ClipboardManager;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.content.SharedPreferences;
 | 
			
		||||
import android.graphics.drawable.Drawable;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Build;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +35,6 @@ import android.text.SpannableStringBuilder;
 | 
			
		|||
import android.text.Spanned;
 | 
			
		||||
import android.text.TextPaint;
 | 
			
		||||
import android.text.style.ClickableSpan;
 | 
			
		||||
import android.text.style.ImageSpan;
 | 
			
		||||
import android.text.style.URLSpan;
 | 
			
		||||
import android.util.Patterns;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
| 
						 | 
				
			
			@ -47,16 +43,7 @@ import android.widget.Toast;
 | 
			
		|||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AlertDialog;
 | 
			
		||||
import androidx.preference.PreferenceManager;
 | 
			
		||||
 | 
			
		||||
import com.bumptech.glide.Glide;
 | 
			
		||||
import com.bumptech.glide.request.FutureTarget;
 | 
			
		||||
import com.github.penfeizhou.animation.apng.APNGDrawable;
 | 
			
		||||
import com.github.penfeizhou.animation.apng.decode.APNGParser;
 | 
			
		||||
import com.github.penfeizhou.animation.gif.GifDrawable;
 | 
			
		||||
import com.github.penfeizhou.animation.gif.decode.GifParser;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.net.MalformedURLException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +52,6 @@ import java.util.HashMap;
 | 
			
		|||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.concurrent.ExecutionException;
 | 
			
		||||
import java.util.regex.Matcher;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +64,6 @@ import app.fedilab.android.activities.ProfileActivity;
 | 
			
		|||
import app.fedilab.android.client.entities.api.Account;
 | 
			
		||||
import app.fedilab.android.client.entities.api.Announcement;
 | 
			
		||||
import app.fedilab.android.client.entities.api.Attachment;
 | 
			
		||||
import app.fedilab.android.client.entities.api.Emoji;
 | 
			
		||||
import app.fedilab.android.client.entities.api.Field;
 | 
			
		||||
import app.fedilab.android.client.entities.api.Mention;
 | 
			
		||||
import app.fedilab.android.client.entities.api.Poll;
 | 
			
		||||
| 
						 | 
				
			
			@ -95,7 +80,7 @@ public class SpannableHelper {
 | 
			
		|||
        return convert(context, status, text, true);
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert HTML content to text. Also, it handles click on link and transform emoji
 | 
			
		||||
     * Convert HTML content to text. Also, it handles click on link
 | 
			
		||||
     * This needs to be run asynchronously
 | 
			
		||||
     *
 | 
			
		||||
     * @param context     {@link Context}
 | 
			
		||||
| 
						 | 
				
			
			@ -138,77 +123,6 @@ public class SpannableHelper {
 | 
			
		|||
            content.removeSpan(span);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--- EMOJI ----
 | 
			
		||||
        SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
 | 
			
		||||
        boolean disableGif = sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_GIF), false);
 | 
			
		||||
        List<Emoji> emojiList = status.reblog != null ? status.reblog.emojis : status.emojis;
 | 
			
		||||
        //Will convert emoji if asked
 | 
			
		||||
        if (emojiList != null && emojiList.size() > 0) {
 | 
			
		||||
            for (Emoji emoji : emojiList) {
 | 
			
		||||
                if (Helper.isValidContextForGlide(context)) {
 | 
			
		||||
                    FutureTarget<File> futureTarget = Glide.with(context)
 | 
			
		||||
                            .asFile()
 | 
			
		||||
                            .load(disableGif ? emoji.static_url : emoji.url)
 | 
			
		||||
                            .submit();
 | 
			
		||||
                    try {
 | 
			
		||||
                        File file = futureTarget.get();
 | 
			
		||||
                        final String targetedEmoji = ":" + emoji.shortcode + ":";
 | 
			
		||||
                        if (content.toString().contains(targetedEmoji)) {
 | 
			
		||||
                            //emojis can be used several times so we have to loop
 | 
			
		||||
                            for (int startPosition = -1; (startPosition = content.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
 | 
			
		||||
                                final int endPosition = startPosition + targetedEmoji.length();
 | 
			
		||||
                                if (endPosition <= content.toString().length() && endPosition >= startPosition) {
 | 
			
		||||
                                    ImageSpan imageSpan;
 | 
			
		||||
                                    if (APNGParser.isAPNG(file.getAbsolutePath())) {
 | 
			
		||||
                                        APNGDrawable apngDrawable = APNGDrawable.fromFile(file.getAbsolutePath());
 | 
			
		||||
                                        try {
 | 
			
		||||
                                            apngDrawable.setBounds(0, 0, (int) convertDpToPixel(20, context), (int) convertDpToPixel(20, context));
 | 
			
		||||
                                            apngDrawable.setVisible(true, true);
 | 
			
		||||
                                            imageSpan = new ImageSpan(apngDrawable);
 | 
			
		||||
                                            if (endPosition <= content.length()) {
 | 
			
		||||
                                                content.setSpan(
 | 
			
		||||
                                                        imageSpan, startPosition,
 | 
			
		||||
                                                        endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        } catch (Exception ignored) {
 | 
			
		||||
                                        }
 | 
			
		||||
                                    } else if (GifParser.isGif(file.getAbsolutePath())) {
 | 
			
		||||
                                        GifDrawable gifDrawable = GifDrawable.fromFile(file.getAbsolutePath());
 | 
			
		||||
                                        try {
 | 
			
		||||
                                            gifDrawable.setBounds(0, 0, (int) convertDpToPixel(20, context), (int) convertDpToPixel(20, context));
 | 
			
		||||
                                            gifDrawable.setVisible(true, true);
 | 
			
		||||
                                            imageSpan = new ImageSpan(gifDrawable);
 | 
			
		||||
                                            if (endPosition <= content.length()) {
 | 
			
		||||
                                                content.setSpan(
 | 
			
		||||
                                                        imageSpan, startPosition,
 | 
			
		||||
                                                        endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        } catch (Exception ignored) {
 | 
			
		||||
                                        }
 | 
			
		||||
                                    } else {
 | 
			
		||||
                                        Drawable drawable = Drawable.createFromPath(file.getAbsolutePath());
 | 
			
		||||
                                        try {
 | 
			
		||||
                                            drawable.setBounds(0, 0, (int) convertDpToPixel(20, context), (int) convertDpToPixel(20, context));
 | 
			
		||||
                                            drawable.setVisible(true, true);
 | 
			
		||||
                                            imageSpan = new ImageSpan(drawable);
 | 
			
		||||
                                            if (endPosition <= content.length()) {
 | 
			
		||||
                                                content.setSpan(
 | 
			
		||||
                                                        imageSpan, startPosition,
 | 
			
		||||
                                                        endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        } catch (Exception ignored) {
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    } catch (ExecutionException | InterruptedException e) {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--- URLs ----
 | 
			
		||||
        Matcher matcherLink = Patterns.WEB_URL.matcher(content);
 | 
			
		||||
        int offSetTruncate = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -565,7 +479,7 @@ public class SpannableHelper {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert HTML content to text. Also, it handles click on link and transform emoji
 | 
			
		||||
     * Convert HTML content to text. Also, it handles click on link
 | 
			
		||||
     * This needs to be run asynchronously
 | 
			
		||||
     *
 | 
			
		||||
     * @param context      {@link Context}
 | 
			
		||||
| 
						 | 
				
			
			@ -603,77 +517,6 @@ public class SpannableHelper {
 | 
			
		|||
            content.removeSpan(span);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--- EMOJI ----
 | 
			
		||||
        SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
 | 
			
		||||
        boolean disableGif = sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_GIF), false);
 | 
			
		||||
        List<Emoji> emojiList = announcement.emojis;
 | 
			
		||||
        //Will convert emoji if asked
 | 
			
		||||
        if (emojiList != null && emojiList.size() > 0) {
 | 
			
		||||
            for (Emoji emoji : emojiList) {
 | 
			
		||||
                if (Helper.isValidContextForGlide(context)) {
 | 
			
		||||
                    FutureTarget<File> futureTarget = Glide.with(context)
 | 
			
		||||
                            .asFile()
 | 
			
		||||
                            .load(disableGif ? emoji.static_url : emoji.url)
 | 
			
		||||
                            .submit();
 | 
			
		||||
                    try {
 | 
			
		||||
                        File file = futureTarget.get();
 | 
			
		||||
                        final String targetedEmoji = ":" + emoji.shortcode + ":";
 | 
			
		||||
                        if (content.toString().contains(targetedEmoji)) {
 | 
			
		||||
                            //emojis can be used several times so we have to loop
 | 
			
		||||
                            for (int startPosition = -1; (startPosition = content.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
 | 
			
		||||
                                final int endPosition = startPosition + targetedEmoji.length();
 | 
			
		||||
                                if (endPosition <= content.toString().length() && endPosition >= startPosition) {
 | 
			
		||||
                                    ImageSpan imageSpan;
 | 
			
		||||
                                    if (APNGParser.isAPNG(file.getAbsolutePath())) {
 | 
			
		||||
                                        APNGDrawable apngDrawable = APNGDrawable.fromFile(file.getAbsolutePath());
 | 
			
		||||
                                        try {
 | 
			
		||||
                                            apngDrawable.setBounds(0, 0, (int) convertDpToPixel(20, context), (int) convertDpToPixel(20, context));
 | 
			
		||||
                                            apngDrawable.setVisible(true, true);
 | 
			
		||||
                                            imageSpan = new ImageSpan(apngDrawable);
 | 
			
		||||
                                            if (endPosition <= content.length()) {
 | 
			
		||||
                                                content.setSpan(
 | 
			
		||||
                                                        imageSpan, startPosition,
 | 
			
		||||
                                                        endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        } catch (Exception ignored) {
 | 
			
		||||
                                        }
 | 
			
		||||
                                    } else if (GifParser.isGif(file.getAbsolutePath())) {
 | 
			
		||||
                                        GifDrawable gifDrawable = GifDrawable.fromFile(file.getAbsolutePath());
 | 
			
		||||
                                        try {
 | 
			
		||||
                                            gifDrawable.setBounds(0, 0, (int) convertDpToPixel(20, context), (int) convertDpToPixel(20, context));
 | 
			
		||||
                                            gifDrawable.setVisible(true, true);
 | 
			
		||||
                                            imageSpan = new ImageSpan(gifDrawable);
 | 
			
		||||
                                            if (endPosition <= content.length()) {
 | 
			
		||||
                                                content.setSpan(
 | 
			
		||||
                                                        imageSpan, startPosition,
 | 
			
		||||
                                                        endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        } catch (Exception ignored) {
 | 
			
		||||
                                        }
 | 
			
		||||
                                    } else {
 | 
			
		||||
                                        Drawable drawable = Drawable.createFromPath(file.getAbsolutePath());
 | 
			
		||||
                                        try {
 | 
			
		||||
                                            drawable.setBounds(0, 0, (int) convertDpToPixel(20, context), (int) convertDpToPixel(20, context));
 | 
			
		||||
                                            drawable.setVisible(true, true);
 | 
			
		||||
                                            imageSpan = new ImageSpan(drawable);
 | 
			
		||||
                                            if (endPosition <= content.length()) {
 | 
			
		||||
                                                content.setSpan(
 | 
			
		||||
                                                        imageSpan, startPosition,
 | 
			
		||||
                                                        endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        } catch (Exception ignored) {
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    } catch (ExecutionException | InterruptedException e) {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--- URLs ----
 | 
			
		||||
        Matcher matcherLink = Patterns.WEB_URL.matcher(content);
 | 
			
		||||
        int offSetTruncate = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1035,7 +878,7 @@ public class SpannableHelper {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert HTML content to text. Also, it handles click on link and transform emoji
 | 
			
		||||
     * Convert HTML content to text. Also, it handles click on link
 | 
			
		||||
     * This needs to be run asynchronously
 | 
			
		||||
     *
 | 
			
		||||
     * @param context {@link Context}
 | 
			
		||||
| 
						 | 
				
			
			@ -1132,7 +975,7 @@ public class SpannableHelper {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert HTML content to text. Also, it handles click on link and transform emoji
 | 
			
		||||
     * Convert HTML content to text. Also, it handles click on link
 | 
			
		||||
     * This needs to be run asynchronously
 | 
			
		||||
     *
 | 
			
		||||
     * @param context {@link Context}
 | 
			
		||||
| 
						 | 
				
			
			@ -1157,75 +1000,6 @@ public class SpannableHelper {
 | 
			
		|||
        URLSpan[] urls = content.getSpans(0, (content.length() - 1), URLSpan.class);
 | 
			
		||||
        for (URLSpan span : urls)
 | 
			
		||||
            content.removeSpan(span);
 | 
			
		||||
        //--- EMOJI ----
 | 
			
		||||
        SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
 | 
			
		||||
        boolean disableGif = sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_GIF), false);
 | 
			
		||||
        //Will convert emoji if asked
 | 
			
		||||
        if (account.emojis != null && account.emojis.size() > 0) {
 | 
			
		||||
            for (Emoji emoji : account.emojis) {
 | 
			
		||||
                if (Helper.isValidContextForGlide(context)) {
 | 
			
		||||
                    FutureTarget<File> futureTarget = Glide.with(context)
 | 
			
		||||
                            .asFile()
 | 
			
		||||
                            .load(disableGif ? emoji.static_url : emoji.url)
 | 
			
		||||
                            .submit();
 | 
			
		||||
                    try {
 | 
			
		||||
                        File file = futureTarget.get();
 | 
			
		||||
                        final String targetedEmoji = ":" + emoji.shortcode + ":";
 | 
			
		||||
                        if (content.toString().contains(targetedEmoji)) {
 | 
			
		||||
                            //emojis can be used several times so we have to loop
 | 
			
		||||
                            for (int startPosition = -1; (startPosition = content.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
 | 
			
		||||
                                final int endPosition = startPosition + targetedEmoji.length();
 | 
			
		||||
                                if (endPosition <= content.toString().length() && endPosition >= startPosition) {
 | 
			
		||||
                                    ImageSpan imageSpan;
 | 
			
		||||
                                    if (APNGParser.isAPNG(file.getAbsolutePath())) {
 | 
			
		||||
                                        APNGDrawable apngDrawable = APNGDrawable.fromFile(file.getAbsolutePath());
 | 
			
		||||
                                        try {
 | 
			
		||||
                                            apngDrawable.setBounds(0, 0, (int) convertDpToPixel(20, context), (int) convertDpToPixel(20, context));
 | 
			
		||||
                                            apngDrawable.setVisible(true, true);
 | 
			
		||||
                                            imageSpan = new ImageSpan(apngDrawable);
 | 
			
		||||
                                            content.setSpan(
 | 
			
		||||
                                                    imageSpan, startPosition,
 | 
			
		||||
                                                    endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
 | 
			
		||||
 | 
			
		||||
                                        } catch (Exception ignored) {
 | 
			
		||||
                                        }
 | 
			
		||||
                                    } else if (GifParser.isGif(file.getAbsolutePath())) {
 | 
			
		||||
                                        GifDrawable gifDrawable = GifDrawable.fromFile(file.getAbsolutePath());
 | 
			
		||||
                                        try {
 | 
			
		||||
                                            gifDrawable.setBounds(0, 0, (int) convertDpToPixel(20, context), (int) convertDpToPixel(20, context));
 | 
			
		||||
                                            gifDrawable.setVisible(true, true);
 | 
			
		||||
                                            imageSpan = new ImageSpan(gifDrawable);
 | 
			
		||||
                                            content.setSpan(
 | 
			
		||||
                                                    imageSpan, startPosition,
 | 
			
		||||
                                                    endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
 | 
			
		||||
                                        } catch (Exception ignored) {
 | 
			
		||||
                                        }
 | 
			
		||||
                                    } else {
 | 
			
		||||
                                        try {
 | 
			
		||||
                                            Drawable drawable = Drawable.createFromPath(file.getAbsolutePath());
 | 
			
		||||
                                            drawable.setBounds(0, 0, (int) convertDpToPixel(20, context), (int) convertDpToPixel(20, context));
 | 
			
		||||
                                            drawable.setVisible(true, true);
 | 
			
		||||
                                            imageSpan = new ImageSpan(drawable);
 | 
			
		||||
                                            if (endPosition <= content.length()) {
 | 
			
		||||
                                                content.setSpan(
 | 
			
		||||
                                                        imageSpan, startPosition,
 | 
			
		||||
                                                        endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        } catch (Exception ignored) {
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    } catch (ExecutionException | InterruptedException e) {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (limitedToDisplayName) {
 | 
			
		||||
            return content;
 | 
			
		||||
        }
 | 
			
		||||
        //--- URLs ----
 | 
			
		||||
        Matcher matcherALink = Patterns.WEB_URL.matcher(content);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,6 +82,7 @@ import com.github.stom79.mytransl.translate.Params;
 | 
			
		|||
import com.github.stom79.mytransl.translate.Translate;
 | 
			
		||||
import com.varunest.sparkbutton.SparkButton;
 | 
			
		||||
 | 
			
		||||
import java.lang.ref.WeakReference;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
| 
						 | 
				
			
			@ -117,6 +118,7 @@ import app.fedilab.android.databinding.LayoutMediaBinding;
 | 
			
		|||
import app.fedilab.android.databinding.LayoutPollItemBinding;
 | 
			
		||||
import app.fedilab.android.exception.DBException;
 | 
			
		||||
import app.fedilab.android.helper.CrossActionHelper;
 | 
			
		||||
import app.fedilab.android.helper.CustomEmoji;
 | 
			
		||||
import app.fedilab.android.helper.GlideFocus;
 | 
			
		||||
import app.fedilab.android.helper.Helper;
 | 
			
		||||
import app.fedilab.android.helper.LongClickLinkMovementMethod;
 | 
			
		||||
| 
						 | 
				
			
			@ -253,6 +255,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
 | 
			
		|||
        statusToDeal.bookmarked = statusReturned.bookmarked;
 | 
			
		||||
        statusToDeal.reblogs_count = statusReturned.reblogs_count;
 | 
			
		||||
        statusToDeal.favourites_count = statusReturned.favourites_count;
 | 
			
		||||
 | 
			
		||||
        //Update status in cache if not a remote instance
 | 
			
		||||
        if (!remote) {
 | 
			
		||||
            new Thread(() -> {
 | 
			
		||||
| 
						 | 
				
			
			@ -370,6 +373,10 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
 | 
			
		|||
        holder.binding.actionButtonBookmark.setActiveImageTint(R.color.marked_icon);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if (statusToDeal.emojis != null && statusToDeal.emojis.size() > 0) {
 | 
			
		||||
            CustomEmoji.displayEmoji(statusToDeal.emojis, statusToDeal.span_content, new WeakReference<>(holder.binding.statusContent));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (status.pinned) {
 | 
			
		||||
            holder.binding.statusPinned.setVisibility(View.VISIBLE);
 | 
			
		||||
        } else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								app/src/main/res/drawable/empty_custom_emoji.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								app/src/main/res/drawable/empty_custom_emoji.xml
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<shape />
 | 
			
		||||
		Loading…
	
		Reference in a new issue