From d8669c94e88345e1ed55468ba60aa5570bb1b745 Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Thu, 11 Jul 2019 16:32:27 +0800 Subject: Submitting posts to subreddit is available now. Fixed User's posts cannot be all loaded. --- .../infinityforreddit/AppComponent.java | 1 + .../infinityforreddit/CommentActivity.java | 4 +- .../infinityforreddit/JSONUtils.java | 1 + .../infinityforreddit/PostDataSource.java | 77 ++++++++------- .../infinityforreddit/PostRecyclerViewAdapter.java | 1 - .../infinityforreddit/PostTextActivity.java | 55 +++++++++++ .../infinityforreddit/RedditAPI.java | 4 + .../infinityforreddit/RedditUtils.java | 8 ++ .../infinityforreddit/SubmitPost.java | 109 +++++++++++++++++++++ .../SubredditSelectionActivity.java | 2 +- .../SubscribedSubredditsListingFragment.java | 6 +- .../SubscribedThingListingActivity.java | 6 +- .../infinityforreddit/ViewPostDetailActivity.java | 33 ------- 13 files changed, 231 insertions(+), 76 deletions(-) create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubmitPost.java (limited to 'app/src/main/java') diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java index aa906d2a..db457e0c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java @@ -17,4 +17,5 @@ interface AppComponent { void inject(ViewUserDetailActivity viewUserDetailActivity); void inject(CommentActivity commentActivity); void inject(SubscribedThingListingActivity subscribedThingListingActivity); + void inject(PostTextActivity postTextActivity); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentActivity.java index e05d4d17..b4560802 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentActivity.java @@ -121,7 +121,9 @@ public class CommentActivity extends AppCompatActivity { finish(); } }); + return true; } - return super.onOptionsItemSelected(item); + + return false; } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java index 8b2f3374..433f22d0 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java @@ -70,4 +70,5 @@ public class JSONUtils { static final String JSON_KEY = "json"; static final String THINGS_KEY = "things"; static final String PARENT_ID_KEY = "parent_id"; + static final String ERRORS_KEY = "errors"; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java index 4aa84343..88101048 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java @@ -2,12 +2,13 @@ package ml.docilealligator.infinityforreddit; import android.util.Log; -import java.util.ArrayList; -import java.util.Locale; - import androidx.annotation.NonNull; import androidx.lifecycle.MutableLiveData; import androidx.paging.PageKeyedDataSource; + +import java.util.ArrayList; +import java.util.Locale; + import retrofit2.Call; import retrofit2.Callback; import retrofit2.Retrofit; @@ -114,7 +115,7 @@ class PostDataSource extends PageKeyedDataSource { loadSubredditPostsAfter(params, callback); break; case TYPE_USER: - loadUserPostsAfter(params, callback); + loadUserPostsAfter(params, callback, null); break; case TYPE_SEARCH: loadSearchPostsAfter(params, callback); @@ -157,8 +158,8 @@ class PostDataSource extends PageKeyedDataSource { } @Override - public void onFailure(Call call, Throwable t) { - String errorMessage = t == null ? "unknown error" : t.getMessage(); + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); } }); @@ -170,7 +171,7 @@ class PostDataSource extends PageKeyedDataSource { bestPost.enqueue(new Callback() { @Override - public void onResponse(Call call, retrofit2.Response response) { + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { if(response.isSuccessful()) { ParsePost.parsePosts(response.body(), locale, new ParsePost.ParsePostsListingListener() { @Override @@ -192,8 +193,8 @@ class PostDataSource extends PageKeyedDataSource { } @Override - public void onFailure(Call call, Throwable t) { - String errorMessage = t == null ? "unknown error" : t.getMessage(); + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); } }); @@ -204,7 +205,7 @@ class PostDataSource extends PageKeyedDataSource { Call getPost = api.getSubredditBestPosts(name, null, RedditUtils.getOAuthHeader(accessToken)); getPost.enqueue(new Callback() { @Override - public void onResponse(Call call, retrofit2.Response response) { + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { if(response.isSuccessful()) { ParsePost.parsePosts(response.body(), locale, new ParsePost.ParsePostsListingListener() { @@ -233,8 +234,8 @@ class PostDataSource extends PageKeyedDataSource { } @Override - public void onFailure(Call call, Throwable t) { - String errorMessage = t == null ? "unknown error" : t.getMessage(); + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); } }); @@ -245,7 +246,7 @@ class PostDataSource extends PageKeyedDataSource { Call getPost = api.getSubredditBestPosts(name, params.key, RedditUtils.getOAuthHeader(accessToken)); getPost.enqueue(new Callback() { @Override - public void onResponse(Call call, retrofit2.Response response) { + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { if(response.isSuccessful()) { ParsePost.parsePosts(response.body(), locale, new ParsePost.ParsePostsListingListener() { @Override @@ -267,8 +268,8 @@ class PostDataSource extends PageKeyedDataSource { } @Override - public void onFailure(Call call, Throwable t) { - String errorMessage = t == null ? "unknown error" : t.getMessage(); + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); } }); @@ -279,7 +280,7 @@ class PostDataSource extends PageKeyedDataSource { Call getPost = api.getUserBestPosts(name, lastItem, RedditUtils.getOAuthHeader(accessToken)); getPost.enqueue(new Callback() { @Override - public void onResponse(Call call, retrofit2.Response response) { + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { if(response.isSuccessful()) { ParsePost.parsePosts(response.body(), locale, new ParsePost.ParsePostsListingListener() { @@ -311,42 +312,48 @@ class PostDataSource extends PageKeyedDataSource { } @Override - public void onFailure(Call call, Throwable t) { - String errorMessage = t == null ? "unknown error" : t.getMessage(); + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); } }); } - private void loadUserPostsAfter(@NonNull LoadParams params, @NonNull final LoadCallback callback) { + private void loadUserPostsAfter(@NonNull LoadParams params, @NonNull final LoadCallback callback, String lastItem) { + String after = lastItem == null ? params.key : lastItem; + RedditAPI api = retrofit.create(RedditAPI.class); - Call getPost = api.getUserBestPosts(name, params.key, RedditUtils.getOAuthHeader(accessToken)); + Call getPost = api.getUserBestPosts(name, after, RedditUtils.getOAuthHeader(accessToken)); getPost.enqueue(new Callback() { @Override - public void onResponse(Call call, retrofit2.Response response) { + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { if(response.isSuccessful()) { ParsePost.parsePosts(response.body(), locale, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(ArrayList newPosts, String lastItem) { - callback.onResult(newPosts, lastItem); - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); + if(newPosts.size() == 0 && !lastItem.equals("null")) { + loadUserPostsAfter(params, callback, lastItem); + } else { + callback.onResult(newPosts, lastItem); + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); + } } @Override public void onParsePostsListingFail() { - Log.i("Best post", "Error parsing data"); + Log.i("User posts", "Error parsing data"); paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); } }); } else { - Log.i("Best post", response.message()); + Log.i("User posts", response.message()); paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); } } @Override - public void onFailure(Call call, Throwable t) { - String errorMessage = t == null ? "unknown error" : t.getMessage(); + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); } }); @@ -357,7 +364,7 @@ class PostDataSource extends PageKeyedDataSource { Call getPost = api.searchPosts(name, null, RedditUtils.getOAuthHeader(accessToken)); getPost.enqueue(new Callback() { @Override - public void onResponse(Call call, retrofit2.Response response) { + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { if(response.isSuccessful()) { ParsePost.parsePosts(response.body(), locale, new ParsePost.ParsePostsListingListener() { @@ -386,8 +393,8 @@ class PostDataSource extends PageKeyedDataSource { } @Override - public void onFailure(Call call, Throwable t) { - String errorMessage = t == null ? "unknown error" : t.getMessage(); + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); } }); @@ -398,7 +405,7 @@ class PostDataSource extends PageKeyedDataSource { Call getPost = api.searchPosts(name, params.key, RedditUtils.getOAuthHeader(accessToken)); getPost.enqueue(new Callback() { @Override - public void onResponse(Call call, retrofit2.Response response) { + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { if(response.isSuccessful()) { ParsePost.parsePosts(response.body(), locale, new ParsePost.ParsePostsListingListener() { @Override @@ -409,19 +416,19 @@ class PostDataSource extends PageKeyedDataSource { @Override public void onParsePostsListingFail() { - Log.i("Best post", "Error parsing data"); + Log.i("Search post", "Error parsing data"); paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); } }); } else { - Log.i("Best post", response.message()); + Log.i("Search post", response.message()); paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); } } @Override - public void onFailure(Call call, Throwable t) { - String errorMessage = t == null ? "unknown error" : t.getMessage(); + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); } }); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java index 1541a233..bb63a905 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java @@ -145,7 +145,6 @@ class PostRecyclerViewAdapter extends PagedListAdapter delete(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @POST("/api/submit") + Call submit(@HeaderMap Map headers, @FieldMap Map params); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditUtils.java index c6964764..faf58e4a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditUtils.java @@ -49,10 +49,18 @@ public class RedditUtils { static final String SR_NAME_KEY = "sr_name"; static final String API_TYPE_KEY = "api_type"; + static final String API_TYPE_JSON = "json"; static final String RETURN_RTJSON_KEY = "return_rtjson"; static final String TEXT_KEY = "text"; static final String THING_ID_KEY = "thing_id"; + static final String SR_KEY = "sr"; + static final String TITLE_KEY = "title"; + static final String NSFW_KEY = "nsfw"; + static final String KIND_KEY = "kind"; + static final String KIND_TEXT = "text"; + static final String KIND_SELF = "self"; + static Map getHttpBasicAuthHeader() { Map params = new HashMap<>(); String credentials = String.format("%s:%s", RedditUtils.CLIENT_ID, ""); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubmitPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubmitPost.java new file mode 100644 index 00000000..7de16719 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubmitPost.java @@ -0,0 +1,109 @@ +package ml.docilealligator.infinityforreddit; + +import android.content.SharedPreferences; +import android.util.Log; + +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Retrofit; + +class SubmitPost { + interface SubmitPostListener { + void submitSuccessful(Post post); + void submitFailed(); + } + + static void submitPostText(Retrofit oauthRetrofit, SharedPreferences authInfoSharedPreferences, + Locale locale, String subredditName, String title, String text, boolean isNSFW, + SubmitPostListener submitPostListener) { + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + String accessToken = authInfoSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, ""); + + Map params = new HashMap<>(); + params.put(RedditUtils.API_TYPE_KEY, RedditUtils.API_TYPE_JSON); + params.put(RedditUtils.SR_KEY, subredditName); + params.put(RedditUtils.TITLE_KEY, title); + params.put(RedditUtils.KIND_KEY, RedditUtils.KIND_TEXT); + params.put(RedditUtils.TEXT_KEY, text); + params.put(RedditUtils.NSFW_KEY, Boolean.toString(isNSFW)); + + Call submitPostCall = api.submit(RedditUtils.getOAuthHeader(accessToken), params); + submitPostCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + Log.i("code", "asfd" + response.body()); + if(response.isSuccessful()) { + try { + getSubmittedPost(response.body(), oauthRetrofit, authInfoSharedPreferences, locale, + submitPostListener); + } catch (JSONException e) { + e.printStackTrace(); + submitPostListener.submitFailed(); + } + } else { + Log.i("call_failed", response.message()); + submitPostListener.submitFailed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.i("call_failed", call.request().url().toString()); + submitPostListener.submitFailed(); + } + }); + } + + private static void getSubmittedPost(String response, Retrofit oauthRetrofit, + SharedPreferences authInfoSharedPreferences, Locale locale, + SubmitPostListener submitPostListener) throws JSONException { + JSONObject responseObject = new JSONObject(response); + if(responseObject.getJSONObject(JSONUtils.JSON_KEY).getJSONArray(JSONUtils.ERRORS_KEY).length() != 0) { + submitPostListener.submitFailed(); + return; + } + + String postId = responseObject.getJSONObject(JSONUtils.JSON_KEY).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.ID_KEY); + + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + String accessToken = authInfoSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, ""); + + Call getPostCall = api.getPost(postId, RedditUtils.getOAuthHeader(accessToken)); + getPostCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if(response.isSuccessful()) { + ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() { + @Override + public void onParsePostSuccess(Post post) { + submitPostListener.submitSuccessful(post); + } + + @Override + public void onParsePostFail() { + submitPostListener.submitFailed(); + } + }); + } else { + Log.i("call_failed", response.message()); + submitPostListener.submitFailed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.i("call_failed", call.request().url().toString()); + submitPostListener.submitFailed(); + } + }); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditSelectionActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditSelectionActivity.java index 3d565f3c..eece6d5c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditSelectionActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditSelectionActivity.java @@ -33,7 +33,7 @@ public class SubredditSelectionActivity extends AppCompatActivity { SubscribedSubredditsListingFragment fragment = new SubscribedSubredditsListingFragment(); Bundle bundle = new Bundle(); - bundle.putInt(PostFragment.POST_TYPE_KEY, PostDataSource.TYPE_FRONT_PAGE); + bundle.putBoolean(SubscribedSubredditsListingFragment.EXTRA_IS_SUBREDDIT_SELECTION, true); fragment.setArguments(bundle); getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_subreddit_selection_activity, fragment).commit(); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditsListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditsListingFragment.java index 476782cb..2950d88c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditsListingFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditsListingFragment.java @@ -60,11 +60,9 @@ public class SubscribedSubredditsListingFragment extends Fragment { SubscribedSubredditsRecyclerViewAdapter adapter; if(getArguments().getBoolean(EXTRA_IS_SUBREDDIT_SELECTION)) { - adapter = new SubscribedSubredditsRecyclerViewAdapter(mActivity); + adapter = new SubscribedSubredditsRecyclerViewAdapter(mActivity, (name, iconUrl) -> ((SubredditSelectionActivity) mActivity).getSelectedSubreddit(name, iconUrl)); } else { - adapter = new SubscribedSubredditsRecyclerViewAdapter(mActivity, (name, iconUrl) -> { - ((SubredditSelectionActivity) mActivity).getSelectedSubreddit(name, iconUrl); - }); + adapter = new SubscribedSubredditsRecyclerViewAdapter(mActivity); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedThingListingActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedThingListingActivity.java index ce3a8b72..92568a9f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedThingListingActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedThingListingActivity.java @@ -129,7 +129,11 @@ public class SubscribedThingListingActivity extends AppCompatActivity { public Fragment getItem(int position) { switch (position) { case 0: { - return new SubscribedSubredditsListingFragment(); + SubscribedSubredditsListingFragment fragment = new SubscribedSubredditsListingFragment(); + Bundle bundle = new Bundle(); + bundle.putBoolean(SubscribedSubredditsListingFragment.EXTRA_IS_SUBREDDIT_SELECTION, false); + fragment.setArguments(bundle); + return fragment; } default: { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java index 96084fc6..9b8529ed 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java @@ -38,7 +38,6 @@ import static ml.docilealligator.infinityforreddit.CommentActivity.WRITE_COMMENT public class ViewPostDetailActivity extends AppCompatActivity { - static final String EXTRA_TITLE = "ET"; static final String EXTRA_POST_DATA = "EPD"; static final String EXTRA_POST_LIST_POSITION = "EPLI"; @@ -185,38 +184,6 @@ public class ViewPostDetailActivity extends AppCompatActivity { } }); } - - /*mCommentProgressbar.setVisibility(View.GONE); - - if (expandedComments.size() > 0) { - if(mAdapter == null) { - mNestedScrollView.getViewTreeObserver().addOnScrollChangedListener(() -> { - if(!isLoadingMoreChildren) { - View view = mNestedScrollView.getChildAt(mNestedScrollView.getChildCount() - 1); - int diff = view.getBottom() - (mNestedScrollView.getHeight() + - mNestedScrollView.getScrollY()); - if(diff == 0) { - fetchMoreComments(mChildrenStartingIndex); - } - } - }); - } - - mAdapter = new CommentRecyclerViewAdapter(ViewPostDetailActivity.this, mRetrofit, - mOauthRetrofit, mGlide, mSharedPreferences, mPost, - mPost.getSubredditNamePrefixed(), mLocale, new CommentRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { - @Override - public void updatePost(Post post) { - EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); - } - }); - mRecyclerView.setAdapter(mAdapter); - - //mCommentCardView.setVisibility(View.VISIBLE); - } else { - mNoCommentWrapperLinearLayout.setVisibility(View.VISIBLE); - mGlide.load(R.drawable.no_comment_placeholder).into(mNoCommentImageView); - }*/ } @Override -- cgit v1.2.3