package me.ccrama.redditslide;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.text.style.RelativeSizeSpan;
import android.text.style.StyleSpan;
import android.util.TypedValue;
import net.dean.jraw.models.DistinguishedStatus;
import net.dean.jraw.models.Submission;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.WeakHashMap;
import me.ccrama.redditslide.Views.RoundedBackgroundSpan;
import me.ccrama.redditslide.Visuals.FontPreferences;
import me.ccrama.redditslide.Visuals.Palette;
/**
* Created by carlo_000 on 4/22/2016.
*/
public class SubmissionCache {
private static WeakHashMap<String, SpannableStringBuilder> titles;
private static WeakHashMap<String, SpannableStringBuilder> info;
public static void cacheSubmissions(List<Submission> submissions, Context mContext,
String baseSub) {
cacheInfo(submissions, mContext, baseSub);
}
private static void cacheInfo(List<Submission> submissions, Context mContext, String baseSub) {
if (titles == null) titles = new WeakHashMap<>();
if (info == null) info = new WeakHashMap<>();
for (Submission submission : submissions) {
titles.put(submission.getFullName(), getTitleSpannable(submission, mContext));
info.put(submission.getFullName(), getInfoSpannable(submission, mContext, baseSub));
}
}
public static void updateInfoSpannable(Submission changed, Context mContext, String baseSub){
info.put(changed.getFullName(), getInfoSpannable(changed,mContext, baseSub));
}
public static void updateTitleFlair(Submission s, String flair, Context c) {
titles.put(s.getFullName(), getTitleSpannable(s, flair, c));
}
public static SpannableStringBuilder getTitleLine(Submission s, Context mContext) {
if (titles == null) titles = new WeakHashMap<>();
if (titles.containsKey(s.getFullName())) {
return titles.get(s.getFullName());
} else {
return getTitleSpannable(s, mContext);
}
}
public static SpannableStringBuilder getInfoLine(Submission s, Context mContext,
String baseSub) {
if (info == null) info = new WeakHashMap<>();
if (info.containsKey(s.getFullName())) {
return info.get(s.getFullName());
} else {
return getInfoSpannable(s, mContext, baseSub);
}
}
private static SpannableStringBuilder getInfoSpannable(Submission submission, Context mContext,
String baseSub) {
String spacer = mContext.getString(R.string.submission_properties_seperator);
SpannableStringBuilder titleString = new SpannableStringBuilder();
SpannableStringBuilder subreddit =
new SpannableStringBuilder(" /r/" + submission.getSubredditName() + " ");
if(submission.getSubredditName() == null){
subreddit = new SpannableStringBuilder("Promoted ");
}
String subname;
if (submission.getSubredditName() != null) {
subname = submission.getSubredditName().toLowerCase();
} else {
subname = "";
}
if (baseSub == null || baseSub.isEmpty()) baseSub = subname;
if ((SettingValues.colorSubName && Palette.getColor(subname) != Palette.getDefaultColor())
|| (baseSub.equals("nomatching") && (SettingValues.colorSubName
&& Palette.getColor(subname) != Palette.getDefaultColor()))) {
boolean secondary = (baseSub.equalsIgnoreCase("frontpage")
|| (baseSub.equalsIgnoreCase("all"))
|| (baseSub.equalsIgnoreCase("popular"))
|| (baseSub.equalsIgnoreCase("friends"))
|| (baseSub.equalsIgnoreCase("mod"))
|| baseSub.contains(".")
|| baseSub.contains("+"));
if (!secondary && !SettingValues.colorEverywhere || secondary) {
subreddit.setSpan(new ForegroundColorSpan(Palette.getColor(subname)), 0,
subreddit.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
subreddit.setSpan(new StyleSpan(Typeface.BOLD), 0, subreddit.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
titleString.append(subreddit);
titleString.append(spacer);
try {
String time = TimeUtils.getTimeAgo(submission.getCreated().getTime(), mContext);
titleString.append(time);
} catch (Exception e) {
titleString.append("just now");
}
titleString.append(((submission.getEdited() != null) ? " (edit " + TimeUtils.getTimeAgo(
submission.getEdited().getTime(), mContext) + ")" : ""));
titleString.append(spacer);
SpannableStringBuilder author =
new SpannableStringBuilder(" " + submission.getAuthor() + " ");
int authorcolor = Palette.getFontColorUser(submission.getAuthor());
if (submission.getAuthor() != null) {
if (Authentication.name != null && submission.getAuthor()
.toLowerCase()
.equals(Authentication.name.toLowerCase())) {
author.setSpan(new RoundedBackgroundSpan(mContext, R.color.white,
R.color.md_deep_orange_300, false), 0, author.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (submission.getDistinguishedStatus() == DistinguishedStatus.ADMIN) {
author.setSpan(
new RoundedBackgroundSpan(mContext, R.color.white, R.color.md_red_300,
false), 0, author.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (submission.getDistinguishedStatus() == DistinguishedStatus.SPECIAL) {
author.setSpan(
new RoundedBackgroundSpan(mContext, R.color.white, R.color.md_purple_300,
false), 0, author.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (submission.getDistinguishedStatus() == DistinguishedStatus.MODERATOR) {
author.setSpan(
new RoundedBackgroundSpan(mContext, R.color.white, R.color.md_green_300,
false), 0, author.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (authorcolor != 0) {
author.setSpan(new ForegroundColorSpan(authorcolor), 0, author.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
titleString.append(author);
}
/*todo maybe? titleString.append(((comment.hasBeenEdited() && comment.getEditDate() != null) ? " *" + TimeUtils.getTimeAgo(comment.getEditDate().getTime(), mContext) : ""));
titleString.append(" ");*/
if (UserTags.isUserTagged(submission.getAuthor())) {
SpannableStringBuilder pinned = new SpannableStringBuilder(
" " + UserTags.getUserTag(submission.getAuthor()) + " ");
pinned.setSpan(
new RoundedBackgroundSpan(mContext, R.color.white, R.color.md_blue_500, false),
0, pinned.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
titleString.append(pinned);
titleString.append(" ");
}
if (UserSubscriptions.friends.contains(submission.getAuthor())) {
SpannableStringBuilder pinned = new SpannableStringBuilder(
" " + mContext.getString(R.string.profile_friend) + " ");
pinned.setSpan(
new RoundedBackgroundSpan(mContext, R.color.white, R.color.md_deep_orange_500,
false), 0, pinned.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
titleString.append(pinned);
titleString.append(" ");
}
/* too big, might add later todo
if (submission.getAuthorFlair() != null && submission.getAuthorFlair().getText() != null && !submission.getAuthorFlair().getText().isEmpty()) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = mContext.getTheme();
theme.resolveAttribute(R.attr.activity_background, typedValue, true);
int color = typedValue.data;
SpannableStringBuilder pinned = new SpannableStringBuilder(" " + submission.getAuthorFlair().getText() + " ");
pinned.setSpan(new RoundedBackgroundSpan(holder.title.getCurrentTextColor(), color, false, mContext), 0, pinned.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
titleString.append(pinned);
titleString.append(" ");
}
if (holder.leadImage.getVisibility() == View.GONE && !full) {
String text = "";
switch (ContentType.getContentType(submission)) {
case NSFW_IMAGE:
text = mContext.getString(R.string.type_nsfw_img);
break;
case NSFW_GIF:
case NSFW_GFY:
text = mContext.getString(R.string.type_nsfw_gif);
break;
case REDDIT:
text = mContext.getString(R.string.type_reddit);
break;
case LINK:
case IMAGE_LINK:
text = mContext.getString(R.string.type_link);
break;
case NSFW_LINK:
text = mContext.getString(R.string.type_nsfw_link);
break;
case STREAMABLE:
text = ("Streamable");
break;
case SELF:
text = ("Selftext");
break;
case ALBUM:
text = mContext.getString(R.string.type_album);
break;
case IMAGE:
text = mContext.getString(R.string.type_img);
break;
case IMGUR:
text = mContext.getString(R.string.type_imgur);
break;
case GFY:
case GIF:
case NONE_GFY:
case NONE_GIF:
text = mContext.getString(R.string.type_gif);
break;
case NONE:
text = mContext.getString(R.string.type_title_only);
break;
case NONE_IMAGE:
text = mContext.getString(R.string.type_img);
break;
case VIDEO:
text = mContext.getString(R.string.type_vid);
break;
case EMBEDDED:
text = mContext.getString(R.string.type_emb);
break;
case NONE_URL:
text = mContext.getString(R.string.type_link);
break;
}
if(!text.isEmpty()) {
titleString.append(" \n");
text = text.toUpperCase();
TypedValue typedValue = new TypedValue();
Resources.Theme theme = mContext.getTheme();
theme.resolveAttribute(R.attr.activity_background, typedValue, true);
int color = typedValue.data;
SpannableStringBuilder pinned = new SpannableStringBuilder(" " + text + " ");
pinned.setSpan(new RoundedBackgroundSpan(holder.title.getCurrentTextColor(), color, false, mContext), 0, pinned.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
titleString.append(pinned);
}
}*/
if (SettingValues.showDomain) {
titleString.append(spacer);
titleString.append(submission.getDomain());
}
if (SettingValues.typeInfoLine) {
titleString.append(spacer);
SpannableStringBuilder s = new SpannableStringBuilder(
ContentType.getContentDescription(submission, mContext));
s.setSpan(new StyleSpan(Typeface.BOLD), 0, s.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
titleString.append(s);
}
if (SettingValues.votesInfoLine) {
titleString.append("\n ");
SpannableStringBuilder s = new SpannableStringBuilder(
submission.getScore()
+ String.format(Locale.getDefault(), " %s", mContext.getResources()
.getQuantityString(R.plurals.points, submission.getScore()))
+ spacer
+ submission.getCommentCount()
+ String.format(Locale.getDefault(), " %s", mContext.getResources()
.getQuantityString(R.plurals.comments, submission.getCommentCount())));
s.setSpan(new StyleSpan(Typeface.BOLD), 0, s.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (SettingValues.commentLastVisit) {
final int more = LastComments.commentsSince(submission);
s.append(more > 0 ? "(+" + more + ")" : "");
}
titleString.append(s);
}
if (removed.contains(submission.getFullName()) || (submission.getBannedBy() != null
&& !approved.contains(submission.getFullName()))) {
titleString.append(createRemovedLine(
(submission.getBannedBy() == null) ? Authentication.name : submission.getBannedBy(),
mContext));
} else if (approved.contains(submission.getFullName()) || (submission.getApprovedBy()
!= null && !removed.contains(submission.getFullName()))) {
titleString.append(createApprovedLine(
(submission.getApprovedBy() == null) ? Authentication.name
: submission.getApprovedBy(), mContext));
}
return titleString;
}
private static SpannableStringBuilder getTitleSpannable(Submission submission,
String flairOverride, Context mContext) {
SpannableStringBuilder titleString = new SpannableStringBuilder();
titleString.append(Html.fromHtml(submission.getTitle()));
if (submission.isStickied()) {
SpannableStringBuilder pinned = new SpannableStringBuilder("\u00A0"
+ mContext.getString(R.string.submission_stickied).toUpperCase()
+ "\u00A0");
pinned.setSpan(
new RoundedBackgroundSpan(mContext, R.color.white, R.color.md_green_300, true),
0, pinned.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
titleString.append(" ");
titleString.append(pinned);
}
if (submission.getTimesGilded() > 0) {
//if the post has only been gilded once, don't show a number
final String timesGilded = (submission.getTimesGilded() == 1) ? "" : "\u200Ax" + Integer.toString(submission.getTimesGilded());
SpannableStringBuilder gilded = new SpannableStringBuilder("\u00A0★" + timesGilded + "\u00A0");
TypedArray a = mContext.obtainStyledAttributes(new FontPreferences(mContext).getPostFontStyle().getResId(), R.styleable.FontStyle);
int fontsize = (int) (a.getDimensionPixelSize(R.styleable.FontStyle_font_cardtitle, -1)*.75);
a.recycle();
Bitmap image = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.gold);
float aspectRatio = (float) (1.00 * image.getWidth() / image.getHeight());
image = Bitmap.createScaledBitmap(image,
(int) Math.ceil(fontsize * aspectRatio),
(int) Math.ceil(fontsize), true);
gilded.setSpan(new ImageSpan(mContext, image, ImageSpan.ALIGN_BASELINE), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
gilded.setSpan(new RelativeSizeSpan(0.75f), 3, gilded.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
titleString.append(" ");
titleString.append(gilded);
}
if (submission.isNsfw()) {
SpannableStringBuilder pinned = new SpannableStringBuilder("\u00A0NSFW\u00A0");
pinned.setSpan(
new RoundedBackgroundSpan(mContext, R.color.white, R.color.md_red_300, true), 0,
pinned.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
titleString.append(" ");
titleString.append(pinned);
}
if (submission.getDataNode().get("spoiler").asBoolean()) {
SpannableStringBuilder pinned = new SpannableStringBuilder("\u00A0SPOILER\u00A0");
pinned.setSpan(
new RoundedBackgroundSpan(mContext, R.color.white, R.color.md_grey_600, true), 0,
pinned.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
titleString.append(" ");
titleString.append(pinned);
}
if (submission.getSubmissionFlair().getText() != null && !submission.getSubmissionFlair()
.getText()
.isEmpty() || flairOverride != null || (submission.getSubmissionFlair()
.getCssClass() != null)) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = mContext.getTheme();
theme.resolveAttribute(R.attr.activity_background, typedValue, false);
int color = typedValue.data;
theme.resolveAttribute(R.attr.font, typedValue, false);
int font = typedValue.data;
String flairString;
if (flairOverride != null) {
flairString = flairOverride;
} else if ((submission.getSubmissionFlair().getText() == null
|| submission.getSubmissionFlair().getText().isEmpty())
&& submission.getSubmissionFlair().getCssClass() != null) {
flairString = submission.getSubmissionFlair().getCssClass();
} else {
flairString = submission.getSubmissionFlair().getText();
}
SpannableStringBuilder pinned =
new SpannableStringBuilder("\u00A0" + Html.fromHtml(flairString) + "\u00A0");
pinned.setSpan(new RoundedBackgroundSpan(font, color, true, mContext), 0,
pinned.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
titleString.append(" ");
titleString.append(pinned);
}
return titleString;
}
public static SpannableStringBuilder createRemovedLine(String removedBy, Context c) {
SpannableStringBuilder removedString = new SpannableStringBuilder("\n");
SpannableStringBuilder mod = new SpannableStringBuilder("Removed by ");
mod.append(removedBy);
mod.setSpan(new StyleSpan(Typeface.BOLD), 0, mod.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
mod.setSpan(new RelativeSizeSpan(0.8f), 0, mod.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
mod.setSpan(new ForegroundColorSpan(c.getResources().getColor(R.color.md_red_300)), 0,
mod.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
removedString.append(mod);
return removedString;
}
public static SpannableStringBuilder createApprovedLine(String removedBy, Context c) {
SpannableStringBuilder removedString = new SpannableStringBuilder("\n");
SpannableStringBuilder mod = new SpannableStringBuilder("Approved by ");
mod.append(removedBy);
mod.setSpan(new StyleSpan(Typeface.BOLD), 0, mod.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
mod.setSpan(new RelativeSizeSpan(0.8f), 0, mod.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
mod.setSpan(new ForegroundColorSpan(c.getResources().getColor(R.color.md_green_300)), 0,
mod.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
removedString.append(mod);
return removedString;
}
public static ArrayList<String> removed = new ArrayList<>();
public static ArrayList<String> approved = new ArrayList<>();
private static SpannableStringBuilder getTitleSpannable(Submission submission,
Context mContext) {
return getTitleSpannable(submission, null, mContext);
}
public static void evictAll() {
info = new WeakHashMap<>();
}
}