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.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.text.Html;
import android.text.Spannable;
import android.text.Spanned; import android.text.Spanned;
import android.text.style.SuperscriptSpan; import android.text.style.SuperscriptSpan;
import android.text.util.Linkify; import android.text.util.Linkify;
@ -81,6 +83,7 @@ import ml.docilealligator.infinityforreddit.Post.PostDataSource;
import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;
import ml.docilealligator.infinityforreddit.SaveThing; import ml.docilealligator.infinityforreddit.SaveThing;
import ml.docilealligator.infinityforreddit.Utils.GlideImageGetter;
import ml.docilealligator.infinityforreddit.Utils.RedditUtils; import ml.docilealligator.infinityforreddit.Utils.RedditUtils;
import ml.docilealligator.infinityforreddit.Utils.Utils; import ml.docilealligator.infinityforreddit.Utils.Utils;
import ml.docilealligator.infinityforreddit.VoteThing; import ml.docilealligator.infinityforreddit.VoteThing;
@ -704,7 +707,14 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<Recy
if (comment.getAuthorFlair() != null && !comment.getAuthorFlair().equals("")) { if (comment.getAuthorFlair() != null && !comment.getAuthorFlair().equals("")) {
((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); ((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()); ((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 id = singleCommentData.getString(JSONUtils.ID_KEY);
String fullName = singleCommentData.getString(JSONUtils.NAME_KEY); String fullName = singleCommentData.getString(JSONUtils.NAME_KEY);
String author = singleCommentData.getString(JSONUtils.AUTHOR_KEY); String author = singleCommentData.getString(JSONUtils.AUTHOR_KEY);
String authorFlair; StringBuilder authorFlairHTMLBuilder = new StringBuilder();
if (!singleCommentData.has(JSONUtils.AUTHOR_FLAIR_TEXT_KEY) || singleCommentData.isNull(JSONUtils.AUTHOR_FLAIR_TEXT_KEY)) { if (singleCommentData.has(JSONUtils.AUTHOR_FLAIR_RICHTEXT_KEY)) {
authorFlair = ""; JSONArray flairArray = singleCommentData.getJSONArray(JSONUtils.AUTHOR_FLAIR_RICHTEXT_KEY);
} else { for (int i = 0; i < flairArray.length(); i++) {
authorFlair = singleCommentData.getString(JSONUtils.AUTHOR_FLAIR_TEXT_KEY); 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 linkAuthor = singleCommentData.has(JSONUtils.LINK_AUTHOR_KEY) ? singleCommentData.getString(JSONUtils.LINK_AUTHOR_KEY) : null;
String linkId = singleCommentData.getString(JSONUtils.LINK_ID_KEY).substring(3); 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 collapsed = singleCommentData.getBoolean(JSONUtils.COLLAPSED_KEY);
boolean hasReply = !(singleCommentData.get(JSONUtils.REPLIES_KEY) instanceof String); boolean hasReply = !(singleCommentData.get(JSONUtils.REPLIES_KEY) instanceof String);
return new CommentData(id, fullName, author, authorFlair, linkAuthor, formattedSubmitTime, return new CommentData(id, fullName, author, authorFlairHTMLBuilder.toString(), linkAuthor,
submitTime, commentMarkdown, commentRawText, linkId, subredditName, parentId, score, formattedSubmitTime, submitTime, commentMarkdown, commentRawText, linkId, subredditName,
voteType, isSubmitter, distinguished, permalink, depth, collapsed, hasReply, parentId, score, voteType, isSubmitter, distinguished, permalink, depth, collapsed,
scoreHidden, saved); hasReply, scoreHidden, saved);
} }
@Nullable @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 SELFTEXT_HTML_KEY = "selftext_html";
public static final String AUTHOR_KEY = "author"; public static final String AUTHOR_KEY = "author";
public static final String AUTHOR_FLAIR_TEXT_KEY = "author_flair_text"; 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_AUTHOR_KEY = "link_author";
public static final String LINK_FLAIR_TEXT_KEY = "link_flair_text"; public static final String LINK_FLAIR_TEXT_KEY = "link_flair_text";
public static final String SCORE_KEY = "score"; 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 IMAGES_KEY = "images";
public static final String WIDTH_KEY = "width"; public static final String WIDTH_KEY = "width";
public static final String HEIGHT_KEY = "height"; 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 SOURCE_KEY = "source";
public static final String URL_KEY = "url"; public static final String URL_KEY = "url";
public static final String MEDIA_KEY = "media"; public static final String MEDIA_KEY = "media";

View File

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