From afb9274ecdf3c5b0c5088fae15a811cac7217016 Mon Sep 17 00:00:00 2001 From: bharatknv Date: Sat, 1 Apr 2023 23:45:30 +0530 Subject: [PATCH 1/5] Add support for emotes in flairs --- .../redreader/common/BetterSSB.java | 39 +++++- .../redreader/reddit/kthings/RedditComment.kt | 29 ++++ .../reddit/prepared/RedditParsedComment.java | 126 +++++++++++++++++- .../prepared/RedditPreparedMessage.java | 9 +- .../prepared/RedditRenderableComment.java | 37 ++--- .../RedditRenderableCommentListItem.java | 3 +- .../redreader/views/RedditCommentView.java | 27 +++- .../redreader/views/RedditInboxItemView.java | 2 +- 8 files changed, 243 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/quantumbadger/redreader/common/BetterSSB.java b/src/main/java/org/quantumbadger/redreader/common/BetterSSB.java index 66404c506..2fd6d8eb8 100644 --- a/src/main/java/org/quantumbadger/redreader/common/BetterSSB.java +++ b/src/main/java/org/quantumbadger/redreader/common/BetterSSB.java @@ -20,6 +20,7 @@ import android.graphics.Typeface; import android.text.SpannableStringBuilder; import android.text.Spanned; +import android.text.TextUtils; import android.text.style.BackgroundColorSpan; import android.text.style.ForegroundColorSpan; import android.text.style.RelativeSizeSpan; @@ -32,8 +33,9 @@ import androidx.annotation.NonNull; import java.util.HashSet; +import java.util.Observable; -public class BetterSSB { +public class BetterSSB extends Observable { private final SpannableStringBuilder sb; @@ -178,6 +180,41 @@ public void linkify() { } } + public void append(final CharSequence text) { + this.sb.append(text); + this.setChanged(); + this.notifyObservers(this.sb); + } + + public void replace(final int start, final int end, final CharSequence text) { + this.sb.replace(start, end, text); + this.setChanged(); + this.notifyObservers(this.sb); + } + + public void replace(final CharSequence textToBeReplaced, final Object replacement) { + final int textStartIndex = TextUtils.indexOf(this.sb, textToBeReplaced); + + this.sb.setSpan(replacement, + textStartIndex, + textStartIndex + textToBeReplaced.length(), + Spanned.SPAN_INCLUSIVE_EXCLUSIVE); + + this.setChanged(); + this.notifyObservers(this.sb); + } + + public boolean isEmpty() { + return this.sb.length() == 0; + } + + public void setSpan(final Object what, final int start, final int end, final int flag) { + this.sb.setSpan(what, start, end, flag); + + this.setChanged(); + this.notifyObservers(this.sb); + } + public SpannableStringBuilder get() { return sb; } diff --git a/src/main/java/org/quantumbadger/redreader/reddit/kthings/RedditComment.kt b/src/main/java/org/quantumbadger/redreader/reddit/kthings/RedditComment.kt index 09ea7b784..e4fd3a0a1 100644 --- a/src/main/java/org/quantumbadger/redreader/reddit/kthings/RedditComment.kt +++ b/src/main/java/org/quantumbadger/redreader/reddit/kthings/RedditComment.kt @@ -23,6 +23,7 @@ import kotlinx.parcelize.Parcelize import kotlinx.serialization.Serializable import org.quantumbadger.redreader.common.LinkHandler import org.quantumbadger.redreader.common.UriString +import org.quantumbadger.redreader.jsonwrap.JsonValue import org.quantumbadger.redreader.reddit.things.RedditThingWithIdAndType import org.quantumbadger.redreader.reddit.url.PostCommentListingURL @@ -39,6 +40,7 @@ data class RedditComment( val author: UrlEncodedString? = null, val subreddit: UrlEncodedString? = null, val author_flair_text: UrlEncodedString? = null, + val author_flair_richtext: List>?= null, val archived: Boolean = false, val likes: Boolean? = null, val score_hidden: Boolean = false, @@ -77,6 +79,33 @@ data class RedditComment( // TODO do this in the HTML parser instead fun copyWithNewBodyHtml(value: String) = copy(body_html = UrlEncodedString(value)) + @Serializable + @Parcelize + data class EmoteMetadata( + val status: String, + val e: String, + val m: String, + val s: ImageMetadata, + val t: String, + val id: String + ) : Parcelable + + @Serializable + @Parcelize + data class ImageMetadata( + val x: String, + val y: String, + val u: String? = null + ) : Parcelable + + @Serializable + @Parcelize + data class FlairEmoteData( + val e: String, + val a: String, + val u: String + ) : Parcelable + override fun getIdAlone() = id override fun getIdAndType() = name diff --git a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java index 9532fa6f9..5d0e0cab5 100644 --- a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java +++ b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java @@ -17,8 +17,28 @@ package org.quantumbadger.redreader.reddit.prepared; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.text.style.ImageSpan; + import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; + +import org.quantumbadger.redreader.account.RedditAccountManager; +import org.quantumbadger.redreader.cache.CacheManager; +import org.quantumbadger.redreader.cache.CacheRequest; +import org.quantumbadger.redreader.cache.CacheRequestCallbacks; +import org.quantumbadger.redreader.cache.downloadstrategy.DownloadStrategyIfNotCached; +import org.quantumbadger.redreader.common.BetterSSB; +import org.quantumbadger.redreader.common.Constants; +import org.quantumbadger.redreader.common.General; +import org.quantumbadger.redreader.common.GenericFactory; +import org.quantumbadger.redreader.common.Optional; +import org.quantumbadger.redreader.common.Priority; +import org.quantumbadger.redreader.common.datastream.SeekableInputStream; +import org.quantumbadger.redreader.http.FailedRequestBody; +import org.quantumbadger.redreader.reddit.kthings.MaybeParseError; import org.quantumbadger.redreader.reddit.kthings.RedditComment; import org.quantumbadger.redreader.reddit.kthings.RedditIdAndType; import org.quantumbadger.redreader.reddit.kthings.UrlEncodedString; @@ -26,12 +46,19 @@ import org.quantumbadger.redreader.reddit.prepared.html.HtmlReader; import org.quantumbadger.redreader.reddit.things.RedditThingWithIdAndType; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.UUID; + public class RedditParsedComment implements RedditThingWithIdAndType { private final RedditComment mSrc; @NonNull private final BodyElement mBody; + private final BetterSSB mFlair; + public RedditParsedComment( final RedditComment comment, final AppCompatActivity activity) { @@ -41,6 +68,21 @@ public RedditParsedComment( mBody = HtmlReader.parse( comment.getBody_html().getDecoded(), // TODO nullable? activity); + + final String flair = General.mapIfNotNull( + comment.getAuthor_flair_text(), + UrlEncodedString::getDecoded); + + if(flair != null) { + mFlair = new BetterSSB(); + mFlair.append(flair); + + if (comment.getAuthor_flair_richtext() != null) { + getFlairEmotes(comment.getAuthor_flair_richtext(), activity); + } + } else { + mFlair = null; + } } @NonNull @@ -48,8 +90,8 @@ public BodyElement getBody() { return mBody; } - public UrlEncodedString getFlair() { - return mSrc.getAuthor_flair_text(); + public BetterSSB getFlair() { + return mFlair; } @Override @@ -65,4 +107,84 @@ public RedditIdAndType getIdAndType() { public RedditComment getRawComment() { return mSrc; } + + private void getFlairEmotes( + final List> flairRichtext, + final AppCompatActivity activity) { + for (final MaybeParseError flairEmoteData : flairRichtext) { + if (!(flairEmoteData instanceof MaybeParseError.Ok)) { + continue; + } + + final RedditComment.FlairEmoteData flairEmoteObject = + ((MaybeParseError.Ok< RedditComment.FlairEmoteData >) flairEmoteData) + .getValue(); + + final String objectType = flairEmoteObject.getE(); + + if (objectType != null && objectType.equals("emoji")) { + final String placeholder = flairEmoteObject.getA(); + final String url = flairEmoteObject.getU(); + + CacheManager.getInstance(activity).makeRequest(new CacheRequest( + General.uriFromString(url), + RedditAccountManager.getAnon(), + null, + new Priority(Constants.Priority.API_COMMENT_LIST), + DownloadStrategyIfNotCached.INSTANCE, + Constants.FileType.IMAGE, + CacheRequest.DOWNLOAD_QUEUE_IMMEDIATE, + activity, + new CacheRequestCallbacks() { + Bitmap image = null; + + @Override + public void onDataStreamComplete( + @NonNull final GenericFactory + stream, + final long timestamp, + @NonNull final UUID session, + final boolean fromCache, + @Nullable final String mimetype) { + try (InputStream is = stream.create()) { + image = BitmapFactory.decodeStream(is); + + image = Bitmap.createScaledBitmap(image, + image.getWidth() / 2, + image.getHeight() / 2, + true); + + if (image == null) { + throw new IOException("Failed to decode bitmap"); + } + + final ImageSpan span = new ImageSpan( + activity.getApplicationContext(), + image); + + mFlair.replace(placeholder, span); + } catch (final Throwable t) { + onFailure( + CacheRequest.REQUEST_FAILURE_CONNECTION, + t, + null, + "Exception while downloading emote", + Optional.empty()); + } + } + + @Override + public void onFailure( + final int type, + @Nullable final Throwable t, + @Nullable final Integer httpStatus, + @Nullable final String readableMessage, + @NonNull final Optional body) { + + } + } + )); + } + } + } } diff --git a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditPreparedMessage.java b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditPreparedMessage.java index 219787bfe..e1f66c750 100644 --- a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditPreparedMessage.java +++ b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditPreparedMessage.java @@ -21,7 +21,6 @@ import android.content.Intent; import android.content.res.TypedArray; import android.graphics.Typeface; -import android.text.SpannableStringBuilder; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; @@ -53,7 +52,7 @@ public final class RedditPreparedMessage implements RedditRenderableInboxItem { - public final SpannableStringBuilder header; + public final BetterSSB header; public final BodyElement body; public final RedditIdAndType idAndType; public final RedditMessage src; @@ -141,10 +140,10 @@ public RedditPreparedMessage( 0, 1f); - header = sb.get(); + header = sb; } - public SpannableStringBuilder getHeader() { + public BetterSSB getHeader() { return header; } @@ -183,7 +182,7 @@ public void handleInboxLongClick(final BaseActivity activity) { } @Override - public CharSequence getHeader( + public BetterSSB getHeader( final RRThemeAttributes theme, final RedditChangeDataManager changeDataManager, final Context context, diff --git a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditRenderableComment.java b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditRenderableComment.java index 867b08fa3..99f23382f 100644 --- a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditRenderableComment.java +++ b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditRenderableComment.java @@ -19,6 +19,7 @@ import android.content.Context; import android.graphics.Color; +import android.text.SpannableStringBuilder; import android.view.View; import androidx.annotation.NonNull; @@ -43,9 +44,11 @@ import org.quantumbadger.redreader.reddit.api.RedditAPICommentAction; import org.quantumbadger.redreader.reddit.kthings.RedditComment; import org.quantumbadger.redreader.reddit.kthings.RedditIdAndType; -import org.quantumbadger.redreader.reddit.kthings.UrlEncodedString; import org.quantumbadger.redreader.reddit.things.RedditThingWithIdAndType; +import java.net.URI; +import java.util.Observer; + public class RedditRenderableComment implements RedditRenderableInboxItem, RedditThingWithIdAndType { @@ -103,7 +106,7 @@ private int computeScore(final RedditChangeDataManager changeDataManager) { } @Override - public CharSequence getHeader( + public BetterSSB getHeader( final RRThemeAttributes theme, final RedditChangeDataManager changeDataManager, final Context context, @@ -183,9 +186,7 @@ public CharSequence getHeader( } } - final String flair = General.mapIfNotNull( - mComment.getFlair(), - UrlEncodedString::getDecoded); + final BetterSSB flair = mComment.getFlair(); if(theme.shouldShow(PrefsUtility.AppearanceCommentHeaderItem.FLAIR) && flair != null && !flair.isEmpty()) { @@ -194,12 +195,18 @@ public CharSequence getHeader( sb.append(" ", 0); } - sb.append( - " " + flair + General.LTR_OVERRIDE_MARK + " ", - BetterSSB.FOREGROUND_COLOR | BetterSSB.BACKGROUND_COLOR, - theme.rrFlairTextCol, - theme.rrFlairBackCol, - 1f); + final int flairStartIndex = sb.get().length(); + + sb.append(flair.get()); + + final int flairEndIndex = sb.get().length(); + + final Observer observer = (observable, o) -> sb.replace( + flairStartIndex, + flairEndIndex, + (SpannableStringBuilder) o); + + flair.addObserver(observer); } if(theme.shouldShow(PrefsUtility.AppearanceCommentHeaderItem.AUTHOR) @@ -308,7 +315,7 @@ public CharSequence getHeader( 1f); } - return sb.get(); + return sb; } @Override @@ -409,9 +416,7 @@ public String getAccessibilityHeader( .append(separator); } - final String flair = General.mapIfNotNull( - mComment.getFlair(), - UrlEncodedString::getDecoded); + final BetterSSB flair = mComment.getFlair(); if(theme.shouldShow(PrefsUtility.AppearanceCommentHeaderItem.FLAIR) && flair != null @@ -422,7 +427,7 @@ public String getAccessibilityHeader( accessibilityConciseMode ? R.string.accessibility_subtitle_flair_withperiod_concise : R.string.accessibility_subtitle_flair_withperiod, - flair + General.LTR_OVERRIDE_MARK)) + flair.get() + General.LTR_OVERRIDE_MARK)) .append(separator); } diff --git a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditRenderableCommentListItem.java b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditRenderableCommentListItem.java index e930f1bf8..efa5c37d5 100644 --- a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditRenderableCommentListItem.java +++ b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditRenderableCommentListItem.java @@ -24,13 +24,14 @@ import androidx.annotation.Nullable; import org.quantumbadger.redreader.activities.BaseActivity; +import org.quantumbadger.redreader.common.BetterSSB; import org.quantumbadger.redreader.common.Optional; import org.quantumbadger.redreader.common.RRThemeAttributes; import org.quantumbadger.redreader.common.time.TimestampUTC; public interface RedditRenderableCommentListItem { - CharSequence getHeader( + BetterSSB getHeader( final RRThemeAttributes theme, final RedditChangeDataManager changeDataManager, final Context context, diff --git a/src/main/java/org/quantumbadger/redreader/views/RedditCommentView.java b/src/main/java/org/quantumbadger/redreader/views/RedditCommentView.java index 6cd782204..f309b124f 100644 --- a/src/main/java/org/quantumbadger/redreader/views/RedditCommentView.java +++ b/src/main/java/org/quantumbadger/redreader/views/RedditCommentView.java @@ -18,6 +18,7 @@ package org.quantumbadger.redreader.views; import android.content.Context; +import android.text.SpannableStringBuilder; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; @@ -33,6 +34,8 @@ import org.quantumbadger.redreader.account.RedditAccount; import org.quantumbadger.redreader.account.RedditAccountManager; import org.quantumbadger.redreader.activities.BaseActivity; +import org.quantumbadger.redreader.common.AndroidCommon; +import org.quantumbadger.redreader.common.BetterSSB; import org.quantumbadger.redreader.common.General; import org.quantumbadger.redreader.common.Optional; import org.quantumbadger.redreader.common.PrefsUtility; @@ -46,6 +49,8 @@ import org.quantumbadger.redreader.reddit.prepared.RedditParsedComment; import org.quantumbadger.redreader.reddit.prepared.RedditRenderableComment; +import java.util.Observer; + public class RedditCommentView extends FlingableItemView implements RedditChangeDataManager.Listener { @@ -68,6 +73,8 @@ public class RedditCommentView extends FlingableItemView private final boolean mShowLinkButtons; + private CharSequence mHeaderText; + private final CommentListener mListener; @Nullable @@ -428,7 +435,7 @@ public void reset( final boolean isCollapsed = mComment.isCollapsed(mChangeDataManager); - final CharSequence headerText = renderableComment.getHeader( + final BetterSSB header = renderableComment.getHeader( mTheme, mChangeDataManager, activity, @@ -436,6 +443,20 @@ public void reset( postTimestamp, parentCommentTimestamp); + final Observer observer = (observable, o) -> { + if (isCollapsed) { + mHeaderText = "[ + ] " + o; + } else { + mHeaderText = (SpannableStringBuilder) o; + } + + AndroidCommon.runOnUiThread(() -> mHeader.setText(mHeaderText)); + }; + + header.addObserver(observer); + + mHeaderText = header.get(); + mHeader.setContentDescription(renderableComment.getAccessibilityHeader( mTheme, mChangeDataManager, @@ -450,12 +471,12 @@ public void reset( setFlingingEnabled(false); //noinspection SetTextI18n mHeader.setText("[ + ] " - + headerText); // Note that this removes formatting (which is fine) + + mHeaderText); // Note that this removes formatting (which is fine) mBodyHolder.setVisibility(GONE); } else { setFlingingEnabled(true); - mHeader.setText(headerText); + mHeader.setText(mHeaderText); mBodyHolder.setVisibility(VISIBLE); } diff --git a/src/main/java/org/quantumbadger/redreader/views/RedditInboxItemView.java b/src/main/java/org/quantumbadger/redreader/views/RedditInboxItemView.java index 3a4717d10..154470677 100644 --- a/src/main/java/org/quantumbadger/redreader/views/RedditInboxItemView.java +++ b/src/main/java/org/quantumbadger/redreader/views/RedditInboxItemView.java @@ -114,7 +114,7 @@ public void reset( context, PrefsUtility.appearance_inbox_age_units(), null, - null)); + null).get()); mHeader.setContentDescription(item.getAccessibilityHeader( theme, From c111015f42ebdeaa88bc9b09f15dc96313c3fd66 Mon Sep 17 00:00:00 2001 From: bharatknv Date: Sat, 15 Apr 2023 21:37:58 +0530 Subject: [PATCH 2/5] Limit height of emotes in comment flair and body --- .../reddit/prepared/RedditParsedComment.java | 33 ++++++++++++++++--- .../prepared/html/HtmlRawElementImg.java | 26 +++++++++++++++ 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java index 5d0e0cab5..8753e1ec5 100644 --- a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java +++ b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java @@ -20,6 +20,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.text.style.ImageSpan; +import android.util.TypedValue; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -35,6 +36,7 @@ import org.quantumbadger.redreader.common.General; import org.quantumbadger.redreader.common.GenericFactory; import org.quantumbadger.redreader.common.Optional; +import org.quantumbadger.redreader.common.PrefsUtility; import org.quantumbadger.redreader.common.Priority; import org.quantumbadger.redreader.common.datastream.SeekableInputStream; import org.quantumbadger.redreader.http.FailedRequestBody; @@ -149,10 +151,33 @@ public void onDataStreamComplete( try (InputStream is = stream.create()) { image = BitmapFactory.decodeStream(is); - image = Bitmap.createScaledBitmap(image, - image.getWidth() / 2, - image.getHeight() / 2, - true); + if (image == null) { + throw new IOException("Failed to decode bitmap"); + } + + final int textSize = 11; + final float maxImageHeightMultiple = 2.0F; + + final float maxHeight = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_SP, + PrefsUtility.appearance_fontscale_comment_headers() + * textSize + * maxImageHeightMultiple, + activity.getApplicationContext() + .getResources() + .getDisplayMetrics()); + + if (image.getHeight() > maxHeight) { + final float imageAspectRatio = + (float) image.getHeight() / image.getWidth(); + + final float newImageWidth = maxHeight / imageAspectRatio; + + image = Bitmap.createScaledBitmap(image, + Math.round(newImageWidth), + Math.round(maxHeight), + true); + } if (image == null) { throw new IOException("Failed to decode bitmap"); diff --git a/src/main/java/org/quantumbadger/redreader/reddit/prepared/html/HtmlRawElementImg.java b/src/main/java/org/quantumbadger/redreader/reddit/prepared/html/HtmlRawElementImg.java index 71db9f635..ecab2cc69 100644 --- a/src/main/java/org/quantumbadger/redreader/reddit/prepared/html/HtmlRawElementImg.java +++ b/src/main/java/org/quantumbadger/redreader/reddit/prepared/html/HtmlRawElementImg.java @@ -22,6 +22,7 @@ import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.ImageSpan; +import android.util.TypedValue; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -36,6 +37,7 @@ import org.quantumbadger.redreader.common.General; import org.quantumbadger.redreader.common.GenericFactory; import org.quantumbadger.redreader.common.Optional; +import org.quantumbadger.redreader.common.PrefsUtility; import org.quantumbadger.redreader.common.Priority; import org.quantumbadger.redreader.common.RRError; import org.quantumbadger.redreader.common.UriString; @@ -105,6 +107,30 @@ public void onDataStreamComplete( throw new IOException("Failed to decode bitmap"); } + final int textSize = 18; + final float maxImageHeightMultiple = 2.0F; + + final float maxHeight = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_SP, + PrefsUtility.appearance_fontscale_comment_headers() + * textSize + * maxImageHeightMultiple, + activity.getApplicationContext() + .getResources() + .getDisplayMetrics()); + + if (image.getHeight() > maxHeight) { + final float imageAspectRatio = + (float) image.getHeight() / image.getWidth(); + + final float newImageWidth = maxHeight / imageAspectRatio; + + image = Bitmap.createScaledBitmap(image, + Math.round(newImageWidth), + Math.round(maxHeight), + true); + } + final ImageSpan span = new ImageSpan( activity.getApplicationContext(), image); From 490bb1b3e1cb6ce4be7eab089d4ba67e4d375d55 Mon Sep 17 00:00:00 2001 From: QuantumBadger Date: Sun, 20 Apr 2025 13:05:48 +0100 Subject: [PATCH 3/5] Build fixes (#1054) --- .../redreader/common/BetterSSB.java | 4 +- .../reddit/prepared/RedditParsedComment.java | 41 ++++++++++--------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/quantumbadger/redreader/common/BetterSSB.java b/src/main/java/org/quantumbadger/redreader/common/BetterSSB.java index 2fd6d8eb8..ee7f9da6a 100644 --- a/src/main/java/org/quantumbadger/redreader/common/BetterSSB.java +++ b/src/main/java/org/quantumbadger/redreader/common/BetterSSB.java @@ -192,7 +192,9 @@ public void replace(final int start, final int end, final CharSequence text) { this.notifyObservers(this.sb); } - public void replace(final CharSequence textToBeReplaced, final Object replacement) { + public void replace( + @NonNull final CharSequence textToBeReplaced, + @NonNull final Object replacement) { final int textStartIndex = TextUtils.indexOf(this.sb, textToBeReplaced); this.sb.setSpan(replacement, diff --git a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java index 8753e1ec5..f969c8cd8 100644 --- a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java +++ b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java @@ -20,6 +20,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.text.style.ImageSpan; +import android.util.Log; import android.util.TypedValue; import androidx.annotation.NonNull; @@ -35,11 +36,12 @@ import org.quantumbadger.redreader.common.Constants; import org.quantumbadger.redreader.common.General; import org.quantumbadger.redreader.common.GenericFactory; -import org.quantumbadger.redreader.common.Optional; import org.quantumbadger.redreader.common.PrefsUtility; import org.quantumbadger.redreader.common.Priority; +import org.quantumbadger.redreader.common.RRError; +import org.quantumbadger.redreader.common.UriString; import org.quantumbadger.redreader.common.datastream.SeekableInputStream; -import org.quantumbadger.redreader.http.FailedRequestBody; +import org.quantumbadger.redreader.common.time.TimestampUTC; import org.quantumbadger.redreader.reddit.kthings.MaybeParseError; import org.quantumbadger.redreader.reddit.kthings.RedditComment; import org.quantumbadger.redreader.reddit.kthings.RedditIdAndType; @@ -122,20 +124,20 @@ private void getFlairEmotes( ((MaybeParseError.Ok< RedditComment.FlairEmoteData >) flairEmoteData) .getValue(); - final String objectType = flairEmoteObject.getE(); + @NonNull final String objectType = flairEmoteObject.getE(); - if (objectType != null && objectType.equals("emoji")) { + if (objectType.equals("emoji")) { final String placeholder = flairEmoteObject.getA(); final String url = flairEmoteObject.getU(); CacheManager.getInstance(activity).makeRequest(new CacheRequest( - General.uriFromString(url), + new UriString(url), RedditAccountManager.getAnon(), null, new Priority(Constants.Priority.API_COMMENT_LIST), DownloadStrategyIfNotCached.INSTANCE, Constants.FileType.IMAGE, - CacheRequest.DOWNLOAD_QUEUE_IMMEDIATE, + CacheRequest.DownloadQueueType.IMMEDIATE, activity, new CacheRequestCallbacks() { Bitmap image = null; @@ -144,7 +146,7 @@ private void getFlairEmotes( public void onDataStreamComplete( @NonNull final GenericFactory stream, - final long timestamp, + final TimestampUTC timestamp, @NonNull final UUID session, final boolean fromCache, @Nullable final String mimetype) { @@ -187,25 +189,24 @@ public void onDataStreamComplete( activity.getApplicationContext(), image); - mFlair.replace(placeholder, span); + if (mFlair != null) { + mFlair.replace(placeholder, span); + } } catch (final Throwable t) { - onFailure( - CacheRequest.REQUEST_FAILURE_CONNECTION, - t, - null, + onFailure(new RRError( "Exception while downloading emote", - Optional.empty()); + null, + true, + t)); } } @Override - public void onFailure( - final int type, - @Nullable final Throwable t, - @Nullable final Integer httpStatus, - @Nullable final String readableMessage, - @NonNull final Optional body) { - + public void onFailure(@NonNull RRError error) { + Log.e( + "RedditParsedComment", + "Failed to download emote: " + error.message, + error.t); } } )); From d2472b08a3e2725aef0409b20048eb54de61a07b Mon Sep 17 00:00:00 2001 From: QuantumBadger Date: Sun, 20 Apr 2025 13:10:26 +0100 Subject: [PATCH 4/5] Improve flair size and alignment (#1054) --- .../reddit/prepared/RedditParsedComment.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java index f969c8cd8..f6c2a68db 100644 --- a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java +++ b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java @@ -19,6 +19,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.os.Build; import android.text.style.ImageSpan; import android.util.Log; import android.util.TypedValue; @@ -115,6 +116,15 @@ public RedditComment getRawComment() { private void getFlairEmotes( final List> flairRichtext, final AppCompatActivity activity) { + + final int alignment; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + alignment = ImageSpan.ALIGN_CENTER; + } else { + alignment = ImageSpan.ALIGN_BASELINE; + } + for (final MaybeParseError flairEmoteData : flairRichtext) { if (!(flairEmoteData instanceof MaybeParseError.Ok)) { continue; @@ -158,7 +168,7 @@ public void onDataStreamComplete( } final int textSize = 11; - final float maxImageHeightMultiple = 2.0F; + final float maxImageHeightMultiple = 1.0F; final float maxHeight = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, @@ -187,7 +197,8 @@ public void onDataStreamComplete( final ImageSpan span = new ImageSpan( activity.getApplicationContext(), - image); + image, + alignment); if (mFlair != null) { mFlair.replace(placeholder, span); From 31bf9db20e83b160f96967a81bc536b31214463b Mon Sep 17 00:00:00 2001 From: QuantumBadger Date: Sun, 20 Apr 2025 13:33:16 +0100 Subject: [PATCH 5/5] Fixing PMD warnings --- .../redreader/reddit/prepared/RedditParsedComment.java | 2 +- .../redreader/reddit/prepared/RedditRenderableComment.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java index f6c2a68db..58be759eb 100644 --- a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java +++ b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditParsedComment.java @@ -213,7 +213,7 @@ public void onDataStreamComplete( } @Override - public void onFailure(@NonNull RRError error) { + public void onFailure(@NonNull final RRError error) { Log.e( "RedditParsedComment", "Failed to download emote: " + error.message, diff --git a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditRenderableComment.java b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditRenderableComment.java index 99f23382f..0114f5dcb 100644 --- a/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditRenderableComment.java +++ b/src/main/java/org/quantumbadger/redreader/reddit/prepared/RedditRenderableComment.java @@ -46,7 +46,6 @@ import org.quantumbadger.redreader.reddit.kthings.RedditIdAndType; import org.quantumbadger.redreader.reddit.things.RedditThingWithIdAndType; -import java.net.URI; import java.util.Observer; public class RedditRenderableComment