Commit 0bdee201 authored by Thomas's avatar Thomas
Browse files

Some tries

parent 941dd215
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
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) {

            }
        };
    }
}
+4 −230
Original line number Diff line number Diff line
@@ -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);

+7 −0

File changed.

Preview size limit exceeded, changes collapsed.

+2 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<shape />
 No newline at end of file