Show image flairs properly. Minor bugs fixed.

This commit is contained in:
Alex Ning 2020-02-19 21:18:08 +08:00
parent 2a077afa43
commit bbc69b45e6
5 changed files with 188 additions and 14 deletions

View File

@ -6,6 +6,8 @@ import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.text.Html;
import android.text.Spannable;
import android.text.Spanned;
import android.text.style.SuperscriptSpan;
import android.text.util.Linkify;
@ -81,6 +83,7 @@ import ml.docilealligator.infinityforreddit.Post.PostDataSource;
import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;
import ml.docilealligator.infinityforreddit.SaveThing;
import ml.docilealligator.infinityforreddit.Utils.GlideImageGetter;
import ml.docilealligator.infinityforreddit.Utils.RedditUtils;
import ml.docilealligator.infinityforreddit.Utils.Utils;
import ml.docilealligator.infinityforreddit.VoteThing;
@ -704,7 +707,14 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy
if (comment.getAuthorFlair() != null && !comment.getAuthorFlair().equals("")) {
((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE);
((CommentViewHolder) holder).authorFlairTextView.setText(comment.getAuthorFlair());
Spannable flairHTML;
GlideImageGetter glideImageGetter = new GlideImageGetter(((CommentViewHolder) holder).authorFlairTextView);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
flairHTML = (Spannable) Html.fromHtml(comment.getAuthorFlair(), Html.FROM_HTML_MODE_LEGACY, glideImageGetter, null);
} else {
flairHTML = (Spannable) Html.fromHtml(comment.getAuthorFlair(), glideImageGetter, null);
}
((CommentViewHolder) holder).authorFlairTextView.setText(flairHTML);
((CommentViewHolder) holder).authorFlairTextView.setOnClickListener(view -> ((CommentViewHolder) holder).authorTextView.performClick());
}

View File

@ -118,11 +118,18 @@ public class ParseComment {
String id = singleCommentData.getString(JSONUtils.ID_KEY);
String fullName = singleCommentData.getString(JSONUtils.NAME_KEY);
String author = singleCommentData.getString(JSONUtils.AUTHOR_KEY);
String authorFlair;
if (!singleCommentData.has(JSONUtils.AUTHOR_FLAIR_TEXT_KEY) || singleCommentData.isNull(JSONUtils.AUTHOR_FLAIR_TEXT_KEY)) {
authorFlair = "";
} else {
authorFlair = singleCommentData.getString(JSONUtils.AUTHOR_FLAIR_TEXT_KEY);
StringBuilder authorFlairHTMLBuilder = new StringBuilder();
if (singleCommentData.has(JSONUtils.AUTHOR_FLAIR_RICHTEXT_KEY)) {
JSONArray flairArray = singleCommentData.getJSONArray(JSONUtils.AUTHOR_FLAIR_RICHTEXT_KEY);
for (int i = 0; i < flairArray.length(); i++) {
JSONObject flairObject = flairArray.getJSONObject(i);
String e = flairObject.getString(JSONUtils.E_KEY);
if (e.equals("text")) {
authorFlairHTMLBuilder.append(flairObject.getString(JSONUtils.T_KEY));
} else if (e.equals("emoji")) {
authorFlairHTMLBuilder.append("<img src=\"").append(flairObject.getString(JSONUtils.U_KEY)).append("\">");
}
}
}
String linkAuthor = singleCommentData.has(JSONUtils.LINK_AUTHOR_KEY) ? singleCommentData.getString(JSONUtils.LINK_AUTHOR_KEY) : null;
String linkId = singleCommentData.getString(JSONUtils.LINK_ID_KEY).substring(3);
@ -161,10 +168,10 @@ public class ParseComment {
boolean collapsed = singleCommentData.getBoolean(JSONUtils.COLLAPSED_KEY);
boolean hasReply = !(singleCommentData.get(JSONUtils.REPLIES_KEY) instanceof String);
return new CommentData(id, fullName, author, authorFlair, linkAuthor, formattedSubmitTime,
submitTime, commentMarkdown, commentRawText, linkId, subredditName, parentId, score,
voteType, isSubmitter, distinguished, permalink, depth, collapsed, hasReply,
scoreHidden, saved);
return new CommentData(id, fullName, author, authorFlairHTMLBuilder.toString(), linkAuthor,
formattedSubmitTime, submitTime, commentMarkdown, commentRawText, linkId, subredditName,
parentId, score, voteType, isSubmitter, distinguished, permalink, depth, collapsed,
hasReply, scoreHidden, saved);
}
@Nullable

View File

@ -0,0 +1,157 @@
package ml.docilealligator.infinityforreddit.Utils;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.Request;
import com.bumptech.glide.request.target.SizeReadyCallback;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;
import java.lang.ref.WeakReference;
public class GlideImageGetter implements Html.ImageGetter {
private WeakReference<TextView> container;
private boolean matchParentWidth;
private HtmlImagesHandler imagesHandler;
private float density = 1.0f;
private float textSize;
public GlideImageGetter(TextView textView) {
this(textView, false, false, null);
}
public GlideImageGetter(TextView textView, boolean matchParentWidth, HtmlImagesHandler imagesHandler) {
this(textView, matchParentWidth, false, imagesHandler);
}
public GlideImageGetter(TextView textView, boolean matchParentWidth, boolean densityAware,
@Nullable HtmlImagesHandler imagesHandler) {
this.container = new WeakReference<>(textView);
this.matchParentWidth = matchParentWidth;
this.imagesHandler = imagesHandler;
if (densityAware) {
density = container.get().getResources().getDisplayMetrics().density;
}
textSize = container.get().getTextSize();
}
@Override
public Drawable getDrawable(String source) {
if (imagesHandler != null) {
imagesHandler.addImage(source);
}
BitmapDrawablePlaceholder drawable = new BitmapDrawablePlaceholder(textSize);
container.get().post(() -> Glide.with(container.get().getContext())
.asBitmap()
.load(source)
.into(drawable));
return drawable;
}
private class BitmapDrawablePlaceholder extends BitmapDrawable implements Target<Bitmap> {
protected Drawable drawable;
BitmapDrawablePlaceholder(float textSize) {
super(container.get().getResources(),
Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888));
}
@Override
public void draw(final Canvas canvas) {
if (drawable != null) {
drawable.draw(canvas);
}
}
private void setDrawable(Drawable drawable) {
this.drawable = drawable;
int drawableWidth = (int) (drawable.getIntrinsicWidth() * density);
int drawableHeight = (int) (drawable.getIntrinsicHeight() * density);
float ratio = (float) drawableWidth / (float) drawableHeight;
drawableHeight = (int) textSize + 10;
drawableWidth = (int) (drawableHeight * ratio);
int maxWidth = container.get().getMeasuredWidth();
if ((drawableWidth > maxWidth) || matchParentWidth) {
int calculatedHeight = maxWidth * drawableHeight / drawableWidth;
drawable.setBounds(0, 0, maxWidth, calculatedHeight);
setBounds(0, 0, maxWidth, calculatedHeight);
} else {
drawable.setBounds(0, 0, drawableWidth, drawableHeight);
setBounds(0, 0, drawableWidth, drawableHeight);
}
container.get().setText(container.get().getText());
}
@Override
public void onLoadStarted(@Nullable Drawable placeholderDrawable) {
if(placeholderDrawable != null) {
setDrawable(placeholderDrawable);
}
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
if (errorDrawable != null) {
setDrawable(errorDrawable);
}
}
@Override
public void onResourceReady(@NonNull Bitmap bitmap, @Nullable Transition<? super Bitmap> transition) {
setDrawable(new BitmapDrawable(container.get().getResources(), bitmap));
}
@Override
public void onLoadCleared(@Nullable Drawable placeholderDrawable) {
if(placeholderDrawable != null) {
setDrawable(placeholderDrawable);
}
}
@Override
public void getSize(@NonNull SizeReadyCallback cb) {
cb.onSizeReady(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
}
@Override
public void removeCallback(@NonNull SizeReadyCallback cb) {}
@Override
public void setRequest(@Nullable Request request) {}
@Nullable
@Override
public Request getRequest() {
return null;
}
@Override
public void onStart() {}
@Override
public void onStop() {}
@Override
public void onDestroy() {}
}
public interface HtmlImagesHandler {
void addImage(String uri);
}
}

View File

@ -17,6 +17,10 @@ public class JSONUtils {
public static final String SELFTEXT_HTML_KEY = "selftext_html";
public static final String AUTHOR_KEY = "author";
public static final String AUTHOR_FLAIR_TEXT_KEY = "author_flair_text";
public static final String AUTHOR_FLAIR_RICHTEXT_KEY = "author_flair_richtext";
public static final String E_KEY = "e";
public static final String T_KEY = "t";
public static final String U_KEY = "u";
public static final String LINK_AUTHOR_KEY = "link_author";
public static final String LINK_FLAIR_TEXT_KEY = "link_flair_text";
public static final String SCORE_KEY = "score";
@ -29,9 +33,6 @@ public class JSONUtils {
public static final String IMAGES_KEY = "images";
public static final String WIDTH_KEY = "width";
public static final String HEIGHT_KEY = "height";
public static final String VARIANTS_KEY = "variants";
public static final String GIF_KEY = "gif";
public static final String MP4_KEY = "mp4";
public static final String SOURCE_KEY = "source";
public static final String URL_KEY = "url";
public static final String MEDIA_KEY = "media";

View File

@ -14,7 +14,6 @@
android:layout_height="match_parent" />
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"