mirror of
https://codeberg.org/tom79/Fedilab.git
synced 2025-01-07 00:20:08 +02: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')
|
implementation project(path: ':cropper')
|
||||||
annotationProcessor "com.github.bumptech.glide:compiler:4.12.0"
|
annotationProcessor "com.github.bumptech.glide:compiler:4.12.0"
|
||||||
implementation 'jp.wasabeef:glide-transformations:4.3.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:glide-plugin:2.22.0'
|
||||||
implementation 'com.github.penfeizhou.android.animation:gif:2.22.0'
|
|
||||||
implementation 'com.google.android.exoplayer:exoplayer:2.16.1'
|
implementation 'com.google.android.exoplayer:exoplayer:2.16.1'
|
||||||
implementation "androidx.viewpager2:viewpager2:1.0.0"
|
implementation "androidx.viewpager2:viewpager2:1.0.0"
|
||||||
implementation 'com.github.piasy:rxandroidaudio:1.7.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.BaseMainActivity.currentAccount;
|
||||||
import static app.fedilab.android.helper.Helper.USER_AGENT;
|
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.Helper.urlPattern;
|
||||||
import static app.fedilab.android.helper.ThemeHelper.linkColor;
|
import static app.fedilab.android.helper.ThemeHelper.linkColor;
|
||||||
|
|
||||||
|
@ -25,8 +24,6 @@ import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
@ -38,7 +35,6 @@ import android.text.SpannableStringBuilder;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.TextPaint;
|
import android.text.TextPaint;
|
||||||
import android.text.style.ClickableSpan;
|
import android.text.style.ClickableSpan;
|
||||||
import android.text.style.ImageSpan;
|
|
||||||
import android.text.style.URLSpan;
|
import android.text.style.URLSpan;
|
||||||
import android.util.Patterns;
|
import android.util.Patterns;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -47,16 +43,7 @@ import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
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.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -65,7 +52,6 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
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.Account;
|
||||||
import app.fedilab.android.client.entities.api.Announcement;
|
import app.fedilab.android.client.entities.api.Announcement;
|
||||||
import app.fedilab.android.client.entities.api.Attachment;
|
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.Field;
|
||||||
import app.fedilab.android.client.entities.api.Mention;
|
import app.fedilab.android.client.entities.api.Mention;
|
||||||
import app.fedilab.android.client.entities.api.Poll;
|
import app.fedilab.android.client.entities.api.Poll;
|
||||||
|
@ -95,7 +80,7 @@ public class SpannableHelper {
|
||||||
return convert(context, status, text, true);
|
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
|
* This needs to be run asynchronously
|
||||||
*
|
*
|
||||||
* @param context {@link Context}
|
* @param context {@link Context}
|
||||||
|
@ -138,77 +123,6 @@ public class SpannableHelper {
|
||||||
content.removeSpan(span);
|
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 ----
|
//--- URLs ----
|
||||||
Matcher matcherLink = Patterns.WEB_URL.matcher(content);
|
Matcher matcherLink = Patterns.WEB_URL.matcher(content);
|
||||||
int offSetTruncate = 0;
|
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
|
* This needs to be run asynchronously
|
||||||
*
|
*
|
||||||
* @param context {@link Context}
|
* @param context {@link Context}
|
||||||
|
@ -603,77 +517,6 @@ public class SpannableHelper {
|
||||||
content.removeSpan(span);
|
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 ----
|
//--- URLs ----
|
||||||
Matcher matcherLink = Patterns.WEB_URL.matcher(content);
|
Matcher matcherLink = Patterns.WEB_URL.matcher(content);
|
||||||
int offSetTruncate = 0;
|
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
|
* This needs to be run asynchronously
|
||||||
*
|
*
|
||||||
* @param context {@link Context}
|
* @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
|
* This needs to be run asynchronously
|
||||||
*
|
*
|
||||||
* @param context {@link Context}
|
* @param context {@link Context}
|
||||||
|
@ -1157,75 +1000,6 @@ public class SpannableHelper {
|
||||||
URLSpan[] urls = content.getSpans(0, (content.length() - 1), URLSpan.class);
|
URLSpan[] urls = content.getSpans(0, (content.length() - 1), URLSpan.class);
|
||||||
for (URLSpan span : urls)
|
for (URLSpan span : urls)
|
||||||
content.removeSpan(span);
|
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 ----
|
//--- URLs ----
|
||||||
Matcher matcherALink = Patterns.WEB_URL.matcher(content);
|
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.github.stom79.mytransl.translate.Translate;
|
||||||
import com.varunest.sparkbutton.SparkButton;
|
import com.varunest.sparkbutton.SparkButton;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -117,6 +118,7 @@ import app.fedilab.android.databinding.LayoutMediaBinding;
|
||||||
import app.fedilab.android.databinding.LayoutPollItemBinding;
|
import app.fedilab.android.databinding.LayoutPollItemBinding;
|
||||||
import app.fedilab.android.exception.DBException;
|
import app.fedilab.android.exception.DBException;
|
||||||
import app.fedilab.android.helper.CrossActionHelper;
|
import app.fedilab.android.helper.CrossActionHelper;
|
||||||
|
import app.fedilab.android.helper.CustomEmoji;
|
||||||
import app.fedilab.android.helper.GlideFocus;
|
import app.fedilab.android.helper.GlideFocus;
|
||||||
import app.fedilab.android.helper.Helper;
|
import app.fedilab.android.helper.Helper;
|
||||||
import app.fedilab.android.helper.LongClickLinkMovementMethod;
|
import app.fedilab.android.helper.LongClickLinkMovementMethod;
|
||||||
|
@ -253,6 +255,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
||||||
statusToDeal.bookmarked = statusReturned.bookmarked;
|
statusToDeal.bookmarked = statusReturned.bookmarked;
|
||||||
statusToDeal.reblogs_count = statusReturned.reblogs_count;
|
statusToDeal.reblogs_count = statusReturned.reblogs_count;
|
||||||
statusToDeal.favourites_count = statusReturned.favourites_count;
|
statusToDeal.favourites_count = statusReturned.favourites_count;
|
||||||
|
|
||||||
//Update status in cache if not a remote instance
|
//Update status in cache if not a remote instance
|
||||||
if (!remote) {
|
if (!remote) {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
|
@ -370,6 +373,10 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
||||||
holder.binding.actionButtonBookmark.setActiveImageTint(R.color.marked_icon);
|
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) {
|
if (status.pinned) {
|
||||||
holder.binding.statusPinned.setVisibility(View.VISIBLE);
|
holder.binding.statusPinned.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} 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