diff options
Diffstat (limited to 'app')
13 files changed, 427 insertions, 237 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java index a9151b50..c4b1958e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java @@ -2,11 +2,12 @@ package ml.docilealligator.infinityforreddit; import android.util.Log; +import androidx.annotation.NonNull; + import java.util.ArrayList; import java.util.List; import java.util.Locale; -import androidx.annotation.NonNull; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -14,13 +15,13 @@ import retrofit2.Retrofit; class FetchComment { interface FetchCommentListener { - void onFetchCommentSuccess(List<?> commentData, + void onFetchCommentSuccess(List<?> commentsData, String parentId, ArrayList<String> children); void onFetchCommentFailed(); } interface FetchMoreCommentListener { - void onFetchMoreCommentSuccess(List<?> commentData, int childrenStartingIndex); + void onFetchMoreCommentSuccess(List<?> commentsData, int childrenStartingIndex); void onFetchMoreCommentFailed(); } @@ -106,9 +107,6 @@ class FetchComment { public void onParseCommentSuccess(List<?> commentData, String parentId, ArrayList<String> children) { fetchMoreCommentListener.onFetchMoreCommentSuccess(commentData, startingIndex + 100); - /*fetchMoreComment(retrofit, subredditNamePrefixed, - mParentId, allChildren, finalStartingIndex, - locale, fetchMoreCommentListener);*/ } @Override @@ -157,15 +155,15 @@ class FetchComment { fetchComment(retrofit, subredditNamePrefixed, article, comment, locale, isPost, parentDepth, new FetchCommentListener() { @Override - public void onFetchCommentSuccess(List<?> commentData, String parentId, ArrayList<String> children) { + public void onFetchCommentSuccess(List<?> commentsData, String parentId, ArrayList<String> children) { if(children.size() != 0) { fetchMoreComment(retrofit, subredditNamePrefixed, parentId, children, 0, locale, new FetchMoreCommentListener() { @Override - public void onFetchMoreCommentSuccess(List<?> moreCommentData, + public void onFetchMoreCommentSuccess(List<?> commentsData, int childrenStartingIndex) { - ((ArrayList<CommentData>)commentData).addAll((ArrayList<CommentData>) moreCommentData); - fetchAllCommentListener.onFetchAllCommentSuccess(commentData); + ((ArrayList<CommentData>) commentsData).addAll((ArrayList<CommentData>) commentsData); + fetchAllCommentListener.onFetchAllCommentSuccess(commentsData); } @Override @@ -175,7 +173,7 @@ class FetchComment { } }); } else { - fetchAllCommentListener.onFetchAllCommentSuccess(commentData); + fetchAllCommentListener.onFetchAllCommentSuccess(commentsData); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchPost.java new file mode 100644 index 00000000..ec736a95 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchPost.java @@ -0,0 +1,52 @@ +package ml.docilealligator.infinityforreddit; + +import android.util.Log; + +import androidx.annotation.NonNull; + +import java.util.Locale; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +class FetchPost { + interface FetchPostListener { + void fetchPostSuccess(Post post); + void fetchPostFailed(); + } + + static void fetchPost(Retrofit oauthRetrofit, String id, String accessToken, Locale locale, FetchPostListener fetchPostListener) { + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + Call<String> postCall = api.getPost(id, RedditUtils.getOAuthHeader(accessToken)); + postCall.enqueue(new Callback<String>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { + if(response.isSuccessful()) { + ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() { + @Override + public void onParsePostSuccess(Post post) { + fetchPostListener.fetchPostSuccess(post); + } + + @Override + public void onParsePostFail() { + fetchPostListener.fetchPostFailed(); + Log.i("error", "fetch post failed"); + } + }); + } else { + fetchPostListener.fetchPostFailed(); + Log.i("call failed", Integer.toString(response.code())); + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + fetchPostListener.fetchPostFailed(); + Log.i("call failed", t.getMessage()); + } + }); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java index 280d36a7..8cd998b2 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java @@ -17,31 +17,56 @@ import java.util.Locale; */ class ParsePost { + interface ParsePostsListingListener { + void onParsePostsListingSuccess(ArrayList<Post> newPostData, String lastItem); + void onParsePostsListingFail(); + } interface ParsePostListener { - void onParsePostSuccess(ArrayList<Post> newPostData, String lastItem); + void onParsePostSuccess(Post post); void onParsePostFail(); } + static void parsePosts(String response, Locale locale, ParsePostsListingListener parsePostsListingListener) { + new ParsePostDataAsyncTask(response, locale, parsePostsListingListener).execute(); + } + static void parsePost(String response, Locale locale, ParsePostListener parsePostListener) { new ParsePostDataAsyncTask(response, locale, parsePostListener).execute(); } private static class ParsePostDataAsyncTask extends AsyncTask<Void, Void, Void> { - private JSONObject jsonResponse; + private JSONArray allData; private Locale locale; + private ParsePostsListingListener parsePostsListingListener; private ParsePostListener parsePostListener; private ArrayList<Post> newPosts; + private Post post; private String lastItem; private boolean parseFailed; ParsePostDataAsyncTask(String response, Locale locale, + ParsePostsListingListener parsePostsListingListener) { + this.parsePostsListingListener = parsePostsListingListener; + try { + JSONObject jsonResponse = new JSONObject(response); + allData = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + lastItem = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); + this.locale = locale; + newPosts = new ArrayList<>(); + parseFailed = false; + } catch (JSONException e) { + e.printStackTrace(); + parseFailed = true; + } + } + + ParsePostDataAsyncTask(String response, Locale locale, ParsePostListener parsePostListener) { this.parsePostListener = parsePostListener; try { - jsonResponse = new JSONObject(response); + allData = new JSONArray(response).getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); this.locale = locale; - newPosts = new ArrayList<>(); parseFailed = false; } catch (JSONException e) { e.printStackTrace(); @@ -56,66 +81,35 @@ class ParsePost { } 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++) { - String kind = allData.getJSONObject(i).getString(JSONUtils.KIND_KEY); - if(!kind.equals("t3")) { - //It's a comment - continue; - } - JSONObject data = allData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); - String id = data.getString(JSONUtils.ID_KEY); - String fullName = data.getString(JSONUtils.NAME_KEY); - String subredditNamePrefixed = data.getString(JSONUtils.SUBREDDIT_NAME_PREFIX_KEY); - String author = data.getString(JSONUtils.AUTHOR_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; - int gilded = data.getInt(JSONUtils.GILDED_KEY); - boolean nsfw = data.getBoolean(JSONUtils.NSFW_KEY); - boolean stickied = data.getBoolean(JSONUtils.STICKIED_KEY); - - if(data.isNull(JSONUtils.LIKES_KEY)) { - voteType = 0; - } else { - voteType = data.getBoolean(JSONUtils.LIKES_KEY) ? 1 : -1; - score -= voteType; + if(newPosts == null) { + //Only one post + if(allData.length() == 0) { + parseFailed = true; + return null; } - Calendar postTimeCalendar = Calendar.getInstance(); - postTimeCalendar.setTimeInMillis(postTime); - String formattedPostTime = new SimpleDateFormat("MMM d, YYYY, HH:mm", - locale).format(postTimeCalendar.getTime()); - String permalink = data.getString(JSONUtils.PERMALINK_KEY); - - String previewUrl = ""; - int previewWidth = -1; - int previewHeight = -1; - 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); - previewWidth = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0) - .getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.WIDTH_KEY); - previewHeight = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0) - .getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.HEIGHT_KEY); - } - if(data.has(JSONUtils.CROSSPOST_PARENT_LIST)) { - //Cross post - data = data.getJSONArray(JSONUtils.CROSSPOST_PARENT_LIST).getJSONObject(0); - parseData(data, permalink, newPosts, id, fullName, subredditNamePrefixed, - author, formattedPostTime, title, previewUrl, previewWidth, previewHeight, - score, voteType, gilded, nsfw, stickied, true, i); + String kind = allData.getJSONObject(0).getString(JSONUtils.KIND_KEY); + if(kind.equals("t3")) { + //It's a post + JSONObject data = allData.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY); + post = parseBasicData(data, locale, -1); } else { - parseData(data, permalink, newPosts, id, fullName, subredditNamePrefixed, - author, formattedPostTime, title, previewUrl, previewWidth, previewHeight, - score, voteType, gilded, nsfw, stickied, false, i); + parseFailed = true; + return null; + } + } else { + //Posts listing + for(int i = 0; i < allData.length(); i++) { + String kind = allData.getJSONObject(i).getString(JSONUtils.KIND_KEY); + if(kind.equals("t3")) { + //It's a post + JSONObject data = allData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); + newPosts.add(parseBasicData(data, locale, i)); + } } } } catch (JSONException e) { - Log.e("best post parse error", e.getMessage()); + Log.e("parsing post error", e.getMessage()); parseFailed = true; } return null; @@ -124,18 +118,78 @@ class ParsePost { @Override protected void onPostExecute(Void aVoid) { if(!parseFailed) { - parsePostListener.onParsePostSuccess(newPosts, lastItem); + if(newPosts != null) { + parsePostsListingListener.onParsePostsListingSuccess(newPosts, lastItem); + } else { + parsePostListener.onParsePostSuccess(post); + } } else { - parsePostListener.onParsePostFail(); + if(newPosts != null) { + parsePostsListingListener.onParsePostsListingFail(); + } else { + parsePostListener.onParsePostFail(); + } } } } - private static void parseData(JSONObject data, String permalink, ArrayList<Post> bestPostData, - String id, String fullName, String subredditNamePrefixed, String author, - String formattedPostTime, String title, String previewUrl, int previewWidth, - int previewHeight ,int score, int voteType, int gilded, - boolean nsfw, boolean stickied, boolean isCrosspost, int i) throws JSONException { + private static Post parseBasicData(JSONObject data, Locale locale, int i) throws JSONException { + String id = data.getString(JSONUtils.ID_KEY); + String fullName = data.getString(JSONUtils.NAME_KEY); + String subredditNamePrefixed = data.getString(JSONUtils.SUBREDDIT_NAME_PREFIX_KEY); + String author = data.getString(JSONUtils.AUTHOR_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; + int gilded = data.getInt(JSONUtils.GILDED_KEY); + boolean nsfw = data.getBoolean(JSONUtils.NSFW_KEY); + boolean stickied = data.getBoolean(JSONUtils.STICKIED_KEY); + + if(data.isNull(JSONUtils.LIKES_KEY)) { + voteType = 0; + } else { + voteType = data.getBoolean(JSONUtils.LIKES_KEY) ? 1 : -1; + score -= voteType; + } + + Calendar postTimeCalendar = Calendar.getInstance(); + postTimeCalendar.setTimeInMillis(postTime); + String formattedPostTime = new SimpleDateFormat("MMM d, YYYY, HH:mm", + locale).format(postTimeCalendar.getTime()); + String permalink = data.getString(JSONUtils.PERMALINK_KEY); + + String previewUrl = ""; + int previewWidth = -1; + int previewHeight = -1; + 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); + previewWidth = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0) + .getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.WIDTH_KEY); + previewHeight = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0) + .getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.HEIGHT_KEY); + } + if(data.has(JSONUtils.CROSSPOST_PARENT_LIST)) { + //Cross post + data = data.getJSONArray(JSONUtils.CROSSPOST_PARENT_LIST).getJSONObject(0); + return parseData(data, permalink, id, fullName, subredditNamePrefixed, + author, formattedPostTime, title, previewUrl, previewWidth, previewHeight, + score, voteType, gilded, nsfw, stickied, true, i); + } else { + return parseData(data, permalink, id, fullName, subredditNamePrefixed, + author, formattedPostTime, title, previewUrl, previewWidth, previewHeight, + score, voteType, gilded, nsfw, stickied, false, i); + } + } + + private static Post parseData(JSONObject data, String permalink, String id, String fullName, + String subredditNamePrefixed, String author, String formattedPostTime, + String title, String previewUrl, int previewWidth, int previewHeight, + int score, int voteType, int gilded, boolean nsfw, boolean stickied, + boolean isCrosspost, int i) throws JSONException { + Post post; + boolean isVideo = data.getBoolean(JSONUtils.IS_VIDEO_KEY); String url = data.getString(JSONUtils.URL_KEY); @@ -144,27 +198,25 @@ class ParsePost { //Text post Log.i("text", Integer.toString(i)); int postType = Post.TEXT_TYPE; - Post post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, + post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost); if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) { post.setSelfText(""); } else { post.setSelfText(data.getString(JSONUtils.SELFTEXT_HTML_KEY).trim()); } - bestPostData.add(post); } else { //No preview link post Log.i("no preview link", Integer.toString(i)); int postType = Post.NO_PREVIEW_LINK_TYPE; - Post linkPost = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, + post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title, previewUrl, url, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost); if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) { - linkPost.setSelfText(""); + post.setSelfText(""); } else { - linkPost.setSelfText(data.getString(JSONUtils.SELFTEXT_HTML_KEY).trim()); + post.setSelfText(data.getString(JSONUtils.SELFTEXT_HTML_KEY).trim()); } - bestPostData.add(linkPost); } } else { if(previewUrl.equals("")) { @@ -179,16 +231,14 @@ class ParsePost { int postType = Post.VIDEO_TYPE; String videoUrl = redditVideoObject.getString(JSONUtils.DASH_URL_KEY); - Post videoPost = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, + post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title, previewUrl, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost, true); - videoPost.setPreviewWidth(previewWidth); - videoPost.setPreviewHeight(previewHeight); - videoPost.setVideoUrl(videoUrl); - videoPost.setDownloadableGifOrVideo(false); - - bestPostData.add(videoPost); + post.setPreviewWidth(previewWidth); + post.setPreviewHeight(previewHeight); + post.setVideoUrl(videoUrl); + post.setDownloadableGifOrVideo(false); } 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)) { @@ -197,17 +247,15 @@ class ParsePost { int postType = Post.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); - Post post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title, + + post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title, previewUrl, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost, false); - post.setPreviewWidth(previewWidth); post.setPreviewHeight(previewHeight); 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)); @@ -215,64 +263,58 @@ class ParsePost { String videoUrl = data.getJSONObject(JSONUtils.PREVIEW_KEY) .getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.DASH_URL_KEY); - Post post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title, + post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title, previewUrl, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost, true); - post.setPreviewWidth(previewWidth); post.setPreviewHeight(previewHeight); 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 = Post.IMAGE_TYPE; - Post imagePost = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, + post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title, url, url, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost); - imagePost.setPreviewWidth(previewWidth); - imagePost.setPreviewHeight(previewHeight); - - bestPostData.add(imagePost); + post.setPreviewWidth(previewWidth); + post.setPreviewHeight(previewHeight); } else { if (url.contains(permalink)) { //Text post but with a preview Log.i("text with image", Integer.toString(i)); int postType = Post.TEXT_TYPE; - Post textWithImagePost = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, + + post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost); - textWithImagePost.setPreviewWidth(previewWidth); - textWithImagePost.setPreviewHeight(previewHeight); + post.setPreviewWidth(previewWidth); + post.setPreviewHeight(previewHeight); if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) { - textWithImagePost.setSelfText(""); + post.setSelfText(""); } else { - textWithImagePost.setSelfText(data.getString(JSONUtils.SELFTEXT_HTML_KEY).trim()); + post.setSelfText(data.getString(JSONUtils.SELFTEXT_HTML_KEY).trim()); } - bestPostData.add(textWithImagePost); } else { //Link post Log.i("link", Integer.toString(i)); int postType = Post.LINK_TYPE; - Post linkPost = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, + + post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title, previewUrl, url, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost); if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) { - linkPost.setSelfText(""); + post.setSelfText(""); } else { - linkPost.setSelfText(data.getString(JSONUtils.SELFTEXT_HTML_KEY).trim()); + post.setSelfText(data.getString(JSONUtils.SELFTEXT_HTML_KEY).trim()); } - linkPost.setPreviewWidth(previewWidth); - linkPost.setPreviewHeight(previewHeight); - - bestPostData.add(linkPost); + post.setPreviewWidth(previewWidth); + post.setPreviewHeight(previewHeight); } } } @@ -281,21 +323,24 @@ class ParsePost { //Image post Log.i("CP image", Integer.toString(i)); int postType = Post.IMAGE_TYPE; - Post linkPost = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, + + post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title, previewUrl, url, permalink, score, postType, voteType, gilded, nsfw, stickied, isCrosspost); - linkPost.setPreviewWidth(previewWidth); - linkPost.setPreviewHeight(previewHeight); - bestPostData.add(linkPost); + post.setPreviewWidth(previewWidth); + post.setPreviewHeight(previewHeight); } else { //CP No Preview Link post Log.i("CP no preview link", Integer.toString(i)); int postType = Post.NO_PREVIEW_LINK_TYPE; - bestPostData.add(new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title, + + post = new Post(id, fullName, subredditNamePrefixed, author, formattedPostTime, title, url, url, permalink, score, postType, voteType, - gilded, nsfw, stickied, isCrosspost)); + gilded, nsfw, stickied, isCrosspost); } } } + + return post; } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java index 7461bd21..4aa84343 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java @@ -130,10 +130,10 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if (response.isSuccessful()) { - ParsePost.parsePost(response.body(), locale, - new ParsePost.ParsePostListener() { + ParsePost.parsePosts(response.body(), locale, + new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) { + public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { if(newPosts.size() == 0) { onPostFetchedCallback.noPost(); } else { @@ -145,7 +145,7 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { } @Override - public void onParsePostFail() { + public void onParsePostsListingFail() { Log.i("Post fetch error", "Error parsing data"); initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); } @@ -172,15 +172,15 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(Call<String> call, retrofit2.Response<String> response) { if(response.isSuccessful()) { - ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() { + ParsePost.parsePosts(response.body(), locale, new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) { + public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { callback.onResult(newPosts, lastItem); paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } @Override - public void onParsePostFail() { + public void onParsePostsListingFail() { Log.i("Best post", "Error parsing data"); paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); } @@ -206,10 +206,10 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(Call<String> call, retrofit2.Response<String> response) { if(response.isSuccessful()) { - ParsePost.parsePost(response.body(), locale, - new ParsePost.ParsePostListener() { + ParsePost.parsePosts(response.body(), locale, + new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) { + public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { if(newPosts.size() == 0) { onPostFetchedCallback.noPost(); } else { @@ -221,7 +221,7 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { } @Override - public void onParsePostFail() { + public void onParsePostsListingFail() { Log.i("Post fetch error", "Error parsing data"); initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); } @@ -247,15 +247,15 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(Call<String> call, retrofit2.Response<String> response) { if(response.isSuccessful()) { - ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() { + ParsePost.parsePosts(response.body(), locale, new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) { + public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { callback.onResult(newPosts, lastItem); paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } @Override - public void onParsePostFail() { + public void onParsePostsListingFail() { Log.i("Best post", "Error parsing data"); paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); } @@ -281,10 +281,10 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(Call<String> call, retrofit2.Response<String> response) { if(response.isSuccessful()) { - ParsePost.parsePost(response.body(), locale, - new ParsePost.ParsePostListener() { + ParsePost.parsePosts(response.body(), locale, + new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) { + public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { if(newPosts.size() == 0 && lastItem.equals("null")) { callback.onResult(newPosts, null, lastItem); initialLoadStateLiveData.postValue(NetworkState.LOADED); @@ -299,7 +299,7 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { } @Override - public void onParsePostFail() { + public void onParsePostsListingFail() { Log.i("Post fetch error", "Error parsing data"); initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); } @@ -325,15 +325,15 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(Call<String> call, retrofit2.Response<String> response) { if(response.isSuccessful()) { - ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() { + ParsePost.parsePosts(response.body(), locale, new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) { + public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { callback.onResult(newPosts, lastItem); paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } @Override - public void onParsePostFail() { + public void onParsePostsListingFail() { Log.i("Best post", "Error parsing data"); paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); } @@ -359,10 +359,10 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(Call<String> call, retrofit2.Response<String> response) { if(response.isSuccessful()) { - ParsePost.parsePost(response.body(), locale, - new ParsePost.ParsePostListener() { + ParsePost.parsePosts(response.body(), locale, + new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) { + public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { if(newPosts.size() == 0) { onPostFetchedCallback.noPost(); } else { @@ -374,7 +374,7 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { } @Override - public void onParsePostFail() { + public void onParsePostsListingFail() { Log.i("Post fetch error", "Error parsing data"); initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); } @@ -400,15 +400,15 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onResponse(Call<String> call, retrofit2.Response<String> response) { if(response.isSuccessful()) { - ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() { + ParsePost.parsePosts(response.body(), locale, new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) { + public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { callback.onResult(newPosts, lastItem); paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } @Override - public void onParsePostFail() { + public void onParsePostsListingFail() { Log.i("Best post", "Error parsing data"); paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java index 4d9cd3c7..2d286377 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java @@ -180,10 +180,12 @@ public class PostFragment extends Fragment implements FragmentCommunicator { } @Subscribe - public void onVoteEvent(VoteEventToPostList event) { + public void onPostUpdateEvent(PostUpdateEventToPostList event) { Post post = mAdapter.getCurrentList().get(event.positionInList); if(post != null) { - post.setVoteType(event.voteType); + post.setTitle(event.post.getTitle()); + post.setVoteType(event.post.getVoteType()); + post.setScore(event.post.getScore()); mAdapter.notifyItemChanged(event.positionInList); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java index b04c10ef..f8607c6c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java @@ -414,7 +414,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo ((DataViewHolder) holder).downvoteButton.clearColorFilter(); ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + post.getVoteType())); - EventBus.getDefault().post(new VoteEventToDetailActivity(post.getId(), post.getVoteType())); + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post.getId(), post.getVoteType())); } @Override @@ -425,7 +425,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo ((DataViewHolder) holder).upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); ((DataViewHolder) holder).downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); - EventBus.getDefault().post(new VoteEventToDetailActivity(post.getId(), post.getVoteType())); + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post.getId(), post.getVoteType())); } }, id, newVoteType, holder.getAdapterPosition()); }); @@ -469,7 +469,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo ((DataViewHolder) holder).upvoteButton.clearColorFilter(); ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + post.getVoteType())); - EventBus.getDefault().post(new VoteEventToDetailActivity(post.getId(), post.getVoteType())); + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post.getId(), post.getVoteType())); } @Override @@ -480,7 +480,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo ((DataViewHolder) holder).upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); ((DataViewHolder) holder).downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); - EventBus.getDefault().post(new VoteEventToDetailActivity(post.getId(), post.getVoteType())); + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post.getId(), post.getVoteType())); } }, id, newVoteType, holder.getAdapterPosition()); }); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/VoteEventToDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostUpdateEventToDetailActivity.java index d3e80ba4..af3d504f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/VoteEventToDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostUpdateEventToDetailActivity.java @@ -1,10 +1,10 @@ package ml.docilealligator.infinityforreddit; -public class VoteEventToDetailActivity { +public class PostUpdateEventToDetailActivity { public final String postId; public final int voteType; - public VoteEventToDetailActivity(String postId, int voteType) { + public PostUpdateEventToDetailActivity(String postId, int voteType) { this.postId = postId; this.voteType = voteType; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostUpdateEventToPostList.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostUpdateEventToPostList.java new file mode 100644 index 00000000..937ab92b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostUpdateEventToPostList.java @@ -0,0 +1,11 @@ +package ml.docilealligator.infinityforreddit; + +public class PostUpdateEventToPostList { + public final Post post; + public final int positionInList; + + public PostUpdateEventToPostList(Post post, int positionInList) { + this.post = post; + this.positionInList = positionInList; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java index a0118ded..00feeb58 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java @@ -33,6 +33,9 @@ public interface RedditAPI { @POST("api/vote") Call<String> voteThing(@HeaderMap Map<String, String> headers, @FieldMap Map<String, String> params); + @GET("comments/{id}.json?raw_json=1") + Call<String> getPost(@Path("id") String id, @HeaderMap Map<String, String> headers); + @GET("best?raw_json=1") Call<String> getBestPosts(@Query("after") String lastItem, @HeaderMap Map<String, String> headers); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java index bd57cd48..a982efab 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java @@ -1,5 +1,6 @@ package ml.docilealligator.infinityforreddit; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.ColorFilter; @@ -7,9 +8,9 @@ import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; +import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.ViewTreeObserver; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; @@ -46,6 +47,7 @@ import org.greenrobot.eventbus.Subscribe; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import javax.inject.Inject; import javax.inject.Named; @@ -66,25 +68,33 @@ public class ViewPostDetailActivity extends AppCompatActivity { static final String EXTRA_POST_DATA = "EPD"; static final String EXTRA_POST_LIST_POSITION = "EPLI"; - private RequestManager glide; + private RequestManager mGlide; + private Locale mLocale; private int orientation; - private static String ORIENTATION_STATE = "OS"; + private static final String ORIENTATION_STATE = "OS"; private static final String POST_STATE = "PS"; + private static final String IS_REFRESHING_STATE = "IRS"; private Post mPost; private int postListPosition = -1; private boolean isLoadingMoreChildren = false; + private boolean isRefreshing = false; + private ArrayList<CommentData> mCommentsData; private ArrayList<String> children; private int mChildrenStartingIndex = 0; + private CommentMultiLevelRecyclerViewAdapter mAdapter; + private LoadSubredditIconAsyncTask mLoadSubredditIconAsyncTask; + @BindView(R.id.coordinator_layout_view_post_detail) CoordinatorLayout mCoordinatorLayout; @BindView(R.id.nested_scroll_view_view_post_detail_activity) NestedScrollView mNestedScrollView; @BindView(R.id.subreddit_icon_name_linear_layout_view_post_detail) LinearLayout mSubredditIconNameLinearLayout; @BindView(R.id.subreddit_icon_circle_image_view_view_post_detail) AspectRatioGifImageView mSubredditIconGifImageView; @BindView(R.id.subreddit_text_view_view_post_detail) TextView mSubredditTextView; @BindView(R.id.post_time_text_view_view_post_detail) TextView mPostTimeTextView; + @BindView(R.id.title_text_view_view_post_detail) TextView mTitleTextView; @BindView(R.id.content_markdown_view_view_post_detail) MarkwonView mContentMarkdownView; @BindView(R.id.type_text_view_view_post_detail) Chip mTypeChip; @BindView(R.id.gilded_image_view_view_post_detail) ImageView mGildedImageView; @@ -111,10 +121,6 @@ public class ViewPostDetailActivity extends AppCompatActivity { @BindView(R.id.no_comment_wrapper_linear_layout_view_post_detail) LinearLayout mNoCommentWrapperLinearLayout; @BindView(R.id.no_comment_image_view_view_post_detail) ImageView mNoCommentImageView; - private CommentMultiLevelRecyclerViewAdapter mAdapter; - private LinearLayoutManager mLayoutManager; - private LoadSubredditIconAsyncTask mLoadSubredditIconAsyncTask; - @Inject @Named("no_oauth") Retrofit mRetrofit; @@ -137,34 +143,53 @@ public class ViewPostDetailActivity extends AppCompatActivity { getSupportActionBar().setDisplayHomeAsUpEnabled(true); + mGlide = Glide.with(this); + mLocale = getResources().getConfiguration().locale; + if(savedInstanceState == null) { orientation = getResources().getConfiguration().orientation; mPost = getIntent().getExtras().getParcelable(EXTRA_POST_DATA); } else { orientation = savedInstanceState.getInt(ORIENTATION_STATE); mPost = savedInstanceState.getParcelable(POST_STATE); + isRefreshing = savedInstanceState.getBoolean(IS_REFRESHING_STATE); + + if(isRefreshing) { + isRefreshing = false; + refresh(); + } } if(getIntent().hasExtra(EXTRA_POST_LIST_POSITION)) { postListPosition = getIntent().getExtras().getInt(EXTRA_POST_LIST_POSITION); } - TextView titleTextView = findViewById(R.id.title_text_view_view_post_detail); - titleTextView.setText(mPost.getTitle()); + mCommentsData = new ArrayList<>(); + + mRecyclerView.setNestedScrollingEnabled(false); + mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL)); + + fetchComment(); + bindView(); + initializeButtonOnClickListener(); + } + + private void bindView() { + mTitleTextView.setText(mPost.getTitle()); - glide = Glide.with(this); if(mPost.getSubredditIconUrl() == null) { mLoadSubredditIconAsyncTask = new LoadSubredditIconAsyncTask( SubredditRoomDatabase.getDatabase(this).subredditDao(), mPost.getSubredditNamePrefixed().substring(2), iconImageUrl -> { if(!iconImageUrl.equals("")) { - glide.load(iconImageUrl) + mGlide.load(iconImageUrl) .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(glide.load(R.drawable.subreddit_default_icon) + .error(mGlide.load(R.drawable.subreddit_default_icon) .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) .into(mSubredditIconGifImageView); } else { - glide.load(R.drawable.subreddit_default_icon) + mGlide.load(R.drawable.subreddit_default_icon) .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) .into(mSubredditIconGifImageView); } @@ -173,13 +198,13 @@ public class ViewPostDetailActivity extends AppCompatActivity { }); mLoadSubredditIconAsyncTask.execute(); } else if(!mPost.getSubredditIconUrl().equals("")) { - glide.load(mPost.getSubredditIconUrl()) + mGlide.load(mPost.getSubredditIconUrl()) .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(glide.load(R.drawable.subreddit_default_icon) + .error(mGlide.load(R.drawable.subreddit_default_icon) .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) .into(mSubredditIconGifImageView); } else { - glide.load(R.drawable.subreddit_default_icon) + mGlide.load(R.drawable.subreddit_default_icon) .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) .into(mSubredditIconGifImageView); } @@ -193,6 +218,9 @@ public class ViewPostDetailActivity extends AppCompatActivity { //Downvote mDownvoteButton.setColorFilter(ContextCompat.getColor(this, R.color.minusButtonColor), PorterDuff.Mode.SRC_IN); break; + case 0: + mUpvoteButton.clearColorFilter(); + mDownvoteButton.clearColorFilter(); } if(mPost.getPostType() != Post.TEXT_TYPE && mPost.getPostType() != Post.NO_PREVIEW_LINK_TYPE) { @@ -200,30 +228,22 @@ public class ViewPostDetailActivity extends AppCompatActivity { mImageView.setVisibility(View.VISIBLE); mImageView.setRatio((float) mPost.getPreviewHeight() / (float) mPost.getPreviewWidth()); loadImage(); + } else { + mRelativeLayout.setVisibility(View.GONE); + mImageView.setVisibility(View.GONE); } if(mPost.isCrosspost()) { mCrosspostImageView.setVisibility(View.VISIBLE); } - mLayoutManager = new LinearLayoutManager(this); - mRecyclerView.setNestedScrollingEnabled(false); - mRecyclerView.setLayoutManager(mLayoutManager); - mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL)); - mSubredditTextView.setText(mPost.getSubredditNamePrefixed()); - mSubredditIconNameLinearLayout.setOnClickListener(view -> { - Intent intent = new Intent(ViewPostDetailActivity.this, ViewSubredditDetailActivity.class); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, - mPost.getSubredditNamePrefixed().substring(2)); - startActivity(intent); - }); mPostTimeTextView.setText(mPost.getPostTime()); if(mPost.getGilded() > 0) { mGildedImageView.setVisibility(View.VISIBLE); - glide.load(R.drawable.gold).into(mGildedImageView); + mGlide.load(R.drawable.gold).into(mGildedImageView); mGildedNumberTextView.setVisibility(View.VISIBLE); String gildedNumber = getResources().getString(R.string.gilded, mPost.getGilded()); mGildedNumberTextView.setText(gildedNumber); @@ -231,16 +251,12 @@ public class ViewPostDetailActivity extends AppCompatActivity { if(mPost.isNSFW()) { mNSFWChip.setVisibility(View.VISIBLE); + } else { + mNSFWChip.setVisibility(View.GONE); } - mScoreTextView.setText(Integer.toString(mPost.getScore() + mPost.getVoteType())); - mShareButton.setOnClickListener(view -> { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("text/plain"); - String extraText = mPost.getTitle() + "\n" + mPost.getPermalink(); - intent.putExtra(Intent.EXTRA_TEXT, extraText); - startActivity(Intent.createChooser(intent, "Share")); - }); + String scoreWithVote = Integer.toString(mPost.getScore() + mPost.getVoteType()); + mScoreTextView.setText(scoreWithVote); switch (mPost.getPostType()) { case Post.IMAGE_TYPE: @@ -329,8 +345,23 @@ public class ViewPostDetailActivity extends AppCompatActivity { } break; } + } - fetchComment(); + private void initializeButtonOnClickListener() { + mSubredditIconNameLinearLayout.setOnClickListener(view -> { + Intent intent = new Intent(ViewPostDetailActivity.this, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, + mPost.getSubredditNamePrefixed().substring(2)); + startActivity(intent); + }); + + mShareButton.setOnClickListener(view -> { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + String extraText = mPost.getTitle() + "\n" + mPost.getPermalink(); + intent.putExtra(Intent.EXTRA_TEXT, extraText); + startActivity(Intent.createChooser(intent, "Share")); + }); mUpvoteButton.setOnClickListener(view -> { ColorFilter previousUpvoteButtonColorFilter = mUpvoteButton.getColorFilter(); @@ -355,7 +386,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { mScoreTextView.setText(Integer.toString(mPost.getScore() + mPost.getVoteType())); if(postListPosition != -1) { - EventBus.getDefault().post(new VoteEventToPostList(postListPosition, mPost.getVoteType())); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); } VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingWithoutPositionListener() { @@ -373,7 +404,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { mScoreTextView.setText(Integer.toString(mPost.getScore() + mPost.getVoteType())); if(postListPosition != -1) { - EventBus.getDefault().post(new VoteEventToPostList(postListPosition, mPost.getVoteType())); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); } } @@ -386,7 +417,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { mDownvoteButton.setColorFilter(previousDownvoteButtonColorFilter); if(postListPosition != -1) { - EventBus.getDefault().post(new VoteEventToPostList(postListPosition, mPost.getVoteType())); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); } } }, mPost.getFullName(), newVoteType); @@ -415,7 +446,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { mScoreTextView.setText(Integer.toString(mPost.getScore() + mPost.getVoteType())); if(postListPosition != -1) { - EventBus.getDefault().post(new VoteEventToPostList(postListPosition, mPost.getVoteType())); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); } VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingWithoutPositionListener() { @@ -433,7 +464,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { mScoreTextView.setText(Integer.toString(mPost.getScore() + mPost.getVoteType())); if(postListPosition != -1) { - EventBus.getDefault().post(new VoteEventToPostList(postListPosition, mPost.getVoteType())); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); } } @@ -446,7 +477,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { mDownvoteButton.setColorFilter(previousDownvoteButtonColorFilter); if(postListPosition != -1) { - EventBus.getDefault().post(new VoteEventToPostList(postListPosition, mPost.getVoteType())); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); } } }, mPost.getFullName(), newVoteType); @@ -454,30 +485,32 @@ public class ViewPostDetailActivity extends AppCompatActivity { } private void fetchComment() { + mCommentCardView.setVisibility(View.GONE); mCommentProgressbar.setVisibility(View.VISIBLE); mNoCommentWrapperLinearLayout.setVisibility(View.GONE); + FetchComment.fetchComment(mRetrofit, mPost.getSubredditNamePrefixed(), mPost.getId(), - null, getResources().getConfiguration().locale, true, 0, new FetchComment.FetchCommentListener() { + null, mLocale, true, 0, new FetchComment.FetchCommentListener() { @Override - public void onFetchCommentSuccess(List<?> commentData, + public void onFetchCommentSuccess(List<?> commentsData, String parentId, ArrayList<String> children) { ViewPostDetailActivity.this.children = children; mCommentProgressbar.setVisibility(View.GONE); - if (commentData.size() > 0) { - mAdapter = new CommentMultiLevelRecyclerViewAdapter( - ViewPostDetailActivity.this, mRetrofit, mOauthRetrofit, - mSharedPreferences, (ArrayList<CommentData>) commentData, - mRecyclerView, mPost.getSubredditNamePrefixed(), - mPost.getId(), getResources().getConfiguration().locale); - mRecyclerView.removeItemClickListeners(); - mRecyclerView.setToggleItemOnClick(false); - mRecyclerView.setAccordion(false); - mRecyclerView.setAdapter(mAdapter); - mCommentCardView.setVisibility(View.VISIBLE); - - mNestedScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() { - @Override - public void onScrollChanged() { + mCommentsData.addAll((ArrayList<CommentData>) commentsData); + + if (mCommentsData.size() > 0) { + if(mAdapter == null) { + mAdapter = new CommentMultiLevelRecyclerViewAdapter( + ViewPostDetailActivity.this, mRetrofit, mOauthRetrofit, + mSharedPreferences, mCommentsData, + mRecyclerView, mPost.getSubredditNamePrefixed(), + mPost.getId(), mLocale); + mRecyclerView.setAdapter(mAdapter); + mRecyclerView.removeItemClickListeners(); + mRecyclerView.setToggleItemOnClick(false); + mRecyclerView.setAccordion(false); + + mNestedScrollView.getViewTreeObserver().addOnScrollChangedListener(() -> { if(!isLoadingMoreChildren) { View view = mNestedScrollView.getChildAt(mNestedScrollView.getChildCount() - 1); int diff = view.getBottom() - (mNestedScrollView.getHeight() + @@ -486,11 +519,15 @@ public class ViewPostDetailActivity extends AppCompatActivity { fetchMoreComment(mChildrenStartingIndex); } } - } - }); + }); + } else { + mAdapter.notifyDataSetChanged(); + } + + mCommentCardView.setVisibility(View.VISIBLE); } else { mNoCommentWrapperLinearLayout.setVisibility(View.VISIBLE); - glide.load(R.drawable.no_comment_indicator).into(mNoCommentImageView); + mGlide.load(R.drawable.no_comment_indicator).into(mNoCommentImageView); } } @@ -505,11 +542,10 @@ public class ViewPostDetailActivity extends AppCompatActivity { private void fetchMoreComment(int startingIndex) { isLoadingMoreChildren = true; FetchComment.fetchMoreComment(mRetrofit, mPost.getSubredditNamePrefixed(), mPost.getFullName(), - children, startingIndex, getResources().getConfiguration().locale, - new FetchComment.FetchMoreCommentListener() { + children, startingIndex, mLocale, new FetchComment.FetchMoreCommentListener() { @Override - public void onFetchMoreCommentSuccess(List<?> commentData, int childrenStartingIndex) { - mAdapter.addComments((ArrayList<CommentData>) commentData); + public void onFetchMoreCommentSuccess(List<?> commentsData, int childrenStartingIndex) { + mAdapter.addComments((ArrayList<CommentData>) commentsData); mChildrenStartingIndex = childrenStartingIndex; isLoadingMoreChildren = false; } @@ -525,7 +561,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { } private void loadImage() { - RequestBuilder imageRequestBuilder = glide.load(mPost.getPreviewUrl()) + RequestBuilder imageRequestBuilder = mGlide.load(mPost.getPreviewUrl()) .apply(new RequestOptions().override(mPost.getPreviewWidth(), mPost.getPreviewHeight())) .listener(new RequestListener<Drawable>() { @Override @@ -582,8 +618,41 @@ public class ViewPostDetailActivity extends AppCompatActivity { snackbar.show(); } + private void refresh() { + if(!isRefreshing) { + isRefreshing = true; + + if(mAdapter != null && mCommentsData != null) { + int size = mCommentsData.size(); + mCommentsData.clear(); + mAdapter.notifyItemRangeRemoved(0, size); + } + + fetchComment(); + + String accessToken = getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE) + .getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, ""); + FetchPost.fetchPost(mOauthRetrofit, mPost.getId(), accessToken, mLocale, + new FetchPost.FetchPostListener() { + @Override + public void fetchPostSuccess(Post post) { + mPost = post; + bindView(); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); + isRefreshing = false; + } + + @Override + public void fetchPostFailed() { + Snackbar.make(mCoordinatorLayout, R.string.refresh_post_failed, Snackbar.LENGTH_SHORT); + isRefreshing = false; + } + }); + } + } + @Subscribe - public void onVoteEvent(VoteEventToDetailActivity event) { + public void onPostUpdateEvent(PostUpdateEventToDetailActivity event) { if(mPost.getId().equals(event.postId)) { mPost.setVoteType(event.voteType); mScoreTextView.setText(Integer.toString(mPost.getScore() + event.voteType)); @@ -591,8 +660,17 @@ public class ViewPostDetailActivity extends AppCompatActivity { } @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.view_post_detail_activity, menu); + return true; + } + + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { + case R.id.action_refresh_view_post_detail_activity: + refresh(); + return true; case android.R.id.home: onBackPressed(); return true; @@ -605,6 +683,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { super.onSaveInstanceState(outState); outState.putInt(ORIENTATION_STATE, orientation); outState.putParcelable(POST_STATE, mPost); + outState.putBoolean(IS_REFRESHING_STATE, isRefreshing); } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/VoteEventToPostList.java b/app/src/main/java/ml/docilealligator/infinityforreddit/VoteEventToPostList.java deleted file mode 100644 index 5de4d799..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/VoteEventToPostList.java +++ /dev/null @@ -1,11 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -public class VoteEventToPostList { - public final int positionInList; - public final int voteType; - - public VoteEventToPostList(int positionInList, int voteType) { - this.positionInList = positionInList; - this.voteType = voteType; - } -} diff --git a/app/src/main/res/menu/view_post_detail_activity.xml b/app/src/main/res/menu/view_post_detail_activity.xml new file mode 100644 index 00000000..c0f667f9 --- /dev/null +++ b/app/src/main/res/menu/view_post_detail_activity.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <item + android:id="@+id/action_refresh_view_post_detail_activity" + android:orderInCategory="2" + android:title="@string/action_refresh" + android:icon="@drawable/ic_refresh_white_24dp" + app:showAsAction="always" /> +</menu>
\ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 85fc75f9..bf1a320d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -26,6 +26,7 @@ <string name="comments">Comments</string> <string name="no_comments_yet">No comments yet. Write a comment?</string> <string name="vote_failed">Vote failed</string> + <string name="refresh_post_failed">Error refreshing the post</string> <string name="nsfw">NSFW</string> <string name="karma_info">Karma: %1$d</string> |