diff options
author | Alex Ning <chineseperson5@gmail.com> | 2018-08-24 02:38:37 +0000 |
---|---|---|
committer | Alex Ning <chineseperson5@gmail.com> | 2018-08-24 02:38:37 +0000 |
commit | d83ded01933d653ac7ea62e9f5f9c4915263a5ca (patch) | |
tree | 77bb0898c7bcdc54de7a049611ab6e527b9a444c /app | |
parent | f90bd4d1cce5f5ca523e4cae395a652a67811615 (diff) | |
download | infinity-for-reddit-d83ded01933d653ac7ea62e9f5f9c4915263a5ca.tar infinity-for-reddit-d83ded01933d653ac7ea62e9f5f9c4915263a5ca.tar.gz infinity-for-reddit-d83ded01933d653ac7ea62e9f5f9c4915263a5ca.tar.bz2 infinity-for-reddit-d83ded01933d653ac7ea62e9f5f9c4915263a5ca.tar.lz infinity-for-reddit-d83ded01933d653ac7ea62e9f5f9c4915263a5ca.tar.xz infinity-for-reddit-d83ded01933d653ac7ea62e9f5f9c4915263a5ca.tar.zst infinity-for-reddit-d83ded01933d653ac7ea62e9f5f9c4915263a5ca.zip |
Display a thumbtack icon if the post is stickied on top. Display a gold icon and the number of gold if the post is gilded. Load subreddit icons in LoadSubredditIconAsyncTaskListener instead of loading the icons in onPostExecute() of LoadSubredditIconAsyncTask in order to avoid loading icons on a destroyed activity when start the Activity and then press back or up button immediately.
Diffstat (limited to 'app')
-rw-r--r-- | app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java | 28 | ||||
-rw-r--r-- | app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java | 48 | ||||
-rw-r--r-- | app/src/main/java/ml/docilealligator/infinityforreddit/PostData.java | 34 | ||||
-rw-r--r-- | app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java | 4 | ||||
-rw-r--r-- | app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java | 91 | ||||
-rw-r--r-- | app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java | 51 | ||||
-rw-r--r-- | app/src/main/res/drawable/gold.png | bin | 0 -> 18745 bytes | |||
-rw-r--r-- | app/src/main/res/drawable/thumbtack.png | bin | 0 -> 6774 bytes | |||
-rw-r--r-- | app/src/main/res/layout/activity_view_post_detail.xml | 21 | ||||
-rw-r--r-- | app/src/main/res/layout/item_post.xml | 46 | ||||
-rw-r--r-- | app/src/main/res/values/colors.xml | 2 | ||||
-rw-r--r-- | app/src/main/res/values/strings.xml | 89 |
12 files changed, 247 insertions, 167 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java index 928951fc..97795c54 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java @@ -1,31 +1,22 @@ package ml.docilealligator.infinityforreddit; -import android.content.Context; import android.os.AsyncTask; -import com.bumptech.glide.Glide; - -import java.lang.ref.WeakReference; - -import de.hdodenhof.circleimageview.CircleImageView; - class LoadSubredditIconAsyncTask extends AsyncTask<Void, Void, Void> { - private final WeakReference<Context> contextWeakReference; - private final WeakReference<CircleImageView> circleImageViewWeakReference; + interface LoadSubredditIconAsyncTaskListener { + void loadIconSuccess(String iconImageUrl); + } private SubredditDao subredditDao; private String subredditName; private String iconImageUrl; - private PostData postData; + private LoadSubredditIconAsyncTaskListener loadSubredditIconAsyncTaskListener; - LoadSubredditIconAsyncTask(Context context, CircleImageView iconImageView, - SubredditDao subredditDao, String subredditName, - PostData postData) { - contextWeakReference = new WeakReference<>(context); - circleImageViewWeakReference = new WeakReference<>(iconImageView); + LoadSubredditIconAsyncTask(SubredditDao subredditDao, String subredditName, + LoadSubredditIconAsyncTaskListener loadSubredditIconAsyncTaskListener) { this.subredditDao = subredditDao; this.subredditName = subredditName; - this.postData = postData; + this.loadSubredditIconAsyncTaskListener = loadSubredditIconAsyncTaskListener; } @Override @@ -41,7 +32,8 @@ class LoadSubredditIconAsyncTask extends AsyncTask<Void, Void, Void> { @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); - Context context = contextWeakReference.get(); + loadSubredditIconAsyncTaskListener.loadIconSuccess(iconImageUrl); + /*Context context = contextWeakReference.get(); CircleImageView circleImageView = circleImageViewWeakReference.get(); if(context != null && circleImageView != null) { @@ -52,6 +44,6 @@ class LoadSubredditIconAsyncTask extends AsyncTask<Void, Void, Void> { } } - postData.setSubredditIconUrl(iconImageUrl); + postData.setSubredditIconUrl(iconImageUrl);*/ } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java index caebd825..ffc2be9b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java @@ -70,7 +70,9 @@ class ParsePost { String title = data.getString(JSONUtils.TITLE_KEY); int score = data.getInt(JSONUtils.SCORE_KEY); int voteType; + int gilded = data.getInt(JSONUtils.GILDED_KEY); boolean nsfw = data.getBoolean(JSONUtils.NSFW_KEY); + boolean stickied = data.getBoolean(JSONUtils.STICKIED_KEY); if(data.isNull(JSONUtils.LIKES_KEY)) { voteType = 0; @@ -93,10 +95,10 @@ class ParsePost { //Cross post data = data.getJSONArray(JSONUtils.CROSSPOST_PARENT_LIST).getJSONObject(0); parseData(data, permalink, newPostData, id, fullName, subredditName, - formattedPostTime, title, previewUrl, score, voteType, nsfw, i); + formattedPostTime, title, previewUrl, score, voteType, gilded, nsfw, stickied, i); } else { parseData(data, permalink, newPostData, id, fullName, subredditName, - formattedPostTime, title, previewUrl, score, voteType, nsfw, i); + formattedPostTime, title, previewUrl, score, voteType, gilded, nsfw, stickied, i); } } } catch (JSONException e) { @@ -119,8 +121,9 @@ class ParsePost { } private void parseData(JSONObject data, String permalink, ArrayList<PostData> bestPostData, - String id, String fullName, String subredditName, String formattedPostTime, String title, - String previewUrl, int score, int voteType, boolean nsfw, int i) throws JSONException { + String id, String fullName, String subredditName, String formattedPostTime, + String title, String previewUrl, int score, int voteType, int gilded, + boolean nsfw, boolean stickied, int i) throws JSONException { boolean isVideo = data.getBoolean(JSONUtils.IS_VIDEO_KEY); String url = data.getString(JSONUtils.URL_KEY); @@ -129,7 +132,8 @@ class ParsePost { //Text post Log.i("text", Integer.toString(i)); int postType = PostData.TEXT_TYPE; - PostData postData = new PostData(id, fullName, subredditName, formattedPostTime, title, permalink, score, postType, voteType, nsfw); + PostData postData = new PostData(id, fullName, subredditName, formattedPostTime, + title, permalink, score, postType, voteType, gilded, nsfw, stickied); if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) { postData.setSelfText(""); } else { @@ -140,7 +144,13 @@ class ParsePost { //No preview link post Log.i("no preview link", Integer.toString(i)); int postType = PostData.NO_PREVIEW_LINK_TYPE; - PostData linkPostData = new PostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, url, permalink, score, postType, voteType, nsfw); + PostData linkPostData = new PostData(id, fullName, subredditName, formattedPostTime, + title, previewUrl, url, permalink, score, postType, voteType, gilded, nsfw, stickied); + if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) { + linkPostData.setSelfText(""); + } else { + linkPostData.setSelfText(data.getString(JSONUtils.SELFTEXT_HTML_KEY).trim()); + } bestPostData.add(linkPostData); } } else if(isVideo) { @@ -150,7 +160,8 @@ class ParsePost { int postType = PostData.VIDEO_TYPE; String videoUrl = redditVideoObject.getString(JSONUtils.DASH_URL_KEY); - PostData videoPostData = new PostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, permalink, score, postType, voteType, nsfw, true); + PostData videoPostData = new PostData(id, fullName, subredditName, formattedPostTime, + title, previewUrl, permalink, score, postType, voteType, gilded, nsfw, stickied, true); videoPostData.setVideoUrl(videoUrl); videoPostData.setDownloadableGifOrVideo(false); @@ -164,7 +175,8 @@ class ParsePost { int postType = PostData.GIF_VIDEO_TYPE; String videoUrl = variations.getJSONObject(JSONUtils.VARIANTS_KEY).getJSONObject(JSONUtils.MP4_KEY).getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY); String gifDownloadUrl = variations.getJSONObject(JSONUtils.VARIANTS_KEY).getJSONObject(JSONUtils.GIF_KEY).getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY); - PostData post = new PostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, permalink, score, postType, voteType, nsfw, false); + PostData post = new PostData(id, fullName, subredditName, formattedPostTime, title, + previewUrl, permalink, score, postType, voteType, gilded, nsfw, stickied, false); post.setVideoUrl(videoUrl); post.setDownloadableGifOrVideo(true); @@ -178,7 +190,8 @@ class ParsePost { String videoUrl = data.getJSONObject(JSONUtils.PREVIEW_KEY) .getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.DASH_URL_KEY); - PostData post = new PostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, permalink, score, postType, voteType, nsfw, true); + PostData post = new PostData(id, fullName, subredditName, formattedPostTime, title, + previewUrl, permalink, score, postType, voteType, gilded, nsfw, stickied, true); post.setVideoUrl(videoUrl); post.setDownloadableGifOrVideo(false); @@ -189,12 +202,19 @@ class ParsePost { //Image post Log.i("image", Integer.toString(i)); int postType = PostData.IMAGE_TYPE; - bestPostData.add(new PostData(id, fullName, subredditName, formattedPostTime, title, url, url, permalink, score, postType, voteType, nsfw)); + bestPostData.add(new PostData(id, fullName, subredditName, formattedPostTime, + title, url, url, permalink, score, postType, voteType, gilded, nsfw, stickied)); } else { //Link post Log.i("link", Integer.toString(i)); int postType = PostData.LINK_TYPE; - PostData linkPostData = new PostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, url, permalink, score, postType, voteType, nsfw); + PostData linkPostData = new PostData(id, fullName, subredditName, formattedPostTime, + title, previewUrl, url, permalink, score, postType, voteType, gilded, nsfw, stickied); + if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) { + linkPostData.setSelfText(""); + } else { + linkPostData.setSelfText(data.getString(JSONUtils.SELFTEXT_HTML_KEY).trim()); + } bestPostData.add(linkPostData); } } @@ -203,12 +223,14 @@ class ParsePost { //Image post Log.i("CP no preview image", Integer.toString(i)); int postType = PostData.IMAGE_TYPE; - bestPostData.add(new PostData(id, fullName, subredditName, formattedPostTime, title, url, url, permalink, score, postType, voteType, nsfw)); + bestPostData.add(new PostData(id, fullName, subredditName, formattedPostTime, title, + url, url, permalink, score, postType, voteType, gilded, nsfw, stickied)); } else { //Link post Log.i("CP no preview link", Integer.toString(i)); int postType = PostData.LINK_TYPE; - PostData linkPostData = new PostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, url, permalink, score, postType, voteType, nsfw); + PostData linkPostData = new PostData(id, fullName, subredditName, formattedPostTime, + title, previewUrl, url, permalink, score, postType, voteType, gilded, nsfw, stickied); bestPostData.add(linkPostData); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostData.java index c91cc333..0626088f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostData.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostData.java @@ -30,11 +30,15 @@ class PostData implements Parcelable { private int score; private int postType; private int voteType; + private int gilded; private boolean nsfw; + private boolean stickied; private boolean isDashVideo; private boolean isDownloadableGifOrVideo; - PostData(String id, String fullName, String subredditName, String postTime, String title, String previewUrl, String permalink, int score, int postType, int voteType, boolean nsfw, boolean isDashVideo) { + PostData(String id, String fullName, String subredditName, String postTime, String title, + String previewUrl, String permalink, int score, int postType, int voteType, int gilded, + boolean nsfw, boolean stickied, boolean isDashVideo) { this.id = id; this.fullName = fullName; this.subredditName = subredditName; @@ -45,11 +49,15 @@ class PostData implements Parcelable { this.score = score; this.postType = postType; this.voteType = voteType; + this.gilded = gilded; this.nsfw = nsfw; + this.stickied = stickied; this.isDashVideo = isDashVideo; } - PostData(String id, String fullName, String subredditName, String postTime, String title, String previewUrl, String url, String permalink, int score, int postType, int voteType, boolean nsfw) { + PostData(String id, String fullName, String subredditName, String postTime, String title, + String previewUrl, String url, String permalink, int score, int postType, int voteType, + int gilded, boolean nsfw, boolean stickied) { this.id = id; this.fullName = fullName; this.subredditName = subredditName; @@ -61,10 +69,14 @@ class PostData implements Parcelable { this.score = score; this.postType = postType; this.voteType = voteType; + this.gilded = gilded; this.nsfw = nsfw; + this.stickied = stickied; } - PostData(String id, String fullName, String subredditName, String postTime, String title, String permalink, int score, int postType, int voteType, boolean nsfw) { + PostData(String id, String fullName, String subredditName, String postTime, String title, + String permalink, int score, int postType, int voteType, int gilded, boolean nsfw, + boolean stickied) { this.id = id; this.fullName = fullName; this.subredditName = subredditName; @@ -74,7 +86,9 @@ class PostData implements Parcelable { this.score = score; this.postType = postType; this.voteType = voteType; + this.gilded = gilded; this.nsfw = nsfw; + this.stickied = stickied; } protected PostData(Parcel in) { @@ -93,7 +107,9 @@ class PostData implements Parcelable { score = in.readInt(); postType = in.readInt(); voteType = in.readInt(); + gilded = in.readInt(); nsfw = in.readByte() != 0; + stickied = in.readByte() != 0; isDashVideo = in.readByte() != 0; isDownloadableGifOrVideo = in.readByte() != 0; } @@ -198,7 +214,11 @@ class PostData implements Parcelable { return voteType; } - public boolean getNSFW() { + public int getGilded() { + return gilded; + } + + public boolean isNSFW() { return nsfw; } @@ -219,6 +239,10 @@ class PostData implements Parcelable { return isDownloadableGifOrVideo; } + public boolean isStickied() { + return stickied; + } + @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(id); @@ -236,7 +260,9 @@ class PostData implements Parcelable { parcel.writeInt(score); parcel.writeInt(postType); parcel.writeInt(voteType); + parcel.writeInt(gilded); parcel.writeByte((byte) (nsfw ? 1 : 0)); + parcel.writeByte((byte) (stickied ? 1 : 0)); parcel.writeByte((byte) (isDashVideo ? 1 : 0)); parcel.writeByte((byte) (isDownloadableGifOrVideo ? 1 : 0)); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java index 49220d94..e8b10896 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java @@ -188,10 +188,6 @@ public class PostFragment extends Fragment { mProgressBar.setVisibility(View.VISIBLE); - /*Uri uri = Uri.parse(RedditUtils.OAUTH_API_BASE_URI + RedditUtils.BEST_POST_SUFFIX) - .buildUpon().appendQueryParameter(RedditUtils.RAW_JSON_KEY, RedditUtils.RAW_JSON_VALUE) - .build();*/ - StringRequest postRequest = new StringRequest(Request.Method.GET, mQueryPostUrl, new Response.Listener<String>() { @Override public void onResponse(String response) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java index 933af11d..724fb753 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java @@ -86,22 +86,36 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold } @Override - public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) { + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) { if(holder instanceof DataViewHolder) { if(mPostData.get(position) == null) { Log.i("is null", Integer.toString(position)); } else { - final String id = mPostData.get(position).getFullName(); - final String subredditName = mPostData.get(position).getSubredditName(); - final String postTime = mPostData.get(position).getPostTime(); - final String title = mPostData.get(position).getTitle(); - final String permalink = mPostData.get(position).getPermalink(); - int voteType = mPostData.get(position).getVoteType(); - boolean nsfw = mPostData.get(position).getNSFW(); - - if(mPostData.get(position).getSubredditIconUrl() == null) { - new LoadSubredditIconAsyncTask(mContext, ((DataViewHolder) holder).subredditIconCircleImageView, - subredditDao, subredditName, mPostData.get(position)).execute(); + final String id = mPostData.get(holder.getAdapterPosition()).getFullName(); + final String subredditName = mPostData.get(holder.getAdapterPosition()).getSubredditName(); + final String postTime = mPostData.get(holder.getAdapterPosition()).getPostTime(); + final String title = mPostData.get(holder.getAdapterPosition()).getTitle(); + final String permalink = mPostData.get(holder.getAdapterPosition()).getPermalink(); + int voteType = mPostData.get(holder.getAdapterPosition()).getVoteType(); + int gilded = mPostData.get(holder.getAdapterPosition()).getGilded(); + boolean nsfw = mPostData.get(holder.getAdapterPosition()).isNSFW(); + + if(mPostData.get(holder.getAdapterPosition()).getSubredditIconUrl() == null) { + new LoadSubredditIconAsyncTask(subredditDao, subredditName, + new LoadSubredditIconAsyncTask.LoadSubredditIconAsyncTaskListener() { + @Override + public void loadIconSuccess(String iconImageUrl) { + if(!iconImageUrl.equals("")) { + Glide.with(mContext).load(iconImageUrl) + .into(((DataViewHolder) holder).subredditIconCircleImageView); + } else { + Glide.with(mContext).load(R.drawable.subreddit_default_icon) + .into(((DataViewHolder) holder).subredditIconCircleImageView); + } + + mPostData.get(holder.getAdapterPosition()).setSubredditIconUrl(iconImageUrl); + } + }).execute(); } else if(!mPostData.get(position).getSubredditIconUrl().equals("")) { glide.load(mPostData.get(position).getSubredditIconUrl()).into(((DataViewHolder) holder).subredditIconCircleImageView); } else { @@ -115,7 +129,7 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold canStartActivity = false; Intent intent = new Intent(mContext, ViewPostDetailActivity.class); intent.putExtra(ViewPostDetailActivity.EXTRA_TITLE, title); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, mPostData.get(position)); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, mPostData.get(holder.getAdapterPosition())); mContext.startActivity(intent); } } @@ -126,6 +140,14 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold ((DataViewHolder) holder).titleTextView.setText(title); ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore())); + if(gilded > 0) { + ((DataViewHolder) holder).gildedImageView.setVisibility(View.VISIBLE); + glide.load(R.drawable.gold).into(((DataViewHolder) holder).gildedImageView); + ((DataViewHolder) holder).gildedNumberTextView.setVisibility(View.VISIBLE); + String gildedNumber = mContext.getResources().getString(R.string.gilded, gilded); + ((DataViewHolder) holder).gildedNumberTextView.setText(gildedNumber); + } + if(nsfw) { ((DataViewHolder) holder).nsfwTextView.setVisibility(View.VISIBLE); } @@ -147,6 +169,11 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold ((DataViewHolder) holder).imageView.setVisibility(View.VISIBLE); } + if(mPostData.get(position).isStickied()) { + ((DataViewHolder) holder).stickiedPostImageView.setVisibility(View.VISIBLE); + glide.load(R.drawable.thumbtack).into(((DataViewHolder) holder).stickiedPostImageView); + } + switch (mPostData.get(position).getPostType()) { case PostData.IMAGE_TYPE: ((DataViewHolder) holder).typeTextView.setText("IMAGE"); @@ -229,10 +256,10 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold Intent intent = new Intent(mContext, ViewVideoActivity.class); intent.setData(gifVideoUri); intent.putExtra(ViewVideoActivity.TITLE_KEY, title); - intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, mPostData.get(position).isDashVideo()); - intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, mPostData.get(position).isDownloadableGifOrVideo()); - if(mPostData.get(position).isDownloadableGifOrVideo()) { - intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, mPostData.get(position).getGifOrVideoDownloadUrl()); + intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, mPostData.get(holder.getAdapterPosition()).isDashVideo()); + intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, mPostData.get(holder.getAdapterPosition()).isDownloadableGifOrVideo()); + if(mPostData.get(holder.getAdapterPosition()).isDownloadableGifOrVideo()) { + intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, mPostData.get(holder.getAdapterPosition()).getGifOrVideoDownloadUrl()); intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, subredditName); intent.putExtra(ViewVideoActivity.ID_KEY, id); } @@ -265,10 +292,10 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold Intent intent = new Intent(mContext, ViewVideoActivity.class); intent.setData(videoUri); intent.putExtra(ViewVideoActivity.TITLE_KEY, title); - intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, mPostData.get(position).isDashVideo()); - intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, mPostData.get(position).isDownloadableGifOrVideo()); - if(mPostData.get(position).isDownloadableGifOrVideo()) { - intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, mPostData.get(position).getGifOrVideoDownloadUrl()); + intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, mPostData.get(holder.getAdapterPosition()).isDashVideo()); + intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, mPostData.get(holder.getAdapterPosition()).isDownloadableGifOrVideo()); + if(mPostData.get(holder.getAdapterPosition()).isDownloadableGifOrVideo()) { + intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, mPostData.get(holder.getAdapterPosition()).getGifOrVideoDownloadUrl()); intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, subredditName); intent.putExtra(ViewVideoActivity.ID_KEY, id); } @@ -307,9 +334,9 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold if (((DataViewHolder) holder).upvoteButton.getColorFilter() == null) { ((DataViewHolder) holder).upvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN); if(isDownvotedBefore) { - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore() + 2)); + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() + 2)); } else { - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore() + 1)); + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() + 1)); } new VoteThing(mContext, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingListener() { @@ -334,7 +361,7 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold } else { //Upvoted before ((DataViewHolder) holder).upvoteButton.clearColorFilter(); - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore() - 1)); + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() - 1)); new VoteThing(mContext, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingListener() { @Override @@ -365,9 +392,9 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold if (((DataViewHolder) holder).downvoteButton.getColorFilter() == null) { ((DataViewHolder) holder).downvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN); if (isUpvotedBefore) { - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore() - 2)); + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() - 2)); } else { - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore() - 1)); + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() - 1)); } new VoteThing(mContext, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingListener() { @@ -392,7 +419,7 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold } else { //Down voted before ((DataViewHolder) holder).downvoteButton.clearColorFilter(); - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore() + 1)); + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() + 1)); new VoteThing(mContext, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingListener() { @Override @@ -471,9 +498,12 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold private CardView cardView; private CircleImageView subredditIconCircleImageView; private TextView subredditNameTextView; + private ImageView stickiedPostImageView; private TextView postTimeTextView; private TextView titleTextView; private TextView typeTextView; + private ImageView gildedImageView; + private TextView gildedNumberTextView; private TextView nsfwTextView; private RelativeLayout relativeLayout; private ProgressBar progressBar; @@ -489,9 +519,12 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold cardView = itemView.findViewById(R.id.card_view_view_post_detail); subredditIconCircleImageView = itemView.findViewById(R.id.subreddit_icon_circle_image_view_best_post_item); subredditNameTextView = itemView.findViewById(R.id.subreddit_text_view_best_post_item); + stickiedPostImageView = itemView.findViewById(R.id.stickied_post_image_view_best_post_item); postTimeTextView = itemView.findViewById(R.id.post_time_text_view_best_post_item); titleTextView = itemView.findViewById(R.id.title_text_view_best_post_item); typeTextView = itemView.findViewById(R.id.type_text_view_item_best_post); + gildedImageView = itemView.findViewById(R.id.gilded_image_view_item_best_post); + gildedNumberTextView = itemView.findViewById(R.id.gilded_number_text_view_item_best_post); nsfwTextView = itemView.findViewById(R.id.nsfw_text_view_item_best_post); relativeLayout = itemView.findViewById(R.id.image_view_wrapper_item_best_post); progressBar = itemView.findViewById(R.id.progress_bar_best_post_item); @@ -522,7 +555,11 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { if(holder instanceof DataViewHolder) { glide.clear(((DataViewHolder) holder).imageView); + glide.clear(((DataViewHolder) holder).subredditIconCircleImageView); + ((DataViewHolder) holder).stickiedPostImageView.setVisibility(View.GONE); ((DataViewHolder) holder).relativeLayout.setVisibility(View.GONE); + ((DataViewHolder) holder).gildedNumberTextView.setVisibility(View.GONE); + glide.clear(((DataViewHolder) holder).gildedImageView); ((DataViewHolder) holder).nsfwTextView.setVisibility(View.GONE); ((DataViewHolder) holder).progressBar.setVisibility(View.GONE); ((DataViewHolder) holder).imageView.setVisibility(View.GONE); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java index ff467f4c..8ebb175e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java @@ -57,6 +57,8 @@ public class ViewPostDetailActivity extends AppCompatActivity { private LinearLayout mNoCommentWrapperLinearLayout; private ImageView mNoCommentImageView; + private LoadSubredditIconAsyncTask mLoadSubredditIconAsyncTask; + private RequestQueue mVoteThingRequestQueue; private RequestQueue mAcquireAccessTokenRequestQueue; private RequestQueue mCommentQueue; @@ -76,11 +78,13 @@ public class ViewPostDetailActivity extends AppCompatActivity { mCoordinatorLayout = findViewById(R.id.coordinator_layout_view_post_detail); - CircleImageView subredditIconCircleImageView = findViewById(R.id.subreddit_icon_circle_image_view_view_post_detail); + final CircleImageView subredditIconCircleImageView = findViewById(R.id.subreddit_icon_circle_image_view_view_post_detail); TextView postTimeTextView = findViewById(R.id.post_time_text_view_view_post_detail); TextView subredditTextView = findViewById(R.id.subreddit_text_view_view_post_detail); HtmlTextView contentTextView = findViewById(R.id.content_html_text_view_view_post_detail); TextView typeTextView = findViewById(R.id.type_text_view_view_post_detail); + ImageView gildedImageView = findViewById(R.id.gilded_image_view_view_post_detail); + TextView gildedNumberTextView = findViewById(R.id.gilded_number_text_view_view_post_detail); TextView nsfwTextView = findViewById(R.id.nsfw_text_view_view_post_detail); RelativeLayout relativeLayout = findViewById(R.id.image_view_wrapper_view_post_detail); final ProgressBar progressBar = findViewById(R.id.progress_bar_view_post_detail); @@ -100,9 +104,23 @@ public class ViewPostDetailActivity extends AppCompatActivity { mNoCommentImageView = findViewById(R.id.no_comment_image_view_view_post_detail); if(mPostData.getSubredditIconUrl() == null) { - new LoadSubredditIconAsyncTask(this, subredditIconCircleImageView, + mLoadSubredditIconAsyncTask = new LoadSubredditIconAsyncTask( SubredditRoomDatabase.getDatabase(this).subredditDao(), mPostData.getSubredditName(), - mPostData).execute(); + new LoadSubredditIconAsyncTask.LoadSubredditIconAsyncTaskListener() { + @Override + public void loadIconSuccess(String iconImageUrl) { + if(!iconImageUrl.equals("")) { + Glide.with(ViewPostDetailActivity.this).load(iconImageUrl) + .into(subredditIconCircleImageView); + } else { + Glide.with(ViewPostDetailActivity.this).load(R.drawable.subreddit_default_icon) + .into(subredditIconCircleImageView); + } + + mPostData.setSubredditIconUrl(iconImageUrl); + } + }); + mLoadSubredditIconAsyncTask.execute(); } else if(!mPostData.getSubredditIconUrl().equals("")) { Glide.with(this).load(mPostData.getSubredditIconUrl()).into(subredditIconCircleImageView); } else { @@ -129,7 +147,16 @@ public class ViewPostDetailActivity extends AppCompatActivity { subredditTextView.setText(mPostData.getSubredditName()); postTimeTextView.setText(mPostData.getPostTime()); - if(mPostData.getNSFW()) { + + if(mPostData.getGilded() > 0) { + gildedImageView.setVisibility(View.VISIBLE); + Glide.with(this).load(R.drawable.gold).into(gildedImageView); + gildedNumberTextView.setVisibility(View.VISIBLE); + String gildedNumber = getResources().getString(R.string.gilded, mPostData.getGilded()); + gildedNumberTextView.setText(gildedNumber); + } + + if(mPostData.isNSFW()) { nsfwTextView.setVisibility(View.VISIBLE); } scoreTextView.setText(Integer.toString(mPostData.getScore())); @@ -177,6 +204,10 @@ public class ViewPostDetailActivity extends AppCompatActivity { case PostData.LINK_TYPE: relativeLayout.setVisibility(View.VISIBLE); typeTextView.setText("LINK"); + if(!mPostData.getSelfText().equals("")) { + contentTextView.setVisibility(View.VISIBLE); + contentTextView.setHtml(mPostData.getSelfText()); + } String linkPreviewUrl = mPostData.getPreviewUrl(); Glide.with(this).load(linkPreviewUrl).listener(new RequestListener<Drawable>() { @Override @@ -279,6 +310,10 @@ public class ViewPostDetailActivity extends AppCompatActivity { break; case PostData.NO_PREVIEW_LINK_TYPE: typeTextView.setText("LINK"); + if(!mPostData.getSelfText().equals("")) { + contentTextView.setVisibility(View.VISIBLE); + contentTextView.setHtml(mPostData.getSelfText()); + } noPreviewLinkImageView.setVisibility(View.VISIBLE); noPreviewLinkImageView.setOnClickListener(new View.OnClickListener() { @Override @@ -535,4 +570,12 @@ public class ViewPostDetailActivity extends AppCompatActivity { finish(); } } + + @Override + protected void onDestroy() { + super.onDestroy(); + if(mLoadSubredditIconAsyncTask != null) { + mLoadSubredditIconAsyncTask.cancel(true); + } + } } diff --git a/app/src/main/res/drawable/gold.png b/app/src/main/res/drawable/gold.png Binary files differnew file mode 100644 index 00000000..df04fbe8 --- /dev/null +++ b/app/src/main/res/drawable/gold.png diff --git a/app/src/main/res/drawable/thumbtack.png b/app/src/main/res/drawable/thumbtack.png Binary files differnew file mode 100644 index 00000000..b537f614 --- /dev/null +++ b/app/src/main/res/drawable/thumbtack.png diff --git a/app/src/main/res/layout/activity_view_post_detail.xml b/app/src/main/res/layout/activity_view_post_detail.xml index d3b0b3ce..64a648c2 100644 --- a/app/src/main/res/layout/activity_view_post_detail.xml +++ b/app/src/main/res/layout/activity_view_post_detail.xml @@ -103,6 +103,27 @@ android:background="@drawable/rounded_corner" android:textColor="@android:color/white" /> + <ImageView + android:id="@+id/gilded_image_view_view_post_detail" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_toEndOf="@id/type_text_view_view_post_detail" + android:layout_centerVertical="true" + android:visibility="gone"/> + + <TextView + android:id="@+id/gilded_number_text_view_view_post_detail" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="4dp" + android:layout_marginEnd="8dp" + android:layout_toEndOf="@id/gilded_image_view_view_post_detail" + android:layout_toStartOf="@id/nsfw_text_view_view_post_detail" + android:layout_centerVertical="true" + android:visibility="gone" + android:textSize="20sp" + android:textColor="@color/gold"/> + <TextView android:id="@+id/nsfw_text_view_view_post_detail" android:layout_width="wrap_content" diff --git a/app/src/main/res/layout/item_post.xml b/app/src/main/res/layout/item_post.xml index 5978957c..871125d8 100644 --- a/app/src/main/res/layout/item_post.xml +++ b/app/src/main/res/layout/item_post.xml @@ -34,10 +34,20 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" + android:layout_toStartOf="@id/stickied_post_image_view_best_post_item" android:layout_toEndOf="@id/subreddit_icon_circle_image_view_best_post_item" android:layout_centerVertical="true" android:textColor="#E91E63"/> + <ImageView + android:id="@+id/stickied_post_image_view_best_post_item" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_toStartOf="@id/post_time_text_view_best_post_item" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:tint="@color/colorPrimary"/> + <TextView android:id="@+id/post_time_text_view_best_post_item" android:layout_width="wrap_content" @@ -60,20 +70,41 @@ <RelativeLayout android:layout_width="match_parent" - android:layout_height="wrap_content"> + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp"> <TextView android:id="@+id/type_text_view_item_best_post" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/rounded_corner" - android:layout_marginTop="8dp" - android:layout_marginLeft="16dp" - android:layout_marginStart="16dp" - android:layout_marginRight="16dp" android:layout_marginEnd="16dp" + android:layout_centerVertical="true" android:textColor="@android:color/white"/> + <ImageView + android:id="@+id/gilded_image_view_item_best_post" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_toEndOf="@id/type_text_view_item_best_post" + android:layout_centerVertical="true" + android:visibility="gone"/> + + <TextView + android:id="@+id/gilded_number_text_view_item_best_post" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="4dp" + android:layout_marginEnd="8dp" + android:layout_toEndOf="@id/gilded_image_view_item_best_post" + android:layout_toStartOf="@id/nsfw_text_view_item_best_post" + android:layout_centerVertical="true" + android:visibility="gone" + android:textSize="20sp" + android:textColor="@color/gold"/> + <TextView android:id="@+id/nsfw_text_view_item_best_post" android:text="@string/nsfw" @@ -81,11 +112,8 @@ android:layout_height="wrap_content" android:background="@drawable/nsfw_rounded_corner" android:layout_alignParentEnd="true" - android:layout_marginTop="8dp" - android:layout_marginLeft="16dp" android:layout_marginStart="16dp" - android:layout_marginRight="16dp" - android:layout_marginEnd="16dp" + android:layout_centerVertical="true" android:textColor="@android:color/white" android:visibility="gone"/> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index bb250be8..ed9b8e8a 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -7,4 +7,6 @@ <color name="minusButtonColor">#E91E63</color> <color name="transparentActionBarColor">#88000000</color> + + <color name="gold">#FFC107</color> </resources> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c7505627..2014e3bb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -22,93 +22,6 @@ <string name="subscriptions">Subscriptions</string> <string name="subscribers_number_detail">Subscribers: %1$d</string> <string name="online_subscribers_number_detail">Online: %1$d</string> - <string name="large_text"> - "Material is the metaphor.\n\n" - "A material metaphor is the unifying theory of a rationalized space and a system of motion." - "The material is grounded in tactile reality, inspired by the study of paper and ink, yet " - "technologically advanced and open to imagination and magic.\n" - "Surfaces and edges of the material provide visual cues that are grounded in reality. The " - "use of familiar tactile attributes helps users quickly understand affordances. Yet the " - "flexibility of the material creates new affordances that supercede those in the physical " - "world, without breaking the rules of physics.\n" - "The fundamentals of light, surface, and movement are key to conveying how objects move, " - "interact, and exist in space and in relation to each other. Realistic lighting shows " - "seams, divides space, and indicates moving parts.\n\n" - - "Bold, graphic, intentional.\n\n" - - "The foundational elements of print based design typography, grids, space, scale, color, " - "and use of imagery guide visual treatments. These elements do far more than please the " - "eye. They create hierarchy, meaning, and focus. Deliberate color choices, edge to edge " - "imagery, large scale typography, and intentional white space create a bold and graphic " - "interface that immerse the user in the experience.\n" - "An emphasis on user actions makes core functionality immediately apparent and provides " - "waypoints for the user.\n\n" - - "Motion provides meaning.\n\n" - - "Motion respects and reinforces the user as the prime mover. Primary user actions are " - "inflection points that initiate motion, transforming the whole design.\n" - "All action takes place in a single environment. Objects are presented to the user without " - "breaking the continuity of experience even as they transform and reorganize.\n" - "Motion is meaningful and appropriate, serving to focus attention and maintain continuity. " - "Feedback is subtle yet clear. Transitions are efficient yet coherent.\n\n" - - "3D world.\n\n" - - "The material environment is a 3D space, which means all objects have x, y, and z " - "dimensions. The z-axis is perpendicularly aligned to the plane of the display, with the " - "positive z-axis extending towards the viewer. Every sheet of material occupies a single " - "position along the z-axis and has a standard 1dp thickness.\n" - "On the web, the z-axis is used for layering and not for perspective. The 3D world is " - "emulated by manipulating the y-axis.\n\n" - - "Light and shadow.\n\n" - - "Within the material environment, virtual lights illuminate the scene. Key lights create " - "directional shadows, while ambient light creates soft shadows from all angles.\n" - "Shadows in the material environment are cast by these two light sources. In Android " - "development, shadows occur when light sources are blocked by sheets of material at " - "various positions along the z-axis. On the web, shadows are depicted by manipulating the " - "y-axis only. The following example shows the card with a height of 6dp.\n\n" - - "Resting elevation.\n\n" - - "All material objects, regardless of size, have a resting elevation, or default elevation " - "that does not change. If an object changes elevation, it should return to its resting " - "elevation as soon as possible.\n\n" - - "Component elevations.\n\n" - - "The resting elevation for a component type is consistent across apps (e.g., FAB elevation " - "does not vary from 6dp in one app to 16dp in another app).\n" - "Components may have different resting elevations across platforms, depending on the depth " - "of the environment (e.g., TV has a greater depth than mobile or desktop).\n\n" - - "Responsive elevation and dynamic elevation offsets.\n\n" - - "Some component types have responsive elevation, meaning they change elevation in response " - "to user input (e.g., normal, focused, and pressed) or system events. These elevation " - "changes are consistently implemented using dynamic elevation offsets.\n" - "Dynamic elevation offsets are the goal elevation that a component moves towards, relative " - "to the component’s resting state. They ensure that elevation changes are consistent " - "across actions and component types. For example, all components that lift on press have " - "the same elevation change relative to their resting elevation.\n" - "Once the input event is completed or cancelled, the component will return to its resting " - "elevation.\n\n" - - "Avoiding elevation interference.\n\n" - - "Components with responsive elevations may encounter other components as they move between " - "their resting elevations and dynamic elevation offsets. Because material cannot pass " - "through other material, components avoid interfering with one another any number of ways, " - "whether on a per component basis or using the entire app layout.\n" - "On a component level, components can move or be removed before they cause interference. " - "For example, a floating action button (FAB) can disappear or move off screen before a " - "user picks up a card, or it can move if a snackbar appears.\n" - "On the layout level, design your app layout to minimize opportunities for interference. " - "For example, position the FAB to one side of stream of a cards so the FAB won’t interfere " - "when a user tries to pick up one of cards.\n\n" - </string> + <string name="gilded">x%1$d</string> </resources> |