Loading app/build.gradle +1 −2 Original line number Diff line number Diff line Loading @@ -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' Loading app/src/main/java/app/fedilab/android/helper/CustomEmoji.java 0 → 100644 +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) { } }; } } app/src/main/java/app/fedilab/android/helper/SpannableHelper.java +4 −230 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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} Loading Loading @@ -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; Loading Loading @@ -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} Loading Loading @@ -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; Loading Loading @@ -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} Loading Loading @@ -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} Loading @@ -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); Loading app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java +7 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes app/src/main/res/drawable/empty_custom_emoji.xml 0 → 100644 +2 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <shape /> No newline at end of file Loading
app/build.gradle +1 −2 Original line number Diff line number Diff line Loading @@ -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' Loading
app/src/main/java/app/fedilab/android/helper/CustomEmoji.java 0 → 100644 +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) { } }; } }
app/src/main/java/app/fedilab/android/helper/SpannableHelper.java +4 −230 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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} Loading Loading @@ -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; Loading Loading @@ -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} Loading Loading @@ -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; Loading Loading @@ -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} Loading Loading @@ -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} Loading @@ -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); Loading
app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java +7 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes
app/src/main/res/drawable/empty_custom_emoji.xml 0 → 100644 +2 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <shape /> No newline at end of file