From 07b32b39007136ac8f6e326da791562a107716ad Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Mon, 20 Aug 2018 00:04:49 +0800 Subject: Rename some classes. Change the logic of getting the subreddit icon. Prepare to display posts in ViewSubredditDetailActivity. --- .../infinityforreddit/BestPostData.java | 243 --------- .../infinityforreddit/BestPostFragment.java | 32 +- .../BestPostPaginationScrollListener.java | 166 ------- .../BestPostRecyclerViewAdapter.java | 542 --------------------- .../infinityforreddit/FetchSubscribedThing.java | 1 + .../infinityforreddit/JSONUtils.java | 1 + .../LoadSubredditIconAsyncTask.java | 8 +- .../infinityforreddit/MainActivity.java | 6 +- .../infinityforreddit/ParseBestPost.java | 212 -------- .../infinityforreddit/ParsePost.java | 212 ++++++++ .../infinityforreddit/ParseSubscribedThing.java | 32 +- .../infinityforreddit/PostData.java | 243 +++++++++ .../PostPaginationScrollListener.java | 166 +++++++ .../infinityforreddit/PostRecyclerViewAdapter.java | 542 +++++++++++++++++++++ .../infinityforreddit/ViewPostDetailActivity.java | 14 +- .../ViewSubredditDetailActivity.java | 6 + 16 files changed, 1220 insertions(+), 1206 deletions(-) delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BestPostData.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BestPostPaginationScrollListener.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BestPostRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/ParseBestPost.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/PostData.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/PostPaginationScrollListener.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java (limited to 'app/src/main/java/ml') diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BestPostData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BestPostData.java deleted file mode 100644 index ce998cff..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BestPostData.java +++ /dev/null @@ -1,243 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Created by alex on 3/1/18. - */ - -class BestPostData implements Parcelable { - static final int TEXT_TYPE = 0; - static final int IMAGE_TYPE = 1; - static final int LINK_TYPE = 2; - static final int VIDEO_TYPE = 3; - static final int GIF_VIDEO_TYPE = 4; - static final int NO_PREVIEW_LINK_TYPE = 5; - - private String id; - private String fullName; - private String subredditName; - private String subredditIconUrl; - private String postTime; - private String title; - private String selfText; - private String previewUrl; - private String url; - private String videoUrl; - private String gifOrVideoDownloadUrl; - private String permalink; - private int score; - private int postType; - private int voteType; - private boolean nsfw; - private boolean isDashVideo; - private boolean isDownloadableGifOrVideo; - - BestPostData(String id, String fullName, String subredditName, String postTime, String title, String previewUrl, String permalink, int score, int postType, int voteType, boolean nsfw, boolean isDashVideo) { - this.id = id; - this.fullName = fullName; - this.subredditName = subredditName; - this.postTime = postTime; - this.title = title; - this.previewUrl = previewUrl; - this.permalink = RedditUtils.API_BASE_URI + permalink; - this.score = score; - this.postType = postType; - this.voteType = voteType; - this.nsfw = nsfw; - this.isDashVideo = isDashVideo; - } - - BestPostData(String id, String fullName, String subredditName, String postTime, String title, String previewUrl, String url, String permalink, int score, int postType, int voteType, boolean nsfw) { - this.id = id; - this.fullName = fullName; - this.subredditName = subredditName; - this.postTime = postTime; - this.title = title; - this.previewUrl = previewUrl; - this.url = url; - this.permalink = RedditUtils.API_BASE_URI + permalink; - this.score = score; - this.postType = postType; - this.voteType = voteType; - this.nsfw = nsfw; - } - - BestPostData(String id, String fullName, String subredditName, String postTime, String title, String permalink, int score, int postType, int voteType, boolean nsfw) { - this.id = id; - this.fullName = fullName; - this.subredditName = subredditName; - this.postTime = postTime; - this.title = title; - this.permalink = RedditUtils.API_BASE_URI + permalink; - this.score = score; - this.postType = postType; - this.voteType = voteType; - this.nsfw = nsfw; - } - - protected BestPostData(Parcel in) { - id = in.readString(); - fullName = in.readString(); - subredditName = in.readString(); - subredditIconUrl = in.readString(); - postTime = in.readString(); - title = in.readString(); - selfText = in.readString(); - previewUrl = in.readString(); - url = in.readString(); - videoUrl = in.readString(); - gifOrVideoDownloadUrl = in.readString(); - permalink = in.readString(); - score = in.readInt(); - postType = in.readInt(); - voteType = in.readInt(); - nsfw = in.readByte() != 0; - isDashVideo = in.readByte() != 0; - isDownloadableGifOrVideo = in.readByte() != 0; - } - - public static final Creator CREATOR = new Creator() { - @Override - public BestPostData createFromParcel(Parcel in) { - return new BestPostData(in); - } - - @Override - public BestPostData[] newArray(int size) { - return new BestPostData[size]; - } - }; - - public String getId() { - return id; - } - - public String getFullName() { - return fullName; - } - - public String getSubredditName() { - return subredditName; - } - - public String getSubredditIconUrl() { - return subredditIconUrl; - } - - public void setSubredditIconUrl(String subredditIconUrl) { - this.subredditIconUrl = subredditIconUrl; - } - - public String getPostTime() { - return postTime; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getTitle() { - return title; - } - - public void setSelfText(String selfText) { - this.selfText = selfText; - } - - public String getSelfText() { - return selfText; - } - - public String getPreviewUrl() { - return previewUrl; - } - - public String getUrl() { - return url; - } - - public void setVideoUrl(String videoUrl) { - this.videoUrl = videoUrl; - } - - public String getVideoUrl() { - return videoUrl; - } - - public String getGifOrVideoDownloadUrl() { - return gifOrVideoDownloadUrl; - } - - public void setGifOrVideoDownloadUrl(String gifOrVideoDownloadUrl) { - this.gifOrVideoDownloadUrl = gifOrVideoDownloadUrl; - } - - public String getPermalink() { - return permalink; - } - - public void setScore(int score) { - this.score = score; - } - - public int getScore() { - return score; - } - - public int getPostType() { - return postType; - } - - public void setVoteType(int voteType) { - this.voteType = voteType; - } - - public int getVoteType() { - return voteType; - } - - public boolean getNSFW() { - return nsfw; - } - - @Override - public int describeContents() { - return 0; - } - - public boolean isDashVideo() { - return isDashVideo; - } - - public void setDownloadableGifOrVideo(boolean isDownloadableGifOrVideo) { - this.isDownloadableGifOrVideo = isDownloadableGifOrVideo; - } - - public boolean isDownloadableGifOrVideo() { - return isDownloadableGifOrVideo; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeString(id); - parcel.writeString(fullName); - parcel.writeString(subredditName); - parcel.writeString(subredditIconUrl); - parcel.writeString(postTime); - parcel.writeString(title); - parcel.writeString(selfText); - parcel.writeString(previewUrl); - parcel.writeString(url); - parcel.writeString(videoUrl); - parcel.writeString(gifOrVideoDownloadUrl); - parcel.writeString(permalink); - parcel.writeInt(score); - parcel.writeInt(postType); - parcel.writeInt(voteType); - parcel.writeByte((byte) (nsfw ? 1 : 0)); - parcel.writeByte((byte) (isDashVideo ? 1 : 0)); - parcel.writeByte((byte) (isDownloadableGifOrVideo ? 1 : 0)); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BestPostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BestPostFragment.java index ab3118c7..87594ef0 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BestPostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/BestPostFragment.java @@ -41,10 +41,10 @@ public class BestPostFragment extends Fragment { private RecyclerView mBestPostRecyclerView; private LinearLayoutManager mLinearLayoutManager; private ProgressBar mProgressBar; - private ArrayList mBestPostData; + private ArrayList mPostData; private String mLastItem; private PaginationSynchronizer mPaginationSynchronizer; - private BestPostRecyclerViewAdapter mAdapter; + private PostRecyclerViewAdapter mAdapter; private String bestPostDataParcelableState = "BPDPS"; private String lastItemState = "LIS"; @@ -64,11 +64,11 @@ public class BestPostFragment extends Fragment { super.onActivityCreated(savedInstanceState); if(savedInstanceState != null) { if(savedInstanceState.containsKey(bestPostDataParcelableState)) { - mBestPostData = savedInstanceState.getParcelableArrayList(bestPostDataParcelableState); + mPostData = savedInstanceState.getParcelableArrayList(bestPostDataParcelableState); mLastItem = savedInstanceState.getString(lastItemState); - mAdapter = new BestPostRecyclerViewAdapter(getActivity(), mBestPostData, mPaginationSynchronizer, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue); + mAdapter = new PostRecyclerViewAdapter(getActivity(), mPostData, mPaginationSynchronizer, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue); mBestPostRecyclerView.setAdapter(mAdapter); - mBestPostRecyclerView.addOnScrollListener(new BestPostPaginationScrollListener(getActivity(), mLinearLayoutManager, mAdapter, mLastItem, mBestPostData, mPaginationSynchronizer, + mBestPostRecyclerView.addOnScrollListener(new PostPaginationScrollListener(getActivity(), mLinearLayoutManager, mAdapter, mLastItem, mPostData, mPaginationSynchronizer, mAcquireAccessTokenRequestQueue, mPaginationSynchronizer.isLoading(), mPaginationSynchronizer.isLoadSuccess())); mProgressBar.setVisibility(View.GONE); } else { @@ -94,11 +94,11 @@ public class BestPostFragment extends Fragment { } if(mPaginationRequestQueue != null) { - mPaginationRequestQueue.cancelAll(BestPostPaginationScrollListener.class); + mPaginationRequestQueue.cancelAll(PostPaginationScrollListener.class); } - if(mBestPostData != null) { - outState.putParcelableArrayList(bestPostDataParcelableState, mBestPostData); + if(mPostData != null) { + outState.putParcelableArrayList(bestPostDataParcelableState, mPostData); outState.putString(lastItemState, mLastItem); outState.putParcelable(paginationSynchronizerState, mPaginationSynchronizer); } @@ -180,27 +180,27 @@ public class BestPostFragment extends Fragment { ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText("response", response); clipboard.setPrimaryClip(clip); - //new ParseBestPostDataAsyncTask(response, accessToken).execute(); - new ParseBestPost(getActivity(), new ParseBestPost.ParseBestPostListener() { + //new ParsePostDataAsyncTask(response, accessToken).execute(); + new ParsePost(getActivity(), new ParsePost.ParsePostListener() { @Override - public void onParseBestPostSuccess(ArrayList bestPostData, String lastItem) { - mBestPostData = bestPostData; + public void onParsePostSuccess(ArrayList bestPostData, String lastItem) { + mPostData = bestPostData; mLastItem = lastItem; - mAdapter = new BestPostRecyclerViewAdapter(getActivity(), bestPostData, mPaginationSynchronizer, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue); + mAdapter = new PostRecyclerViewAdapter(getActivity(), bestPostData, mPaginationSynchronizer, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue); mBestPostRecyclerView.setAdapter(mAdapter); - mBestPostRecyclerView.addOnScrollListener(new BestPostPaginationScrollListener(getActivity(), mLinearLayoutManager, mAdapter, lastItem, bestPostData, mPaginationSynchronizer, + mBestPostRecyclerView.addOnScrollListener(new PostPaginationScrollListener(getActivity(), mLinearLayoutManager, mAdapter, lastItem, bestPostData, mPaginationSynchronizer, mAcquireAccessTokenRequestQueue, mPaginationSynchronizer.isLoading(), mPaginationSynchronizer.isLoadSuccess())); mProgressBar.setVisibility(View.GONE); } @Override - public void onParseBestPostFail() { + public void onParsePostFail() { Toast.makeText(getActivity(), "Error parsing data", Toast.LENGTH_SHORT).show(); Log.i("Best post fetch error", "Error parsing data"); mProgressBar.setVisibility(View.GONE); } - }).parseBestPost(response, new ArrayList()); + }).parseBestPost(response, new ArrayList()); } } }, new Response.ErrorListener() { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BestPostPaginationScrollListener.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BestPostPaginationScrollListener.java deleted file mode 100644 index 41dbe0af..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BestPostPaginationScrollListener.java +++ /dev/null @@ -1,166 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.net.Uri; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.util.Log; -import android.widget.Toast; - -import com.android.volley.AuthFailureError; -import com.android.volley.Request; -import com.android.volley.RequestQueue; -import com.android.volley.Response; -import com.android.volley.VolleyError; -import com.android.volley.toolbox.StringRequest; -import com.android.volley.toolbox.Volley; - -import java.util.ArrayList; -import java.util.Map; - -/** - * Created by alex on 3/12/18. - */ - -class BestPostPaginationScrollListener extends RecyclerView.OnScrollListener { - private Context mContext; - private LinearLayoutManager mLayoutManager; - private BestPostRecyclerViewAdapter mAdapter; - private ArrayList mBestPostData; - private PaginationSynchronizer mPaginationSynchronizer; - private PaginationRetryNotifier mPaginationRetryNotifier; - private LastItemSynchronizer mLastItemSynchronizer; - private PaginationRequestQueueSynchronizer mPaginationRequestQueueSynchronizer; - - private boolean isLoading; - private boolean loadSuccess; - private String mLastItem; - private RequestQueue mRequestQueue; - private RequestQueue mAcquireAccessTokenRequestQueue; - - BestPostPaginationScrollListener(Context context, LinearLayoutManager layoutManager, BestPostRecyclerViewAdapter adapter, String lastItem, ArrayList bestPostData, PaginationSynchronizer paginationSynchronizer, - RequestQueue acquireAccessTokenRequestQueue, boolean isLoading, boolean loadSuccess) { - if(context != null) { - this.mContext = context; - this.mLayoutManager = layoutManager; - this.mAdapter = adapter; - this.mLastItem = lastItem; - this.mBestPostData = bestPostData; - this.mPaginationSynchronizer = paginationSynchronizer; - this.mAcquireAccessTokenRequestQueue = acquireAccessTokenRequestQueue; - this.isLoading = isLoading; - this.loadSuccess = loadSuccess; - - mRequestQueue = Volley.newRequestQueue(mContext); - mAcquireAccessTokenRequestQueue = Volley.newRequestQueue(mContext); - mPaginationRetryNotifier = new PaginationRetryNotifier() { - @Override - public void retry() { - fetchBestPost(1); - } - }; - mPaginationSynchronizer.setPaginationRetryNotifier(mPaginationRetryNotifier); - mLastItemSynchronizer = mPaginationSynchronizer.getLastItemSynchronizer(); - mPaginationRequestQueueSynchronizer = mPaginationSynchronizer.getPaginationRequestQueueSynchronizer(); - mPaginationRequestQueueSynchronizer.passQueue(mRequestQueue); - } - } - - @Override - public void onScrolled(RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); - if(!isLoading && loadSuccess) { - int visibleItemCount = mLayoutManager.getChildCount(); - int totalItemCount = mLayoutManager.getItemCount(); - int firstVisibleItemPosition = mLayoutManager.findFirstVisibleItemPosition(); - - if((visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) { - fetchBestPost(1); - } - } - } - - - private void fetchBestPost(final int refreshTime) { - if(refreshTime < 0) { - loadFailed(); - return; - } - - isLoading = true; - loadSuccess = false; - mPaginationSynchronizer.setLoading(true); - - Uri uri = Uri.parse(RedditUtils.OAUTH_API_BASE_URI + RedditUtils.BEST_POST_SUFFIX) - .buildUpon().appendQueryParameter(RedditUtils.AFTER_KEY, mLastItem) - .appendQueryParameter(RedditUtils.RAW_JSON_KEY, RedditUtils.RAW_JSON_VALUE).build(); - - StringRequest bestPostRequest = new StringRequest(Request.Method.GET, uri.toString(), new Response.Listener() { - @Override - public void onResponse(String response) { - ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText("response", response); - clipboard.setPrimaryClip(clip); - new ParseBestPost(mContext, new ParseBestPost.ParseBestPostListener() { - @Override - public void onParseBestPostSuccess(ArrayList bestPostData, String lastItem) { - mAdapter.notifyDataSetChanged(); - mLastItem = lastItem; - mLastItemSynchronizer.lastItemChanged(mLastItem); - - isLoading = false; - loadSuccess = true; - mPaginationSynchronizer.setLoading(false); - mPaginationSynchronizer.setLoadingState(true); - } - - @Override - public void onParseBestPostFail() { - Toast.makeText(mContext, "Error parsing data", Toast.LENGTH_SHORT).show(); - Log.i("Best post", "Error parsing data"); - loadFailed(); - } - }).parseBestPost(response, mBestPostData); - } - }, new Response.ErrorListener() { - @Override - public void onErrorResponse(VolleyError error) { - if (error instanceof AuthFailureError) { - //Access token expired - new AcquireAccessToken(mContext).refreshAccessToken(mAcquireAccessTokenRequestQueue, - new AcquireAccessToken.AcquireAccessTokenListener() { - @Override - public void onAcquireAccessTokenSuccess() { - fetchBestPost(refreshTime - 1); - } - - @Override - public void onAcquireAccessTokenFail() { - } - }); - } else { - Toast.makeText(mContext, "Error getting best post", Toast.LENGTH_SHORT).show(); - Log.i("best post", error.toString()); - loadFailed(); - } - } - }) { - @Override - public Map getHeaders() { - String accessToken = mContext.getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE).getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, ""); - return RedditUtils.getOAuthHeader(accessToken); - } - }; - bestPostRequest.setTag(BestPostPaginationScrollListener.class); - mRequestQueue.add(bestPostRequest); - } - - private void loadFailed() { - isLoading = false; - loadSuccess = false; - mPaginationSynchronizer.setLoading(false); - mPaginationSynchronizer.setLoadingState(false); - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BestPostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BestPostRecyclerViewAdapter.java deleted file mode 100644 index d5d8614f..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BestPostRecyclerViewAdapter.java +++ /dev/null @@ -1,542 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import android.content.Context; -import android.content.Intent; -import android.graphics.ColorFilter; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.customtabs.CustomTabsIntent; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.CardView; -import android.support.v7.widget.RecyclerView; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.TextView; -import android.widget.Toast; - -import com.android.volley.RequestQueue; -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.load.DataSource; -import com.bumptech.glide.load.engine.GlideException; -import com.bumptech.glide.request.RequestListener; -import com.bumptech.glide.request.target.Target; - -import java.util.ArrayList; - -import de.hdodenhof.circleimageview.CircleImageView; - -/** - * Created by alex on 2/25/18. - */ - -class BestPostRecyclerViewAdapter extends RecyclerView.Adapter { - private ArrayList mBestPostData; - private Context mContext; - private PaginationSynchronizer mPaginationSynchronizer; - private RequestQueue mVoteThingRequestQueue; - private RequestQueue mAcquireAccessTokenRequestQueue; - private RequestManager glide; - private SubredditDao subredditDao; - private boolean isLoadingMorePostSuccess; - private boolean canStartActivity; - - private static final int VIEW_TYPE_DATA = 0; - private static final int VIEW_TYPE_LOADING = 1; - - - BestPostRecyclerViewAdapter(Context context, ArrayList bestPostData, PaginationSynchronizer paginationSynchronizer, - RequestQueue voteThingRequestQueue, RequestQueue acquireAccessTokenRequestQueue) { - if(context != null) { - mContext = context; - mBestPostData = bestPostData; - mPaginationSynchronizer = paginationSynchronizer; - mVoteThingRequestQueue = voteThingRequestQueue; - mAcquireAccessTokenRequestQueue = acquireAccessTokenRequestQueue; - isLoadingMorePostSuccess = true; - canStartActivity = true; - glide = Glide.with(mContext); - subredditDao = SubredditRoomDatabase.getDatabase(mContext).subredditDao(); - } - } - - void setCanStartActivity(boolean canStartActivity) { - this.canStartActivity = canStartActivity; - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - if(viewType == VIEW_TYPE_DATA) { - CardView cardView = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_best_post, parent, false); - return new DataViewHolder(cardView); - } else { - LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_progress_bar, parent, false); - return new LoadingViewHolder(linearLayout); - } - } - - @Override - public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) { - if(holder instanceof DataViewHolder) { - if(mBestPostData.get(position) == null) { - Log.i("is null", Integer.toString(position)); - } else { - final String id = mBestPostData.get(position).getFullName(); - final String subredditName = mBestPostData.get(position).getSubredditName(); - final String postTime = mBestPostData.get(position).getPostTime(); - final String title = mBestPostData.get(position).getTitle(); - final String permalink = mBestPostData.get(position).getPermalink(); - int voteType = mBestPostData.get(position).getVoteType(); - boolean nsfw = mBestPostData.get(position).getNSFW(); - - if(mBestPostData.get(position).getSubredditIconUrl() == null) { - new LoadSubredditIconAsyncTask(mContext, ((DataViewHolder) holder).subredditIconCircleImageView, - subredditDao, subredditName, mBestPostData.get(position)).execute(); - } else if(!mBestPostData.get(position).getSubredditIconUrl().equals("")) { - glide.load(mBestPostData.get(position).getSubredditIconUrl()).into(((DataViewHolder) holder).subredditIconCircleImageView); - } else { - glide.load(R.drawable.subreddit_default_icon).into(((DataViewHolder) holder).subredditIconCircleImageView); - } - - ((DataViewHolder) holder).cardView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if(canStartActivity) { - canStartActivity = false; - Intent intent = new Intent(mContext, ViewPostDetailActivity.class); - intent.putExtra(ViewPostDetailActivity.EXTRA_TITLE, title); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, mBestPostData.get(position)); - mContext.startActivity(intent); - } - } - }); - - ((DataViewHolder) holder).subredditNameTextView.setText(subredditName); - ((DataViewHolder) holder).postTimeTextView.setText(postTime); - ((DataViewHolder) holder).titleTextView.setText(title); - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mBestPostData.get(position).getScore())); - - if(nsfw) { - ((DataViewHolder) holder).nsfwTextView.setVisibility(View.VISIBLE); - } - - switch (voteType) { - case 1: - //Upvote - ((DataViewHolder) holder).upvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN); - break; - case -1: - //Downvote - ((DataViewHolder) holder).downvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN); - break; - } - - if(mBestPostData.get(position).getPostType() != BestPostData.TEXT_TYPE && mBestPostData.get(position).getPostType() != BestPostData.NO_PREVIEW_LINK_TYPE) { - ((DataViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); - ((DataViewHolder) holder).progressBar.setVisibility(View.VISIBLE); - ((DataViewHolder) holder).imageView.setVisibility(View.VISIBLE); - } - - switch (mBestPostData.get(position).getPostType()) { - case BestPostData.IMAGE_TYPE: - ((DataViewHolder) holder).typeTextView.setText("IMAGE"); - final String previewImageUrl = mBestPostData.get(position).getPreviewUrl(); - final String imageUrl = mBestPostData.get(position).getUrl(); - glide.load(previewImageUrl).listener(new RequestListener() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - ((DataViewHolder) holder).progressBar.setVisibility(View.GONE); - return false; - } - }).into(((DataViewHolder) holder).imageView); - ((DataViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Intent intent = new Intent(mContext, ViewImageActivity.class); - intent.putExtra(ViewImageActivity.IMAGE_URL_KEY, imageUrl); - intent.putExtra(ViewImageActivity.TITLE_KEY, title); - intent.putExtra(ViewImageActivity.SUBREDDIT_KEY, subredditName); - intent.putExtra(ViewImageActivity.ID_KEY, id); - mContext.startActivity(intent); - } - }); - break; - case BestPostData.LINK_TYPE: - ((DataViewHolder) holder).typeTextView.setText("LINK"); - String linkPreviewUrl = mBestPostData.get(position).getPreviewUrl(); - glide.load(linkPreviewUrl).listener(new RequestListener() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - ((DataViewHolder) holder).progressBar.setVisibility(View.GONE); - return false; - } - }).into(((DataViewHolder) holder).imageView); - final String linkUrl = mBestPostData.get(position).getUrl(); - ((DataViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); - // add share action to menu list - builder.addDefaultShareMenuItem(); - builder.setToolbarColor(mContext.getResources().getColor(R.color.colorPrimary)); - CustomTabsIntent customTabsIntent = builder.build(); - customTabsIntent.launchUrl(mContext, Uri.parse(linkUrl)); - } - }); - break; - case BestPostData.GIF_VIDEO_TYPE: - ((DataViewHolder) holder).typeTextView.setText("GIF"); - String gifVideoPreviewUrl = mBestPostData.get(position).getPreviewUrl(); - glide.load(gifVideoPreviewUrl).listener(new RequestListener() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - ((DataViewHolder) holder).progressBar.setVisibility(View.GONE); - return false; - } - }).into(((DataViewHolder) holder).imageView); - - String gifVideoUrl = mBestPostData.get(position).getVideoUrl(); - final Uri gifVideoUri = Uri.parse(gifVideoUrl); - - ((DataViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Intent intent = new Intent(mContext, ViewVideoActivity.class); - intent.setData(gifVideoUri); - intent.putExtra(ViewVideoActivity.TITLE_KEY, title); - intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, mBestPostData.get(position).isDashVideo()); - intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, mBestPostData.get(position).isDownloadableGifOrVideo()); - if(mBestPostData.get(position).isDownloadableGifOrVideo()) { - intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, mBestPostData.get(position).getGifOrVideoDownloadUrl()); - intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, subredditName); - intent.putExtra(ViewVideoActivity.ID_KEY, id); - } - mContext.startActivity(intent); - } - }); - break; - case BestPostData.VIDEO_TYPE: - ((DataViewHolder) holder).typeTextView.setText("VIDEO"); - String videoPreviewUrl = mBestPostData.get(position).getPreviewUrl(); - glide.load(videoPreviewUrl).listener(new RequestListener() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - ((DataViewHolder) holder).progressBar.setVisibility(View.GONE); - return false; - } - }).into(((DataViewHolder) holder).imageView); - - String videoUrl = mBestPostData.get(position).getVideoUrl(); - final Uri videoUri = Uri.parse(videoUrl); - - ((DataViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Intent intent = new Intent(mContext, ViewVideoActivity.class); - intent.setData(videoUri); - intent.putExtra(ViewVideoActivity.TITLE_KEY, title); - intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, mBestPostData.get(position).isDashVideo()); - intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, mBestPostData.get(position).isDownloadableGifOrVideo()); - if(mBestPostData.get(position).isDownloadableGifOrVideo()) { - intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, mBestPostData.get(position).getGifOrVideoDownloadUrl()); - intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, subredditName); - intent.putExtra(ViewVideoActivity.ID_KEY, id); - } - mContext.startActivity(intent); - } - }); - break; - case BestPostData.NO_PREVIEW_LINK_TYPE: - ((DataViewHolder) holder).typeTextView.setText("LINK"); - final String noPreviewLinkUrl = mBestPostData.get(position).getUrl(); - ((DataViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); - ((DataViewHolder) holder).noPreviewLinkImageView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); - // add share action to menu list - builder.addDefaultShareMenuItem(); - builder.setToolbarColor(mContext.getResources().getColor(R.color.colorPrimary)); - CustomTabsIntent customTabsIntent = builder.build(); - customTabsIntent.launchUrl(mContext, Uri.parse(noPreviewLinkUrl)); - } - }); - break; - default: - ((DataViewHolder) holder).typeTextView.setText("TEXT"); - } - - ((DataViewHolder) holder).upvoteButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - final boolean isDownvotedBefore = ((DataViewHolder) holder).downvoteButton.getColorFilter() != null; - - final ColorFilter downvoteButtonColorFilter = ((DataViewHolder) holder).downvoteButton.getColorFilter(); - ((DataViewHolder) holder).downvoteButton.clearColorFilter(); - - 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(mBestPostData.get(position).getScore() + 2)); - } else { - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mBestPostData.get(position).getScore() + 1)); - } - - new VoteThing(mContext, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position) { - mBestPostData.get(position).setVoteType(1); - if(isDownvotedBefore) { - mBestPostData.get(position).setScore(mBestPostData.get(position).getScore() + 2); - } else { - mBestPostData.get(position).setScore(mBestPostData.get(position).getScore() + 1); - } - } - - @Override - public void onVoteThingFail(int position) { - Toast.makeText(mContext, "Cannot upvote this post", Toast.LENGTH_SHORT).show(); - ((DataViewHolder) holder).upvoteButton.clearColorFilter(); - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mBestPostData.get(position).getScore())); - ((DataViewHolder) holder).downvoteButton.setColorFilter(downvoteButtonColorFilter); - } - }, id, RedditUtils.DIR_UPVOTE, ((DataViewHolder) holder).getAdapterPosition(), 1); - } else { - //Upvoted before - ((DataViewHolder) holder).upvoteButton.clearColorFilter(); - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mBestPostData.get(position).getScore() - 1)); - - new VoteThing(mContext, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position) { - mBestPostData.get(position).setVoteType(0); - mBestPostData.get(position).setScore(mBestPostData.get(position).getScore() - 1); - } - - @Override - public void onVoteThingFail(int position) { - Toast.makeText(mContext, "Cannot unvote this post", Toast.LENGTH_SHORT).show(); - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mBestPostData.get(position).getScore() + 1)); - ((DataViewHolder) holder).upvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN); - mBestPostData.get(position).setScore(mBestPostData.get(position).getScore() + 1); - } - }, id, RedditUtils.DIR_UNVOTE, ((DataViewHolder) holder).getAdapterPosition(), 1); - } - } - }); - - ((DataViewHolder) holder).downvoteButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - final boolean isUpvotedBefore = ((DataViewHolder) holder).upvoteButton.getColorFilter() != null; - - final ColorFilter upvoteButtonColorFilter = ((DataViewHolder) holder).upvoteButton.getColorFilter(); - ((DataViewHolder) holder).upvoteButton.clearColorFilter(); - 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(mBestPostData.get(position).getScore() - 2)); - } else { - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mBestPostData.get(position).getScore() - 1)); - } - - new VoteThing(mContext, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position) { - mBestPostData.get(position).setVoteType(-1); - if(isUpvotedBefore) { - mBestPostData.get(position).setScore(mBestPostData.get(position).getScore() - 2); - } else { - mBestPostData.get(position).setScore(mBestPostData.get(position).getScore() - 1); - } - } - - @Override - public void onVoteThingFail(int position) { - Toast.makeText(mContext, "Cannot downvote this post", Toast.LENGTH_SHORT).show(); - ((DataViewHolder) holder).downvoteButton.clearColorFilter(); - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mBestPostData.get(position).getScore())); - ((DataViewHolder) holder).upvoteButton.setColorFilter(upvoteButtonColorFilter); - } - }, id, RedditUtils.DIR_DOWNVOTE, holder.getAdapterPosition(), 1); - } else { - //Down voted before - ((DataViewHolder) holder).downvoteButton.clearColorFilter(); - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mBestPostData.get(position).getScore() + 1)); - - new VoteThing(mContext, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position) { - mBestPostData.get(position).setVoteType(0); - mBestPostData.get(position).setScore(mBestPostData.get(position).getScore()); - } - - @Override - public void onVoteThingFail(int position) { - Toast.makeText(mContext, "Cannot unvote this post", Toast.LENGTH_SHORT).show(); - ((DataViewHolder) holder).downvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN); - ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mBestPostData.get(position).getScore())); - mBestPostData.get(position).setScore(mBestPostData.get(position).getScore()); - } - }, id, RedditUtils.DIR_UNVOTE, holder.getAdapterPosition(), 1); - } - } - }); - - ((DataViewHolder) holder).shareButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("text/plain"); - String extraText = title + "\n" + permalink; - intent.putExtra(Intent.EXTRA_TEXT, extraText); - mContext.startActivity(Intent.createChooser(intent, "Share")); - } - }); - } - } else if(holder instanceof LoadingViewHolder) { - ((LoadingViewHolder) holder).retryButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - mPaginationSynchronizer.getPaginationRetryNotifier().retry(); - ((LoadingViewHolder) holder).progressBar.setVisibility(View.VISIBLE); - ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.GONE); - } - }); - - PaginationNotifier mPaginationNotifier = new PaginationNotifier() { - @Override - public void LoadMorePostSuccess() { - isLoadingMorePostSuccess = true; - } - - @Override - public void LoadMorePostFail() { - ((LoadingViewHolder) holder).progressBar.setVisibility(View.GONE); - ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); - isLoadingMorePostSuccess = false; - } - }; - - mPaginationSynchronizer.setPaginationNotifier(mPaginationNotifier); - - if(!mPaginationSynchronizer.isLoadSuccess()) { - ((LoadingViewHolder) holder).progressBar.setVisibility(View.GONE); - ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); - } - } - } - - @Override - public int getItemCount() { - return mBestPostData.size() + 1; - } - - @Override - public int getItemViewType(int position) { - return (position >= mBestPostData.size() ? VIEW_TYPE_LOADING : VIEW_TYPE_DATA); - } - - class DataViewHolder extends RecyclerView.ViewHolder { - private CardView cardView; - private CircleImageView subredditIconCircleImageView; - private TextView subredditNameTextView; - private TextView postTimeTextView; - private TextView titleTextView; - private TextView typeTextView; - private TextView nsfwTextView; - private RelativeLayout relativeLayout; - private ProgressBar progressBar; - private ImageView imageView; - private ImageView noPreviewLinkImageView; - private ImageView upvoteButton; - private TextView scoreTextView; - private ImageView downvoteButton; - private ImageView shareButton; - - DataViewHolder(CardView itemView) { - super(itemView); - 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); - 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); - 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); - imageView = itemView.findViewById(R.id.image_view_best_post_item); - noPreviewLinkImageView = itemView.findViewById(R.id.image_view_no_preview_link_best_post_item); - - upvoteButton = itemView.findViewById(R.id.plus_button_item_best_post); - scoreTextView = itemView.findViewById(R.id.score_text_view_item_best_post); - downvoteButton = itemView.findViewById(R.id.minus_button_item_best_post); - shareButton = itemView.findViewById(R.id.share_button_item_best_post); - } - } - - class LoadingViewHolder extends RecyclerView.ViewHolder { - private ProgressBar progressBar; - private RelativeLayout relativeLayout; - private Button retryButton; - - LoadingViewHolder(LinearLayout itemView) { - super(itemView); - progressBar = itemView.findViewById(R.id.progress_bar_footer_progress_bar_item); - relativeLayout = itemView.findViewById(R.id.relative_layout_footer_progress_bar_item); - retryButton = itemView.findViewById(R.id.retry_button_footer_progress_bar_item); - } - } - - @Override - public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - if(holder instanceof DataViewHolder) { - glide.clear(((DataViewHolder) holder).imageView); - ((DataViewHolder) holder).relativeLayout.setVisibility(View.GONE); - ((DataViewHolder) holder).nsfwTextView.setVisibility(View.GONE); - ((DataViewHolder) holder).progressBar.setVisibility(View.GONE); - ((DataViewHolder) holder).imageView.setVisibility(View.GONE); - ((DataViewHolder) holder).noPreviewLinkImageView.setVisibility(View.GONE); - ((DataViewHolder) holder).upvoteButton.clearColorFilter(); - ((DataViewHolder) holder).downvoteButton.clearColorFilter(); - } else if(holder instanceof LoadingViewHolder) { - if(isLoadingMorePostSuccess) { - ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.GONE); - ((LoadingViewHolder) holder).progressBar.setVisibility(View.VISIBLE); - } else { - ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); - ((LoadingViewHolder) holder).progressBar.setVisibility(View.GONE); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchSubscribedThing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchSubscribedThing.java index d30bfa7f..be468f7a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchSubscribedThing.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchSubscribedThing.java @@ -66,6 +66,7 @@ class FetchSubscribedThing { String lastItem) { mSubscribedSubredditData = subscribedSubredditData; mSubscribedUserData = subscribedUserData; + mSubredditData = subredditData; mLastItem = lastItem; if(mLastItem.equals("null")) { mFetchSubscribedSubredditsListener.onFetchSubscribedSubredditsSuccess(mSubscribedSubredditData, diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java index 60ea1c98..81d2a77f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java @@ -54,6 +54,7 @@ class JSONUtils { static final String SUBREDDIT_KEY = "subreddit"; static final String BANNER_IMG_KEY = "banner_img"; static final String ICON_IMG_KEY = "icon_img"; + static final String COMMUNITY_ICON_KEY = "community_icon"; static final String LINK_KARMA_KEY = "link_karma"; static final String COMMENT_KARMA_KEY = "comment_karma"; static final String DISPLAY_NAME = "display_name"; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java index e75343d3..928951fc 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java @@ -16,16 +16,16 @@ class LoadSubredditIconAsyncTask extends AsyncTask { private SubredditDao subredditDao; private String subredditName; private String iconImageUrl; - private BestPostData bestPostData; + private PostData postData; LoadSubredditIconAsyncTask(Context context, CircleImageView iconImageView, SubredditDao subredditDao, String subredditName, - BestPostData bestPostData) { + PostData postData) { contextWeakReference = new WeakReference<>(context); circleImageViewWeakReference = new WeakReference<>(iconImageView); this.subredditDao = subredditDao; this.subredditName = subredditName; - this.bestPostData = bestPostData; + this.postData = postData; } @Override @@ -52,6 +52,6 @@ class LoadSubredditIconAsyncTask extends AsyncTask { } } - bestPostData.setSubredditIconUrl(iconImageUrl); + postData.setSubredditIconUrl(iconImageUrl); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java index ca31c815..b07bbd4c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java @@ -17,6 +17,7 @@ import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; +import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.TextView; @@ -165,6 +166,7 @@ public class MainActivity extends AppCompatActivity { @Override public void onChanged(@Nullable final List subscribedUserData) { if(!mIsInserting) { + Log.i("view", "observed"); if(subscribedUserData == null || subscribedUserData.size() == 0) { followingLabelTextView.setVisibility(View.GONE); } else { @@ -219,7 +221,7 @@ public class MainActivity extends AppCompatActivity { @Override public void onFetchUserInfoFail() { - + mFetchUserInfoSuccess = false; } }, 1); } @@ -251,7 +253,7 @@ public class MainActivity extends AppCompatActivity { @Override public void onFetchSubscribedSubredditsFail() { - + mInsertSuccess = false; } }, 1); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseBestPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseBestPost.java deleted file mode 100644 index e8168e0f..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseBestPost.java +++ /dev/null @@ -1,212 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import android.content.Context; -import android.os.AsyncTask; -import android.util.Log; -import android.widget.Toast; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; - -/** - * Created by alex on 3/21/18. - */ - -class ParseBestPost { - - interface ParseBestPostListener { - void onParseBestPostSuccess(ArrayList bestPostData, String lastItem); - void onParseBestPostFail(); - } - - private Context mContext; - private ParseBestPostListener mParseBetPostListener; - - ParseBestPost(Context context, ParseBestPostListener parseBestPostListener) { - mContext = context; - mParseBetPostListener = parseBestPostListener; - } - - void parseBestPost(String response, ArrayList bestPostData) { - new ParseBestPostDataAsyncTask(response, bestPostData).execute(); - } - - private class ParseBestPostDataAsyncTask extends AsyncTask { - private JSONObject jsonResponse; - private ArrayList bestPostData; - private ArrayList newBestPostData; - private String lastItem; - private boolean parseFailed; - - ParseBestPostDataAsyncTask(String response, ArrayList bestPostData) { - try { - jsonResponse = new JSONObject(response); - this.bestPostData = bestPostData; - newBestPostData = new ArrayList<>(); - parseFailed = false; - } catch (JSONException e) { - e.printStackTrace(); - Toast.makeText(mContext, "Error converting response to JSON", Toast.LENGTH_SHORT).show(); - } - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONArray allData = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - - lastItem = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); - for(int i = 0; i < allData.length(); i++) { - JSONObject data = allData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); - String id = data.getString(JSONUtils.ID_KEY); - String fullName = data.getString(JSONUtils.NAME_KEY); - String subredditName = data.getString(JSONUtils.SUBREDDIT_NAME_PREFIX_KEY); - long postTime = data.getLong(JSONUtils.CREATED_UTC_KEY) * 1000; - String title = data.getString(JSONUtils.TITLE_KEY); - int score = data.getInt(JSONUtils.SCORE_KEY); - int voteType; - boolean nsfw = data.getBoolean(JSONUtils.NSFW_KEY); - - if(data.isNull(JSONUtils.LIKES_KEY)) { - voteType = 0; - } else { - voteType = data.getBoolean(JSONUtils.LIKES_KEY) ? 1 : -1; - } - Calendar postTimeCalendar = Calendar.getInstance(); - postTimeCalendar.setTimeInMillis(postTime); - String formattedPostTime = new SimpleDateFormat("MMM d, YYYY, HH:mm", - mContext.getResources().getConfiguration().locale).format(postTimeCalendar.getTime()); - String permalink = data.getString(JSONUtils.PERMALINK_KEY); - - String previewUrl = ""; - if(data.has(JSONUtils.PREVIEW_KEY)) { - previewUrl = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0) - .getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY); - } - - if(data.has(JSONUtils.CROSSPOST_PARENT_LIST)) { - //Cross post - data = data.getJSONArray(JSONUtils.CROSSPOST_PARENT_LIST).getJSONObject(0); - parseData(data, permalink, newBestPostData, id, fullName, subredditName, - formattedPostTime, title, previewUrl, score, voteType, nsfw, i); - } else { - parseData(data, permalink, newBestPostData, id, fullName, subredditName, - formattedPostTime, title, previewUrl, score, voteType, nsfw, i); - } - } - } catch (JSONException e) { - Log.e("error", e.getMessage()); - Log.i("Best post", "Error parsing data"); - parseFailed = true; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - if(!parseFailed) { - bestPostData.addAll(newBestPostData); - mParseBetPostListener.onParseBestPostSuccess(bestPostData, lastItem); - } else { - mParseBetPostListener.onParseBestPostFail(); - } - } - } - - private void parseData(JSONObject data, String permalink, ArrayList bestPostData, - String id, String fullName, String subredditName, String formattedPostTime, String title, - String previewUrl, int score, int voteType, boolean nsfw, int i) throws JSONException { - boolean isVideo = data.getBoolean(JSONUtils.IS_VIDEO_KEY); - String url = data.getString(JSONUtils.URL_KEY); - - if(!data.has(JSONUtils.PREVIEW_KEY) && previewUrl.equals("")) { - if(url.contains(permalink)) { - //Text post - Log.i("text", Integer.toString(i)); - int postType = BestPostData.TEXT_TYPE; - BestPostData postData = new BestPostData(id, fullName, subredditName, formattedPostTime, title, permalink, score, postType, voteType, nsfw); - postData.setSelfText(data.getString(JSONUtils.SELF_TEXT_KEY).trim()); - bestPostData.add(postData); - } else { - //No preview link post - Log.i("no preview link", Integer.toString(i)); - int postType = BestPostData.NO_PREVIEW_LINK_TYPE; - BestPostData linkPostData = new BestPostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, url, permalink, score, postType, voteType, nsfw); - bestPostData.add(linkPostData); - } - } else if(isVideo) { - //Video post - Log.i("video", Integer.toString(i)); - JSONObject redditVideoObject = data.getJSONObject(JSONUtils.MEDIA_KEY).getJSONObject(JSONUtils.REDDIT_VIDEO_KEY); - int postType = BestPostData.VIDEO_TYPE; - String videoUrl = redditVideoObject.getString(JSONUtils.DASH_URL_KEY); - - BestPostData videoPostData = new BestPostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, permalink, score, postType, voteType, nsfw, true); - - videoPostData.setVideoUrl(videoUrl); - videoPostData.setDownloadableGifOrVideo(false); - - bestPostData.add(videoPostData); - } else if(data.has(JSONUtils.PREVIEW_KEY)){ - JSONObject variations = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0); - if (variations.has(JSONUtils.VARIANTS_KEY) && variations.getJSONObject(JSONUtils.VARIANTS_KEY).has(JSONUtils.MP4_KEY)) { - //Gif video post (MP4) - Log.i("gif video mp4", Integer.toString(i)); - int postType = BestPostData.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); - BestPostData post = new BestPostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, permalink, score, postType, voteType, nsfw, false); - - post.setVideoUrl(videoUrl); - post.setDownloadableGifOrVideo(true); - post.setGifOrVideoDownloadUrl(gifDownloadUrl); - - bestPostData.add(post); - } else if(data.getJSONObject(JSONUtils.PREVIEW_KEY).has(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY)) { - //Gif video post (Dash) - Log.i("gif video dash", Integer.toString(i)); - int postType = BestPostData.GIF_VIDEO_TYPE; - String videoUrl = data.getJSONObject(JSONUtils.PREVIEW_KEY) - .getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.DASH_URL_KEY); - - BestPostData post = new BestPostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, permalink, score, postType, voteType, nsfw, true); - - post.setVideoUrl(videoUrl); - post.setDownloadableGifOrVideo(false); - - bestPostData.add(post); - } else { - if (url.endsWith("jpg") || url.endsWith("png")) { - //Image post - Log.i("image", Integer.toString(i)); - int postType = BestPostData.IMAGE_TYPE; - bestPostData.add(new BestPostData(id, fullName, subredditName, formattedPostTime, title, url, url, permalink, score, postType, voteType, nsfw)); - } else { - //Link post - Log.i("link", Integer.toString(i)); - int postType = BestPostData.LINK_TYPE; - BestPostData linkPostData = new BestPostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, url, permalink, score, postType, voteType, nsfw); - bestPostData.add(linkPostData); - } - } - } else { - if (url.endsWith("jpg") || url.endsWith("png")) { - //Image post - Log.i("CP no preview image", Integer.toString(i)); - int postType = BestPostData.IMAGE_TYPE; - bestPostData.add(new BestPostData(id, fullName, subredditName, formattedPostTime, title, url, url, permalink, score, postType, voteType, nsfw)); - } else { - //Link post - Log.i("CP no preview link", Integer.toString(i)); - int postType = BestPostData.LINK_TYPE; - BestPostData linkPostData = new BestPostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, url, permalink, score, postType, voteType, nsfw); - bestPostData.add(linkPostData); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java new file mode 100644 index 00000000..579d5c04 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java @@ -0,0 +1,212 @@ +package ml.docilealligator.infinityforreddit; + +import android.content.Context; +import android.os.AsyncTask; +import android.util.Log; +import android.widget.Toast; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; + +/** + * Created by alex on 3/21/18. + */ + +class ParsePost { + + interface ParsePostListener { + void onParsePostSuccess(ArrayList postData, String lastItem); + void onParsePostFail(); + } + + private Context mContext; + private ParsePostListener mParseBetPostListener; + + ParsePost(Context context, ParsePostListener parsePostListener) { + mContext = context; + mParseBetPostListener = parsePostListener; + } + + void parseBestPost(String response, ArrayList postData) { + new ParsePostDataAsyncTask(response, postData).execute(); + } + + private class ParsePostDataAsyncTask extends AsyncTask { + private JSONObject jsonResponse; + private ArrayList postData; + private ArrayList newPostData; + private String lastItem; + private boolean parseFailed; + + ParsePostDataAsyncTask(String response, ArrayList postData) { + try { + jsonResponse = new JSONObject(response); + this.postData = postData; + newPostData = new ArrayList<>(); + parseFailed = false; + } catch (JSONException e) { + e.printStackTrace(); + Toast.makeText(mContext, "Error converting response to JSON", Toast.LENGTH_SHORT).show(); + } + } + + @Override + protected Void doInBackground(Void... voids) { + try { + JSONArray allData = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + + lastItem = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); + for(int i = 0; i < allData.length(); i++) { + JSONObject data = allData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); + String id = data.getString(JSONUtils.ID_KEY); + String fullName = data.getString(JSONUtils.NAME_KEY); + String subredditName = data.getString(JSONUtils.SUBREDDIT_NAME_PREFIX_KEY); + long postTime = data.getLong(JSONUtils.CREATED_UTC_KEY) * 1000; + String title = data.getString(JSONUtils.TITLE_KEY); + int score = data.getInt(JSONUtils.SCORE_KEY); + int voteType; + boolean nsfw = data.getBoolean(JSONUtils.NSFW_KEY); + + if(data.isNull(JSONUtils.LIKES_KEY)) { + voteType = 0; + } else { + voteType = data.getBoolean(JSONUtils.LIKES_KEY) ? 1 : -1; + } + Calendar postTimeCalendar = Calendar.getInstance(); + postTimeCalendar.setTimeInMillis(postTime); + String formattedPostTime = new SimpleDateFormat("MMM d, YYYY, HH:mm", + mContext.getResources().getConfiguration().locale).format(postTimeCalendar.getTime()); + String permalink = data.getString(JSONUtils.PERMALINK_KEY); + + String previewUrl = ""; + if(data.has(JSONUtils.PREVIEW_KEY)) { + previewUrl = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0) + .getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY); + } + + if(data.has(JSONUtils.CROSSPOST_PARENT_LIST)) { + //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); + } else { + parseData(data, permalink, newPostData, id, fullName, subredditName, + formattedPostTime, title, previewUrl, score, voteType, nsfw, i); + } + } + } catch (JSONException e) { + Log.e("error", e.getMessage()); + Log.i("Best post", "Error parsing data"); + parseFailed = true; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + if(!parseFailed) { + postData.addAll(newPostData); + mParseBetPostListener.onParsePostSuccess(postData, lastItem); + } else { + mParseBetPostListener.onParsePostFail(); + } + } + } + + private void parseData(JSONObject data, String permalink, ArrayList bestPostData, + String id, String fullName, String subredditName, String formattedPostTime, String title, + String previewUrl, int score, int voteType, boolean nsfw, int i) throws JSONException { + boolean isVideo = data.getBoolean(JSONUtils.IS_VIDEO_KEY); + String url = data.getString(JSONUtils.URL_KEY); + + if(!data.has(JSONUtils.PREVIEW_KEY) && previewUrl.equals("")) { + if(url.contains(permalink)) { + //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.setSelfText(data.getString(JSONUtils.SELF_TEXT_KEY).trim()); + bestPostData.add(postData); + } else { + //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); + bestPostData.add(linkPostData); + } + } else if(isVideo) { + //Video post + Log.i("video", Integer.toString(i)); + JSONObject redditVideoObject = data.getJSONObject(JSONUtils.MEDIA_KEY).getJSONObject(JSONUtils.REDDIT_VIDEO_KEY); + 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); + + videoPostData.setVideoUrl(videoUrl); + videoPostData.setDownloadableGifOrVideo(false); + + bestPostData.add(videoPostData); + } else if(data.has(JSONUtils.PREVIEW_KEY)){ + JSONObject variations = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0); + if (variations.has(JSONUtils.VARIANTS_KEY) && variations.getJSONObject(JSONUtils.VARIANTS_KEY).has(JSONUtils.MP4_KEY)) { + //Gif video post (MP4) + Log.i("gif video mp4", Integer.toString(i)); + 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); + + post.setVideoUrl(videoUrl); + post.setDownloadableGifOrVideo(true); + post.setGifOrVideoDownloadUrl(gifDownloadUrl); + + bestPostData.add(post); + } else if(data.getJSONObject(JSONUtils.PREVIEW_KEY).has(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY)) { + //Gif video post (Dash) + Log.i("gif video dash", Integer.toString(i)); + int postType = PostData.GIF_VIDEO_TYPE; + 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); + + post.setVideoUrl(videoUrl); + post.setDownloadableGifOrVideo(false); + + bestPostData.add(post); + } else { + if (url.endsWith("jpg") || url.endsWith("png")) { + //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)); + } 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); + bestPostData.add(linkPostData); + } + } + } else { + if (url.endsWith("jpg") || url.endsWith("png")) { + //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)); + } 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); + bestPostData.add(linkPostData); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java index cc1754ac..63b82702 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java @@ -18,17 +18,15 @@ class ParseSubscribedThing { void onParseSubscribedSubredditsFail(); } - private ParseSubscribedSubredditsListener mParseSubscribedSubredditsListener; - void parseSubscribedSubreddits(String response, ArrayList subscribedSubredditData, ArrayList subscribedUserData, ArrayList subredditData, ParseSubscribedSubredditsListener parseSubscribedSubredditsListener) { - mParseSubscribedSubredditsListener = parseSubscribedSubredditsListener; - new ParseSubscribedSubredditsAsyncTask(response, subscribedSubredditData, subscribedUserData, subredditData).execute(); + new ParseSubscribedSubredditsAsyncTask(response, subscribedSubredditData, subscribedUserData, subredditData, + parseSubscribedSubredditsListener).execute(); } - private class ParseSubscribedSubredditsAsyncTask extends AsyncTask { + private static class ParseSubscribedSubredditsAsyncTask extends AsyncTask { private JSONObject jsonResponse; private boolean parseFailed; private String lastItem; @@ -38,10 +36,12 @@ class ParseSubscribedThing { private ArrayList newSubscribedSubredditData; private ArrayList newSubscribedUserData; private ArrayList newSubredditData; + private ParseSubscribedSubredditsListener parseSubscribedSubredditsListener; ParseSubscribedSubredditsAsyncTask(String response, ArrayList subscribedSubredditData, ArrayList subscribedUserData, - ArrayList subredditData){ + ArrayList subredditData, + ParseSubscribedSubredditsListener parseSubscribedSubredditsListener){ try { jsonResponse = new JSONObject(response); parseFailed = false; @@ -51,9 +51,10 @@ class ParseSubscribedThing { newSubscribedSubredditData = new ArrayList<>(); newSubscribedUserData = new ArrayList<>(); newSubredditData = new ArrayList<>(); + this.parseSubscribedSubredditsListener = parseSubscribedSubredditsListener; } catch (JSONException e) { Log.i("user info json error", e.getMessage()); - mParseSubscribedSubredditsListener.onParseSubscribedSubredditsFail(); + parseSubscribedSubredditsListener.onParseSubscribedSubredditsFail(); } } @@ -66,12 +67,15 @@ class ParseSubscribedThing { String name = data.getString(JSONUtils.DISPLAY_NAME); String bannerUrl = data.getString(JSONUtils.BANNER_IMG_KEY); String iconUrl = data.getString(JSONUtils.ICON_IMG_KEY); - String id = children.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.NAME_KEY); - if(iconUrl.equals("null")) { - iconUrl = ""; + String id = data.getString(JSONUtils.NAME_KEY); + if(iconUrl.equals("") || iconUrl.equals("null")) { + iconUrl = data.getString(JSONUtils.COMMUNITY_ICON_KEY); + if(iconUrl.equals("null")) { + iconUrl = ""; + } } - if(children.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.SUBREDDIT_TYPE_KEY) + if(data.getString(JSONUtils.SUBREDDIT_TYPE_KEY) .equals(JSONUtils.SUBREDDIT_TYPE_VALUE_USER)) { //It's a user newSubscribedUserData.add(new SubscribedUserData(id, name.substring(2), iconUrl)); @@ -86,7 +90,7 @@ class ParseSubscribedThing { lastItem = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); } catch (JSONException e) { parseFailed = true; - Log.i("parse comment error", e.getMessage()); + Log.i("parse subscribed error", e.getMessage()); } return null; } @@ -97,10 +101,10 @@ class ParseSubscribedThing { subscribedSubredditData.addAll(newSubscribedSubredditData); subscribedUserData.addAll(newSubscribedUserData); subredditData.addAll(newSubredditData); - mParseSubscribedSubredditsListener.onParseSubscribedSubredditsSuccess(subscribedSubredditData, + parseSubscribedSubredditsListener.onParseSubscribedSubredditsSuccess(subscribedSubredditData, subscribedUserData, subredditData, lastItem); } else { - mParseSubscribedSubredditsListener.onParseSubscribedSubredditsFail(); + parseSubscribedSubredditsListener.onParseSubscribedSubredditsFail(); } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostData.java new file mode 100644 index 00000000..c91cc333 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostData.java @@ -0,0 +1,243 @@ +package ml.docilealligator.infinityforreddit; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Created by alex on 3/1/18. + */ + +class PostData implements Parcelable { + static final int TEXT_TYPE = 0; + static final int IMAGE_TYPE = 1; + static final int LINK_TYPE = 2; + static final int VIDEO_TYPE = 3; + static final int GIF_VIDEO_TYPE = 4; + static final int NO_PREVIEW_LINK_TYPE = 5; + + private String id; + private String fullName; + private String subredditName; + private String subredditIconUrl; + private String postTime; + private String title; + private String selfText; + private String previewUrl; + private String url; + private String videoUrl; + private String gifOrVideoDownloadUrl; + private String permalink; + private int score; + private int postType; + private int voteType; + private boolean nsfw; + 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) { + this.id = id; + this.fullName = fullName; + this.subredditName = subredditName; + this.postTime = postTime; + this.title = title; + this.previewUrl = previewUrl; + this.permalink = RedditUtils.API_BASE_URI + permalink; + this.score = score; + this.postType = postType; + this.voteType = voteType; + this.nsfw = nsfw; + 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) { + this.id = id; + this.fullName = fullName; + this.subredditName = subredditName; + this.postTime = postTime; + this.title = title; + this.previewUrl = previewUrl; + this.url = url; + this.permalink = RedditUtils.API_BASE_URI + permalink; + this.score = score; + this.postType = postType; + this.voteType = voteType; + this.nsfw = nsfw; + } + + PostData(String id, String fullName, String subredditName, String postTime, String title, String permalink, int score, int postType, int voteType, boolean nsfw) { + this.id = id; + this.fullName = fullName; + this.subredditName = subredditName; + this.postTime = postTime; + this.title = title; + this.permalink = RedditUtils.API_BASE_URI + permalink; + this.score = score; + this.postType = postType; + this.voteType = voteType; + this.nsfw = nsfw; + } + + protected PostData(Parcel in) { + id = in.readString(); + fullName = in.readString(); + subredditName = in.readString(); + subredditIconUrl = in.readString(); + postTime = in.readString(); + title = in.readString(); + selfText = in.readString(); + previewUrl = in.readString(); + url = in.readString(); + videoUrl = in.readString(); + gifOrVideoDownloadUrl = in.readString(); + permalink = in.readString(); + score = in.readInt(); + postType = in.readInt(); + voteType = in.readInt(); + nsfw = in.readByte() != 0; + isDashVideo = in.readByte() != 0; + isDownloadableGifOrVideo = in.readByte() != 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public PostData createFromParcel(Parcel in) { + return new PostData(in); + } + + @Override + public PostData[] newArray(int size) { + return new PostData[size]; + } + }; + + public String getId() { + return id; + } + + public String getFullName() { + return fullName; + } + + public String getSubredditName() { + return subredditName; + } + + public String getSubredditIconUrl() { + return subredditIconUrl; + } + + public void setSubredditIconUrl(String subredditIconUrl) { + this.subredditIconUrl = subredditIconUrl; + } + + public String getPostTime() { + return postTime; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getTitle() { + return title; + } + + public void setSelfText(String selfText) { + this.selfText = selfText; + } + + public String getSelfText() { + return selfText; + } + + public String getPreviewUrl() { + return previewUrl; + } + + public String getUrl() { + return url; + } + + public void setVideoUrl(String videoUrl) { + this.videoUrl = videoUrl; + } + + public String getVideoUrl() { + return videoUrl; + } + + public String getGifOrVideoDownloadUrl() { + return gifOrVideoDownloadUrl; + } + + public void setGifOrVideoDownloadUrl(String gifOrVideoDownloadUrl) { + this.gifOrVideoDownloadUrl = gifOrVideoDownloadUrl; + } + + public String getPermalink() { + return permalink; + } + + public void setScore(int score) { + this.score = score; + } + + public int getScore() { + return score; + } + + public int getPostType() { + return postType; + } + + public void setVoteType(int voteType) { + this.voteType = voteType; + } + + public int getVoteType() { + return voteType; + } + + public boolean getNSFW() { + return nsfw; + } + + @Override + public int describeContents() { + return 0; + } + + public boolean isDashVideo() { + return isDashVideo; + } + + public void setDownloadableGifOrVideo(boolean isDownloadableGifOrVideo) { + this.isDownloadableGifOrVideo = isDownloadableGifOrVideo; + } + + public boolean isDownloadableGifOrVideo() { + return isDownloadableGifOrVideo; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(id); + parcel.writeString(fullName); + parcel.writeString(subredditName); + parcel.writeString(subredditIconUrl); + parcel.writeString(postTime); + parcel.writeString(title); + parcel.writeString(selfText); + parcel.writeString(previewUrl); + parcel.writeString(url); + parcel.writeString(videoUrl); + parcel.writeString(gifOrVideoDownloadUrl); + parcel.writeString(permalink); + parcel.writeInt(score); + parcel.writeInt(postType); + parcel.writeInt(voteType); + parcel.writeByte((byte) (nsfw ? 1 : 0)); + parcel.writeByte((byte) (isDashVideo ? 1 : 0)); + parcel.writeByte((byte) (isDownloadableGifOrVideo ? 1 : 0)); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostPaginationScrollListener.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostPaginationScrollListener.java new file mode 100644 index 00000000..19ab4109 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostPaginationScrollListener.java @@ -0,0 +1,166 @@ +package ml.docilealligator.infinityforreddit; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.net.Uri; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.widget.Toast; + +import com.android.volley.AuthFailureError; +import com.android.volley.Request; +import com.android.volley.RequestQueue; +import com.android.volley.Response; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.StringRequest; +import com.android.volley.toolbox.Volley; + +import java.util.ArrayList; +import java.util.Map; + +/** + * Created by alex on 3/12/18. + */ + +class PostPaginationScrollListener extends RecyclerView.OnScrollListener { + private Context mContext; + private LinearLayoutManager mLayoutManager; + private PostRecyclerViewAdapter mAdapter; + private ArrayList mPostData; + private PaginationSynchronizer mPaginationSynchronizer; + private PaginationRetryNotifier mPaginationRetryNotifier; + private LastItemSynchronizer mLastItemSynchronizer; + private PaginationRequestQueueSynchronizer mPaginationRequestQueueSynchronizer; + + private boolean isLoading; + private boolean loadSuccess; + private String mLastItem; + private RequestQueue mRequestQueue; + private RequestQueue mAcquireAccessTokenRequestQueue; + + PostPaginationScrollListener(Context context, LinearLayoutManager layoutManager, PostRecyclerViewAdapter adapter, String lastItem, ArrayList postData, PaginationSynchronizer paginationSynchronizer, + RequestQueue acquireAccessTokenRequestQueue, boolean isLoading, boolean loadSuccess) { + if(context != null) { + this.mContext = context; + this.mLayoutManager = layoutManager; + this.mAdapter = adapter; + this.mLastItem = lastItem; + this.mPostData = postData; + this.mPaginationSynchronizer = paginationSynchronizer; + this.mAcquireAccessTokenRequestQueue = acquireAccessTokenRequestQueue; + this.isLoading = isLoading; + this.loadSuccess = loadSuccess; + + mRequestQueue = Volley.newRequestQueue(mContext); + mAcquireAccessTokenRequestQueue = Volley.newRequestQueue(mContext); + mPaginationRetryNotifier = new PaginationRetryNotifier() { + @Override + public void retry() { + fetchBestPost(1); + } + }; + mPaginationSynchronizer.setPaginationRetryNotifier(mPaginationRetryNotifier); + mLastItemSynchronizer = mPaginationSynchronizer.getLastItemSynchronizer(); + mPaginationRequestQueueSynchronizer = mPaginationSynchronizer.getPaginationRequestQueueSynchronizer(); + mPaginationRequestQueueSynchronizer.passQueue(mRequestQueue); + } + } + + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + if(!isLoading && loadSuccess) { + int visibleItemCount = mLayoutManager.getChildCount(); + int totalItemCount = mLayoutManager.getItemCount(); + int firstVisibleItemPosition = mLayoutManager.findFirstVisibleItemPosition(); + + if((visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) { + fetchBestPost(1); + } + } + } + + + private void fetchBestPost(final int refreshTime) { + if(refreshTime < 0) { + loadFailed(); + return; + } + + isLoading = true; + loadSuccess = false; + mPaginationSynchronizer.setLoading(true); + + Uri uri = Uri.parse(RedditUtils.OAUTH_API_BASE_URI + RedditUtils.BEST_POST_SUFFIX) + .buildUpon().appendQueryParameter(RedditUtils.AFTER_KEY, mLastItem) + .appendQueryParameter(RedditUtils.RAW_JSON_KEY, RedditUtils.RAW_JSON_VALUE).build(); + + StringRequest bestPostRequest = new StringRequest(Request.Method.GET, uri.toString(), new Response.Listener() { + @Override + public void onResponse(String response) { + ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("response", response); + clipboard.setPrimaryClip(clip); + new ParsePost(mContext, new ParsePost.ParsePostListener() { + @Override + public void onParsePostSuccess(ArrayList bestPostData, String lastItem) { + mAdapter.notifyDataSetChanged(); + mLastItem = lastItem; + mLastItemSynchronizer.lastItemChanged(mLastItem); + + isLoading = false; + loadSuccess = true; + mPaginationSynchronizer.setLoading(false); + mPaginationSynchronizer.setLoadingState(true); + } + + @Override + public void onParsePostFail() { + Toast.makeText(mContext, "Error parsing data", Toast.LENGTH_SHORT).show(); + Log.i("Best post", "Error parsing data"); + loadFailed(); + } + }).parseBestPost(response, mPostData); + } + }, new Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + if (error instanceof AuthFailureError) { + //Access token expired + new AcquireAccessToken(mContext).refreshAccessToken(mAcquireAccessTokenRequestQueue, + new AcquireAccessToken.AcquireAccessTokenListener() { + @Override + public void onAcquireAccessTokenSuccess() { + fetchBestPost(refreshTime - 1); + } + + @Override + public void onAcquireAccessTokenFail() { + } + }); + } else { + Toast.makeText(mContext, "Error getting best post", Toast.LENGTH_SHORT).show(); + Log.i("best post", error.toString()); + loadFailed(); + } + } + }) { + @Override + public Map getHeaders() { + String accessToken = mContext.getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE).getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, ""); + return RedditUtils.getOAuthHeader(accessToken); + } + }; + bestPostRequest.setTag(PostPaginationScrollListener.class); + mRequestQueue.add(bestPostRequest); + } + + private void loadFailed() { + isLoading = false; + loadSuccess = false; + mPaginationSynchronizer.setLoading(false); + mPaginationSynchronizer.setLoadingState(false); + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java new file mode 100644 index 00000000..101ff11f --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java @@ -0,0 +1,542 @@ +package ml.docilealligator.infinityforreddit; + +import android.content.Context; +import android.content.Intent; +import android.graphics.ColorFilter; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsIntent; +import android.support.v4.content.ContextCompat; +import android.support.v7.widget.CardView; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.volley.RequestQueue; +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.Target; + +import java.util.ArrayList; + +import de.hdodenhof.circleimageview.CircleImageView; + +/** + * Created by alex on 2/25/18. + */ + +class PostRecyclerViewAdapter extends RecyclerView.Adapter { + private ArrayList mPostData; + private Context mContext; + private PaginationSynchronizer mPaginationSynchronizer; + private RequestQueue mVoteThingRequestQueue; + private RequestQueue mAcquireAccessTokenRequestQueue; + private RequestManager glide; + private SubredditDao subredditDao; + private boolean isLoadingMorePostSuccess; + private boolean canStartActivity; + + private static final int VIEW_TYPE_DATA = 0; + private static final int VIEW_TYPE_LOADING = 1; + + + PostRecyclerViewAdapter(Context context, ArrayList postData, PaginationSynchronizer paginationSynchronizer, + RequestQueue voteThingRequestQueue, RequestQueue acquireAccessTokenRequestQueue) { + if(context != null) { + mContext = context; + mPostData = postData; + mPaginationSynchronizer = paginationSynchronizer; + mVoteThingRequestQueue = voteThingRequestQueue; + mAcquireAccessTokenRequestQueue = acquireAccessTokenRequestQueue; + isLoadingMorePostSuccess = true; + canStartActivity = true; + glide = Glide.with(mContext); + subredditDao = SubredditRoomDatabase.getDatabase(mContext).subredditDao(); + } + } + + void setCanStartActivity(boolean canStartActivity) { + this.canStartActivity = canStartActivity; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if(viewType == VIEW_TYPE_DATA) { + CardView cardView = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_best_post, parent, false); + return new DataViewHolder(cardView); + } else { + LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_progress_bar, parent, false); + return new LoadingViewHolder(linearLayout); + } + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final 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(); + } else if(!mPostData.get(position).getSubredditIconUrl().equals("")) { + glide.load(mPostData.get(position).getSubredditIconUrl()).into(((DataViewHolder) holder).subredditIconCircleImageView); + } else { + glide.load(R.drawable.subreddit_default_icon).into(((DataViewHolder) holder).subredditIconCircleImageView); + } + + ((DataViewHolder) holder).cardView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if(canStartActivity) { + canStartActivity = false; + Intent intent = new Intent(mContext, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_TITLE, title); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, mPostData.get(position)); + mContext.startActivity(intent); + } + } + }); + + ((DataViewHolder) holder).subredditNameTextView.setText(subredditName); + ((DataViewHolder) holder).postTimeTextView.setText(postTime); + ((DataViewHolder) holder).titleTextView.setText(title); + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore())); + + if(nsfw) { + ((DataViewHolder) holder).nsfwTextView.setVisibility(View.VISIBLE); + } + + switch (voteType) { + case 1: + //Upvote + ((DataViewHolder) holder).upvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN); + break; + case -1: + //Downvote + ((DataViewHolder) holder).downvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN); + break; + } + + if(mPostData.get(position).getPostType() != PostData.TEXT_TYPE && mPostData.get(position).getPostType() != PostData.NO_PREVIEW_LINK_TYPE) { + ((DataViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); + ((DataViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((DataViewHolder) holder).imageView.setVisibility(View.VISIBLE); + } + + switch (mPostData.get(position).getPostType()) { + case PostData.IMAGE_TYPE: + ((DataViewHolder) holder).typeTextView.setText("IMAGE"); + final String previewImageUrl = mPostData.get(position).getPreviewUrl(); + final String imageUrl = mPostData.get(position).getUrl(); + glide.load(previewImageUrl).listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + ((DataViewHolder) holder).progressBar.setVisibility(View.GONE); + return false; + } + }).into(((DataViewHolder) holder).imageView); + ((DataViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(mContext, ViewImageActivity.class); + intent.putExtra(ViewImageActivity.IMAGE_URL_KEY, imageUrl); + intent.putExtra(ViewImageActivity.TITLE_KEY, title); + intent.putExtra(ViewImageActivity.SUBREDDIT_KEY, subredditName); + intent.putExtra(ViewImageActivity.ID_KEY, id); + mContext.startActivity(intent); + } + }); + break; + case PostData.LINK_TYPE: + ((DataViewHolder) holder).typeTextView.setText("LINK"); + String linkPreviewUrl = mPostData.get(position).getPreviewUrl(); + glide.load(linkPreviewUrl).listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + ((DataViewHolder) holder).progressBar.setVisibility(View.GONE); + return false; + } + }).into(((DataViewHolder) holder).imageView); + final String linkUrl = mPostData.get(position).getUrl(); + ((DataViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); + // add share action to menu list + builder.addDefaultShareMenuItem(); + builder.setToolbarColor(mContext.getResources().getColor(R.color.colorPrimary)); + CustomTabsIntent customTabsIntent = builder.build(); + customTabsIntent.launchUrl(mContext, Uri.parse(linkUrl)); + } + }); + break; + case PostData.GIF_VIDEO_TYPE: + ((DataViewHolder) holder).typeTextView.setText("GIF"); + String gifVideoPreviewUrl = mPostData.get(position).getPreviewUrl(); + glide.load(gifVideoPreviewUrl).listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + ((DataViewHolder) holder).progressBar.setVisibility(View.GONE); + return false; + } + }).into(((DataViewHolder) holder).imageView); + + String gifVideoUrl = mPostData.get(position).getVideoUrl(); + final Uri gifVideoUri = Uri.parse(gifVideoUrl); + + ((DataViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + 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.SUBREDDIT_KEY, subredditName); + intent.putExtra(ViewVideoActivity.ID_KEY, id); + } + mContext.startActivity(intent); + } + }); + break; + case PostData.VIDEO_TYPE: + ((DataViewHolder) holder).typeTextView.setText("VIDEO"); + String videoPreviewUrl = mPostData.get(position).getPreviewUrl(); + glide.load(videoPreviewUrl).listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + ((DataViewHolder) holder).progressBar.setVisibility(View.GONE); + return false; + } + }).into(((DataViewHolder) holder).imageView); + + String videoUrl = mPostData.get(position).getVideoUrl(); + final Uri videoUri = Uri.parse(videoUrl); + + ((DataViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + 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.SUBREDDIT_KEY, subredditName); + intent.putExtra(ViewVideoActivity.ID_KEY, id); + } + mContext.startActivity(intent); + } + }); + break; + case PostData.NO_PREVIEW_LINK_TYPE: + ((DataViewHolder) holder).typeTextView.setText("LINK"); + final String noPreviewLinkUrl = mPostData.get(position).getUrl(); + ((DataViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); + ((DataViewHolder) holder).noPreviewLinkImageView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); + // add share action to menu list + builder.addDefaultShareMenuItem(); + builder.setToolbarColor(mContext.getResources().getColor(R.color.colorPrimary)); + CustomTabsIntent customTabsIntent = builder.build(); + customTabsIntent.launchUrl(mContext, Uri.parse(noPreviewLinkUrl)); + } + }); + break; + default: + ((DataViewHolder) holder).typeTextView.setText("TEXT"); + } + + ((DataViewHolder) holder).upvoteButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + final boolean isDownvotedBefore = ((DataViewHolder) holder).downvoteButton.getColorFilter() != null; + + final ColorFilter downvoteButtonColorFilter = ((DataViewHolder) holder).downvoteButton.getColorFilter(); + ((DataViewHolder) holder).downvoteButton.clearColorFilter(); + + 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)); + } else { + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore() + 1)); + } + + new VoteThing(mContext, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position) { + mPostData.get(position).setVoteType(1); + if(isDownvotedBefore) { + mPostData.get(position).setScore(mPostData.get(position).getScore() + 2); + } else { + mPostData.get(position).setScore(mPostData.get(position).getScore() + 1); + } + } + + @Override + public void onVoteThingFail(int position) { + Toast.makeText(mContext, "Cannot upvote this post", Toast.LENGTH_SHORT).show(); + ((DataViewHolder) holder).upvoteButton.clearColorFilter(); + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore())); + ((DataViewHolder) holder).downvoteButton.setColorFilter(downvoteButtonColorFilter); + } + }, id, RedditUtils.DIR_UPVOTE, ((DataViewHolder) holder).getAdapterPosition(), 1); + } else { + //Upvoted before + ((DataViewHolder) holder).upvoteButton.clearColorFilter(); + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore() - 1)); + + new VoteThing(mContext, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position) { + mPostData.get(position).setVoteType(0); + mPostData.get(position).setScore(mPostData.get(position).getScore() - 1); + } + + @Override + public void onVoteThingFail(int position) { + Toast.makeText(mContext, "Cannot unvote this post", Toast.LENGTH_SHORT).show(); + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore() + 1)); + ((DataViewHolder) holder).upvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN); + mPostData.get(position).setScore(mPostData.get(position).getScore() + 1); + } + }, id, RedditUtils.DIR_UNVOTE, ((DataViewHolder) holder).getAdapterPosition(), 1); + } + } + }); + + ((DataViewHolder) holder).downvoteButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + final boolean isUpvotedBefore = ((DataViewHolder) holder).upvoteButton.getColorFilter() != null; + + final ColorFilter upvoteButtonColorFilter = ((DataViewHolder) holder).upvoteButton.getColorFilter(); + ((DataViewHolder) holder).upvoteButton.clearColorFilter(); + 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)); + } else { + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore() - 1)); + } + + new VoteThing(mContext, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position) { + mPostData.get(position).setVoteType(-1); + if(isUpvotedBefore) { + mPostData.get(position).setScore(mPostData.get(position).getScore() - 2); + } else { + mPostData.get(position).setScore(mPostData.get(position).getScore() - 1); + } + } + + @Override + public void onVoteThingFail(int position) { + Toast.makeText(mContext, "Cannot downvote this post", Toast.LENGTH_SHORT).show(); + ((DataViewHolder) holder).downvoteButton.clearColorFilter(); + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore())); + ((DataViewHolder) holder).upvoteButton.setColorFilter(upvoteButtonColorFilter); + } + }, id, RedditUtils.DIR_DOWNVOTE, holder.getAdapterPosition(), 1); + } else { + //Down voted before + ((DataViewHolder) holder).downvoteButton.clearColorFilter(); + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore() + 1)); + + new VoteThing(mContext, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position) { + mPostData.get(position).setVoteType(0); + mPostData.get(position).setScore(mPostData.get(position).getScore()); + } + + @Override + public void onVoteThingFail(int position) { + Toast.makeText(mContext, "Cannot unvote this post", Toast.LENGTH_SHORT).show(); + ((DataViewHolder) holder).downvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN); + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore())); + mPostData.get(position).setScore(mPostData.get(position).getScore()); + } + }, id, RedditUtils.DIR_UNVOTE, holder.getAdapterPosition(), 1); + } + } + }); + + ((DataViewHolder) holder).shareButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + String extraText = title + "\n" + permalink; + intent.putExtra(Intent.EXTRA_TEXT, extraText); + mContext.startActivity(Intent.createChooser(intent, "Share")); + } + }); + } + } else if(holder instanceof LoadingViewHolder) { + ((LoadingViewHolder) holder).retryButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mPaginationSynchronizer.getPaginationRetryNotifier().retry(); + ((LoadingViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.GONE); + } + }); + + PaginationNotifier mPaginationNotifier = new PaginationNotifier() { + @Override + public void LoadMorePostSuccess() { + isLoadingMorePostSuccess = true; + } + + @Override + public void LoadMorePostFail() { + ((LoadingViewHolder) holder).progressBar.setVisibility(View.GONE); + ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); + isLoadingMorePostSuccess = false; + } + }; + + mPaginationSynchronizer.setPaginationNotifier(mPaginationNotifier); + + if(!mPaginationSynchronizer.isLoadSuccess()) { + ((LoadingViewHolder) holder).progressBar.setVisibility(View.GONE); + ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); + } + } + } + + @Override + public int getItemCount() { + return mPostData.size() + 1; + } + + @Override + public int getItemViewType(int position) { + return (position >= mPostData.size() ? VIEW_TYPE_LOADING : VIEW_TYPE_DATA); + } + + class DataViewHolder extends RecyclerView.ViewHolder { + private CardView cardView; + private CircleImageView subredditIconCircleImageView; + private TextView subredditNameTextView; + private TextView postTimeTextView; + private TextView titleTextView; + private TextView typeTextView; + private TextView nsfwTextView; + private RelativeLayout relativeLayout; + private ProgressBar progressBar; + private ImageView imageView; + private ImageView noPreviewLinkImageView; + private ImageView upvoteButton; + private TextView scoreTextView; + private ImageView downvoteButton; + private ImageView shareButton; + + DataViewHolder(CardView itemView) { + super(itemView); + 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); + 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); + 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); + imageView = itemView.findViewById(R.id.image_view_best_post_item); + noPreviewLinkImageView = itemView.findViewById(R.id.image_view_no_preview_link_best_post_item); + + upvoteButton = itemView.findViewById(R.id.plus_button_item_best_post); + scoreTextView = itemView.findViewById(R.id.score_text_view_item_best_post); + downvoteButton = itemView.findViewById(R.id.minus_button_item_best_post); + shareButton = itemView.findViewById(R.id.share_button_item_best_post); + } + } + + class LoadingViewHolder extends RecyclerView.ViewHolder { + private ProgressBar progressBar; + private RelativeLayout relativeLayout; + private Button retryButton; + + LoadingViewHolder(LinearLayout itemView) { + super(itemView); + progressBar = itemView.findViewById(R.id.progress_bar_footer_progress_bar_item); + relativeLayout = itemView.findViewById(R.id.relative_layout_footer_progress_bar_item); + retryButton = itemView.findViewById(R.id.retry_button_footer_progress_bar_item); + } + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + if(holder instanceof DataViewHolder) { + glide.clear(((DataViewHolder) holder).imageView); + ((DataViewHolder) holder).relativeLayout.setVisibility(View.GONE); + ((DataViewHolder) holder).nsfwTextView.setVisibility(View.GONE); + ((DataViewHolder) holder).progressBar.setVisibility(View.GONE); + ((DataViewHolder) holder).imageView.setVisibility(View.GONE); + ((DataViewHolder) holder).noPreviewLinkImageView.setVisibility(View.GONE); + ((DataViewHolder) holder).upvoteButton.clearColorFilter(); + ((DataViewHolder) holder).downvoteButton.clearColorFilter(); + } else if(holder instanceof LoadingViewHolder) { + if(isLoadingMorePostSuccess) { + ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.GONE); + ((LoadingViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + } else { + ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); + ((LoadingViewHolder) holder).progressBar.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 050db26c..e5a66601 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java @@ -45,7 +45,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { private String orientationState = "OS"; private int mMoreCommentCount; - private BestPostData mPostData; + private PostData mPostData; private CoordinatorLayout mCoordinatorLayout; private ProgressBar mCommentProgressbar; @@ -144,7 +144,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { }); switch (mPostData.getPostType()) { - case BestPostData.IMAGE_TYPE: + case PostData.IMAGE_TYPE: typeTextView.setText("IMAGE"); relativeLayout.setVisibility(View.VISIBLE); Glide.with(this).load(mPostData.getPreviewUrl()).listener(new RequestListener() { @@ -172,7 +172,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { } }); break; - case BestPostData.LINK_TYPE: + case PostData.LINK_TYPE: relativeLayout.setVisibility(View.VISIBLE); typeTextView.setText("LINK"); String linkPreviewUrl = mPostData.getPreviewUrl(); @@ -201,7 +201,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { } }); break; - case BestPostData.GIF_VIDEO_TYPE: + case PostData.GIF_VIDEO_TYPE: relativeLayout.setVisibility(View.VISIBLE); typeTextView.setText("VIDEO"); String gifVideoPreviewUrl = mPostData.getPreviewUrl(); @@ -238,7 +238,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { } }); break; - case BestPostData.VIDEO_TYPE: + case PostData.VIDEO_TYPE: relativeLayout.setVisibility(View.VISIBLE); typeTextView.setText("VIDEO"); String videoPreviewUrl = mPostData.getPreviewUrl(); @@ -275,7 +275,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { } }); break; - case BestPostData.NO_PREVIEW_LINK_TYPE: + case PostData.NO_PREVIEW_LINK_TYPE: typeTextView.setText("LINK"); noPreviewLinkImageView.setVisibility(View.VISIBLE); noPreviewLinkImageView.setOnClickListener(new View.OnClickListener() { @@ -290,7 +290,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { } }); break; - case BestPostData.TEXT_TYPE: + case PostData.TEXT_TYPE: typeTextView.setText("TEXT"); if(!mPostData.getSelfText().equals("")) { contentTextView.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java index 887beb01..4d4eb8c5 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java @@ -7,6 +7,8 @@ import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CollapsingToolbarLayout; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.MenuItem; @@ -117,6 +119,10 @@ public class ViewSubredditDetailActivity extends AppCompatActivity { } }); + + FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); + Fragment mFragment = new BestPostFragment(); + fragmentTransaction.replace(R.id.frame_layout_view_subreddit_detail_activity, mFragment).commit(); } @Override -- cgit v1.2.3