diff options
author | Alex Ning <chineseperson5@gmail.com> | 2019-08-05 07:28:53 +0000 |
---|---|---|
committer | Alex Ning <chineseperson5@gmail.com> | 2019-08-05 07:28:53 +0000 |
commit | 199690355be9fb461ceddc346a9cc68a75940aa1 (patch) | |
tree | 983184cdc1c6c17118eabc3b7d29c61d141ce731 | |
parent | 0d1fcecde60bbb1eb3b43736807883b12e54b2e8 (diff) | |
download | infinity-for-reddit-199690355be9fb461ceddc346a9cc68a75940aa1.tar infinity-for-reddit-199690355be9fb461ceddc346a9cc68a75940aa1.tar.gz infinity-for-reddit-199690355be9fb461ceddc346a9cc68a75940aa1.tar.bz2 infinity-for-reddit-199690355be9fb461ceddc346a9cc68a75940aa1.tar.lz infinity-for-reddit-199690355be9fb461ceddc346a9cc68a75940aa1.tar.xz infinity-for-reddit-199690355be9fb461ceddc346a9cc68a75940aa1.tar.zst infinity-for-reddit-199690355be9fb461ceddc346a9cc68a75940aa1.zip |
Filtering posts to specific type when the type chip is clicked in posts. Minor bugs fixed related to PostDataSource to continue loading posts.
20 files changed, 460 insertions, 150 deletions
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser Binary files differindex 4e46c294..95a34af4 100644 --- a/.idea/caches/build_file_checksums.ser +++ b/.idea/caches/build_file_checksums.ser diff --git a/.idea/caches/gradle_models.ser b/.idea/caches/gradle_models.ser Binary files differindex 52d3c3c9..ce72386a 100644 --- a/.idea/caches/gradle_models.ser +++ b/.idea/caches/gradle_models.ser diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ed7e1a17..c9493e9a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,6 +20,10 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true"> <activity + android:name=".FilteredPostsActivity" + android:parentActivityName=".MainActivity" + android:theme="@style/AppTheme.NoActionBar" /> + <activity android:name=".SearchSubredditsResultActivity" android:label="@string/search_subreddits_activity_label" android:parentActivityName=".MainActivity" @@ -74,8 +78,8 @@ android:name=".PostTextActivity" android:label="@string/post_text_activity_label" android:parentActivityName=".MainActivity" - android:windowSoftInputMode="adjustResize" - android:theme="@style/AppTheme.NoActionBar" /> + android:theme="@style/AppTheme.NoActionBar" + android:windowSoftInputMode="adjustResize" /> <activity android:name=".CommentActivity" android:label="@string/comment_activity_label" diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FilteredPostsActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FilteredPostsActivity.java new file mode 100644 index 00000000..4cddd4d9 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FilteredPostsActivity.java @@ -0,0 +1,111 @@ +package ml.docilealligator.infinityforreddit; + +import android.os.Bundle; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class FilteredPostsActivity extends AppCompatActivity { + + static final String EXTRA_NAME = "ESN"; + static final String EXTRA_QUERY = "EQ"; + static final String EXTRA_FILTER = "EF"; + static final String EXTRA_POST_TYPE = "EPT"; + static final String EXTRA_SORT_TYPE = "EST"; + + private static final String FRAGMENT_OUT_STATE = "FOS"; + + @BindView(R.id.toolbar_filtered_posts_activity) Toolbar toolbar; + + private Fragment mFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_filtered_posts); + + ButterKnife.bind(this); + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + String name = getIntent().getExtras().getString(EXTRA_NAME); + int filter = getIntent().getExtras().getInt(EXTRA_FILTER); + int postType = getIntent().getExtras().getInt(EXTRA_POST_TYPE); + String sortType = getIntent().getExtras().getString(EXTRA_SORT_TYPE); + + switch (postType) { + case PostDataSource.TYPE_FRONT_PAGE: + getSupportActionBar().setTitle(name); + break; + case PostDataSource.TYPE_SEARCH: + getSupportActionBar().setTitle(R.string.search); + break; + case PostDataSource.TYPE_SUBREDDIT: + String subredditNamePrefixed = "r/" + name; + getSupportActionBar().setTitle(subredditNamePrefixed); + case PostDataSource.TYPE_USER: + String usernamePrefixed = "u/" + name; + getSupportActionBar().setTitle(usernamePrefixed); + break; + } + + switch (filter) { + case Post.TEXT_TYPE: + toolbar.setSubtitle(R.string.text); + break; + case Post.LINK_TYPE: + case Post.NO_PREVIEW_LINK_TYPE: + toolbar.setSubtitle(R.string.link); + break; + case Post.IMAGE_TYPE: + toolbar.setSubtitle(R.string.image); + break; + case Post.VIDEO_TYPE: + toolbar.setSubtitle(R.string.video); + break; + case Post.GIF_VIDEO_TYPE: + toolbar.setSubtitle(R.string.gif); + } + + if(savedInstanceState == null) { + mFragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putString(PostFragment.EXTRA_NAME, name); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, postType); + bundle.putString(PostFragment.EXTRA_SORT_TYPE, sortType); + bundle.putInt(PostFragment.EXTRA_FILTER, filter); + if(postType == PostDataSource.TYPE_SEARCH) { + bundle.putString(PostFragment.EXTRA_QUERY, getIntent().getExtras().getString(EXTRA_QUERY)); + } + mFragment.setArguments(bundle); + getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_filtered_posts_activity, mFragment).commit(); + } else { + mFragment = getSupportFragmentManager().getFragment(savedInstanceState, FRAGMENT_OUT_STATE); + getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_filtered_posts_activity, mFragment).commit(); + } + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if(item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + if (mFragment != null) { + getSupportFragmentManager().putFragment(outState, FRAGMENT_OUT_STATE, mFragment); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java index 64662e0a..7b284a79 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java @@ -389,22 +389,25 @@ public class MainActivity extends AppCompatActivity implements SortTypeBottomShe Bundle bundle = new Bundle(); bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_FRONT_PAGE); bundle.putString(PostFragment.EXTRA_SORT_TYPE, PostDataSource.SORT_TYPE_BEST); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); fragment.setArguments(bundle); return fragment; } else if(position == 1) { PostFragment fragment = new PostFragment(); Bundle bundle = new Bundle(); bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); - bundle.putString(PostFragment.EXTRA_SUBREDDIT_NAME, "popular"); + bundle.putString(PostFragment.EXTRA_NAME, "popular"); bundle.putString(PostFragment.EXTRA_SORT_TYPE, PostDataSource.SORT_TYPE_HOT); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); fragment.setArguments(bundle); return fragment; } else { PostFragment fragment = new PostFragment(); Bundle bundle = new Bundle(); bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); - bundle.putString(PostFragment.EXTRA_SUBREDDIT_NAME, "all"); + bundle.putString(PostFragment.EXTRA_NAME, "all"); bundle.putString(PostFragment.EXTRA_SORT_TYPE, PostDataSource.SORT_TYPE_HOT); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); fragment.setArguments(bundle); return fragment; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java index 7003d91a..05890b9b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java @@ -28,8 +28,8 @@ class ParsePost { void onParsePostFail(); } - static void parsePosts(String response, Locale locale, int nPosts, ParsePostsListingListener parsePostsListingListener) { - new ParsePostDataAsyncTask(response, locale, nPosts, parsePostsListingListener).execute(); + static void parsePosts(String response, Locale locale, int nPosts, int filter, ParsePostsListingListener parsePostsListingListener) { + new ParsePostDataAsyncTask(response, locale, nPosts, filter, parsePostsListingListener).execute(); } static void parsePost(String response, Locale locale, ParsePostListener parsePostListener) { @@ -40,6 +40,7 @@ class ParsePost { private JSONArray allData; private Locale locale; private int nPosts; + private int filter; private ParsePostsListingListener parsePostsListingListener; private ParsePostListener parsePostListener; private ArrayList<Post> newPosts; @@ -47,7 +48,7 @@ class ParsePost { private String lastItem; private boolean parseFailed; - ParsePostDataAsyncTask(String response, Locale locale, int nPosts, + ParsePostDataAsyncTask(String response, Locale locale, int nPosts, int filter, ParsePostsListingListener parsePostsListingListener) { this.parsePostsListingListener = parsePostsListingListener; try { @@ -56,6 +57,7 @@ class ParsePost { lastItem = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); this.locale = locale; this.nPosts = nPosts; + this.filter = filter; newPosts = new ArrayList<>(); parseFailed = false; } catch (JSONException e) { @@ -104,7 +106,14 @@ class ParsePost { for(int i = 0; i < size; i++) { JSONObject data = allData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); - newPosts.add(parseBasicData(data, locale, i)); + Post post = parseBasicData(data, locale, i); + if(filter == PostFragment.EXTRA_NO_FILTER) { + newPosts.add(post); + } else if(filter == post.getPostType()) { + newPosts.add(post); + } else if(filter == Post.LINK_TYPE && post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + newPosts.add(post); + } } } } catch (JSONException e) { @@ -192,7 +201,8 @@ class ParsePost { String subredditNamePrefixed, String author, String formattedPostTime, String title, String previewUrl, int previewWidth, int previewHeight, int score, int voteType, int gilded, String flair, boolean spoiler, - boolean nsfw, boolean stickied, boolean archived, boolean isCrosspost, int i) throws JSONException { + boolean nsfw, boolean stickied, boolean archived, boolean isCrosspost, + int i) throws JSONException { Post post; boolean isVideo = data.getBoolean(JSONUtils.IS_VIDEO_KEY); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubredditData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubredditData.java index bfdb084d..22e3787c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubredditData.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubredditData.java @@ -54,7 +54,7 @@ class ParseSubredditData { JSONObject data = jsonResponse.getJSONObject(JSONUtils.DATA_KEY); mNCurrentOnlineSubscribers = data.getInt(JSONUtils.ACTIVE_USER_COUNT_KEY); subredditData = parseSubredditData(data); - /*String id = data.getString(JSONUtils.EXTRA_SUBREDDIT_NAME); + /*String id = data.getString(JSONUtils.EXTRA_NAME); String subredditFullName = data.getString(JSONUtils.DISPLAY_NAME); String description = data.getString(JSONUtils.PUBLIC_DESCRIPTION_KEY).trim(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java index ff6d5a48..6cd6730c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java @@ -37,10 +37,11 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { private Retrofit retrofit; private String accessToken; private Locale locale; - private String subredditName; + private String subredditOrUserName; private String query; private int postType; private String sortType; + private int filter; private OnPostFetchedCallback onPostFetchedCallback; private MutableLiveData<NetworkState> paginationNetworkStateLiveData; @@ -52,7 +53,7 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { private LoadCallback<String, Post> callback; PostDataSource(Retrofit retrofit, String accessToken, Locale locale, int postType, String sortType, - OnPostFetchedCallback onPostFetchedCallback) { + int filter, OnPostFetchedCallback onPostFetchedCallback) { this.retrofit = retrofit; this.accessToken = accessToken; this.locale = locale; @@ -60,45 +61,49 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { initialLoadStateLiveData = new MutableLiveData(); this.postType = postType; this.sortType = sortType; + this.filter = filter; this.onPostFetchedCallback = onPostFetchedCallback; } - PostDataSource(Retrofit retrofit, String accessToken, Locale locale, String subredditName, int postType, - String sortType, OnPostFetchedCallback onPostFetchedCallback) { + PostDataSource(Retrofit retrofit, String accessToken, Locale locale, String subredditOrUserName, int postType, + String sortType, int filter, OnPostFetchedCallback onPostFetchedCallback) { this.retrofit = retrofit; this.accessToken = accessToken; this.locale = locale; - this.subredditName = subredditName; + this.subredditOrUserName = subredditOrUserName; paginationNetworkStateLiveData = new MutableLiveData(); initialLoadStateLiveData = new MutableLiveData(); this.postType = postType; this.sortType = sortType; + this.filter = filter; this.onPostFetchedCallback = onPostFetchedCallback; } - PostDataSource(Retrofit retrofit, String accessToken, Locale locale, String subredditName, int postType, - OnPostFetchedCallback onPostFetchedCallback) { + PostDataSource(Retrofit retrofit, String accessToken, Locale locale, String subredditOrUserName, int postType, + int filter, OnPostFetchedCallback onPostFetchedCallback) { this.retrofit = retrofit; this.accessToken = accessToken; this.locale = locale; - this.subredditName = subredditName; + this.subredditOrUserName = subredditOrUserName; paginationNetworkStateLiveData = new MutableLiveData(); initialLoadStateLiveData = new MutableLiveData(); this.postType = postType; + this.filter = filter; this.onPostFetchedCallback = onPostFetchedCallback; } - PostDataSource(Retrofit retrofit, String accessToken, Locale locale, String subredditName, String query, - int postType, String sortType, OnPostFetchedCallback onPostFetchedCallback) { + PostDataSource(Retrofit retrofit, String accessToken, Locale locale, String subredditOrUserName, String query, + int postType, String sortType, int filter, OnPostFetchedCallback onPostFetchedCallback) { this.retrofit = retrofit; this.accessToken = accessToken; this.locale = locale; - this.subredditName = subredditName; + this.subredditOrUserName = subredditOrUserName; this.query = query; paginationNetworkStateLiveData = new MutableLiveData(); initialLoadStateLiveData = new MutableLiveData(); this.postType = postType; this.sortType = sortType; + this.filter = filter; this.onPostFetchedCallback = onPostFetchedCallback; } @@ -119,16 +124,16 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { switch (postType) { case TYPE_FRONT_PAGE: - loadBestPostsInitial(callback); + loadBestPostsInitial(callback, null); break; case TYPE_SUBREDDIT: - loadSubredditPostsInitial(callback); + loadSubredditPostsInitial(callback, null); break; case TYPE_USER: loadUserPostsInitial(callback, null); break; case TYPE_SEARCH: - loadSearchPostsInitial(callback); + loadSearchPostsInitial(callback, null); break; } } @@ -143,7 +148,7 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { this.params = params; this.callback = callback; - if(params.key.equals("null")) { + if(params.key.equals("") || params.key.equals("null")) { return; } @@ -151,24 +156,24 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { switch (postType) { case TYPE_FRONT_PAGE: - loadBestPostsAfter(params, callback); + loadBestPostsAfter(params, callback, null); break; case TYPE_SUBREDDIT: - loadSubredditPostsAfter(params, callback); + loadSubredditPostsAfter(params, callback, null); break; case TYPE_USER: loadUserPostsAfter(params, callback, null); break; case TYPE_SEARCH: - loadSearchPostsAfter(params, callback); + loadSearchPostsAfter(params, callback, null); break; } } - private void loadBestPostsInitial(@NonNull final LoadInitialCallback<String, Post> callback) { + private void loadBestPostsInitial(@NonNull final LoadInitialCallback<String, Post> callback, String lastItem) { RedditAPI api = retrofit.create(RedditAPI.class); - Call<String> bestPost = api.getBestPosts(sortType, null, RedditUtils.getOAuthHeader(accessToken)); + Call<String> bestPost = api.getBestPosts(sortType, lastItem, RedditUtils.getOAuthHeader(accessToken)); bestPost.enqueue(new Callback<String>() { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { @@ -191,21 +196,27 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { } }); } else { - ParsePost.parsePosts(response.body(), locale, -1, + ParsePost.parsePosts(response.body(), locale, -1, filter, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { - if(newPosts.size() == 0) { - onPostFetchedCallback.noPost(); + String nextPageKey; + if(lastItem == null || lastItem.equals("") || lastItem.equals("null")) { + nextPageKey = null; } else { - onPostFetchedCallback.hasPost(); + nextPageKey = lastItem; } - if(lastItem == null || lastItem.equals("") || lastItem.equals("null")) { - callback.onResult(newPosts, null, null); + if(newPosts.size() != 0) { + onPostFetchedCallback.hasPost(); + } else if(nextPageKey != null) { + loadBestPostsInitial(callback, nextPageKey); + return; } else { - callback.onResult(newPosts, null, lastItem); + onPostFetchedCallback.noPost(); } + + callback.onResult(newPosts, null, nextPageKey); initialLoadStateLiveData.postValue(NetworkState.LOADED); } @@ -230,23 +241,25 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { }); } - private void loadBestPostsAfter(@NonNull LoadParams<String> params, @NonNull final LoadCallback<String, Post> callback) { + private void loadBestPostsAfter(@NonNull LoadParams<String> params, @NonNull final LoadCallback<String, Post> callback, String lastItem) { + String after = lastItem == null ? params.key : lastItem; + RedditAPI api = retrofit.create(RedditAPI.class); - Call<String> bestPost = api.getBestPosts(sortType, params.key, RedditUtils.getOAuthHeader(accessToken)); + Call<String> bestPost = api.getBestPosts(sortType, after, RedditUtils.getOAuthHeader(accessToken)); bestPost.enqueue(new Callback<String>() { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if(response.isSuccessful()) { - ParsePost.parsePosts(response.body(), locale, -1, new ParsePost.ParsePostsListingListener() { + ParsePost.parsePosts(response.body(), locale, -1, filter, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { - if(lastItem == null || lastItem.equals("") || lastItem.equals("null")) { - callback.onResult(newPosts, null); + if(newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { + loadBestPostsAfter(params, callback, lastItem); } else { callback.onResult(newPosts, lastItem); + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } @Override @@ -269,9 +282,9 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { }); } - private void loadSubredditPostsInitial(@NonNull final LoadInitialCallback<String, Post> callback) { + private void loadSubredditPostsInitial(@NonNull final LoadInitialCallback<String, Post> callback, String lastItem) { RedditAPI api = retrofit.create(RedditAPI.class); - Call<String> getPost = api.getSubredditBestPosts(subredditName, sortType, null, RedditUtils.getOAuthHeader(accessToken)); + Call<String> getPost = api.getSubredditBestPosts(subredditOrUserName, sortType, lastItem, RedditUtils.getOAuthHeader(accessToken)); getPost.enqueue(new Callback<String>() { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { @@ -294,21 +307,27 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { } }); } else { - ParsePost.parsePosts(response.body(), locale, -1, + ParsePost.parsePosts(response.body(), locale, -1, filter, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { - if(newPosts.size() == 0) { - onPostFetchedCallback.noPost(); + String nextPageKey; + if(lastItem == null || lastItem.equals("") || lastItem.equals("null")) { + nextPageKey = null; } else { - onPostFetchedCallback.hasPost(); + nextPageKey = lastItem; } - if(lastItem == null || lastItem.equals("") || lastItem.equals("null")) { - callback.onResult(newPosts, null, null); + if(newPosts.size() != 0) { + onPostFetchedCallback.hasPost(); + } else if(nextPageKey != null) { + loadSubredditPostsInitial(callback, nextPageKey); + return; } else { - callback.onResult(newPosts, null, lastItem); + onPostFetchedCallback.noPost(); } + + callback.onResult(newPosts, null, nextPageKey); initialLoadStateLiveData.postValue(NetworkState.LOADED); } @@ -333,22 +352,24 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { }); } - private void loadSubredditPostsAfter(@NonNull LoadParams<String> params, @NonNull final LoadCallback<String, Post> callback) { + private void loadSubredditPostsAfter(@NonNull LoadParams<String> params, @NonNull final LoadCallback<String, Post> callback, String lastItem) { + String after = lastItem == null ? params.key : lastItem; + RedditAPI api = retrofit.create(RedditAPI.class); - Call<String> getPost = api.getSubredditBestPosts(subredditName, sortType, params.key, RedditUtils.getOAuthHeader(accessToken)); + Call<String> getPost = api.getSubredditBestPosts(subredditOrUserName, sortType, after, RedditUtils.getOAuthHeader(accessToken)); getPost.enqueue(new Callback<String>() { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if(response.isSuccessful()) { - ParsePost.parsePosts(response.body(), locale, -1, new ParsePost.ParsePostsListingListener() { + ParsePost.parsePosts(response.body(), locale, -1, filter, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { - if(lastItem == null || lastItem.equals("") || lastItem.equals("null")) { - callback.onResult(newPosts, null); + if(newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { + loadSubredditPostsAfter(params, callback, lastItem); } else { callback.onResult(newPosts, lastItem); + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } @Override @@ -373,26 +394,32 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { private void loadUserPostsInitial(@NonNull final LoadInitialCallback<String, Post> callback, String lastItem) { RedditAPI api = retrofit.create(RedditAPI.class); - Call<String> getPost = api.getUserBestPosts(subredditName, lastItem, RedditUtils.getOAuthHeader(accessToken)); + Call<String> getPost = api.getUserBestPosts(subredditOrUserName, lastItem, RedditUtils.getOAuthHeader(accessToken)); getPost.enqueue(new Callback<String>() { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if(response.isSuccessful()) { - ParsePost.parsePosts(response.body(), locale, -1, + ParsePost.parsePosts(response.body(), locale, -1, filter, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { - if(newPosts.size() == 0) { - onPostFetchedCallback.noPost(); + String nextPageKey; + if(lastItem == null || lastItem.equals("") || lastItem.equals("null")) { + nextPageKey = null; } else { - onPostFetchedCallback.hasPost(); + nextPageKey = lastItem; } - if(lastItem == null || lastItem.equals("") || lastItem.equals("null")) { - callback.onResult(newPosts, null, null); + if(newPosts.size() != 0) { + onPostFetchedCallback.hasPost(); + } else if(nextPageKey != null) { + loadUserPostsInitial(callback, nextPageKey); + return; } else { - callback.onResult(newPosts, null, lastItem); + onPostFetchedCallback.noPost(); } + + callback.onResult(newPosts, null, nextPageKey); initialLoadStateLiveData.postValue(NetworkState.LOADED); } @@ -420,15 +447,15 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { String after = lastItem == null ? params.key : lastItem; RedditAPI api = retrofit.create(RedditAPI.class); - Call<String> getPost = api.getUserBestPosts(subredditName, after, RedditUtils.getOAuthHeader(accessToken)); + Call<String> getPost = api.getUserBestPosts(subredditOrUserName, after, RedditUtils.getOAuthHeader(accessToken)); getPost.enqueue(new Callback<String>() { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if(response.isSuccessful()) { - ParsePost.parsePosts(response.body(), locale, -1, new ParsePost.ParsePostsListingListener() { + ParsePost.parsePosts(response.body(), locale, -1, filter, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { - if(newPosts.size() == 0 && !lastItem.equals("null")) { + if(newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { loadUserPostsAfter(params, callback, lastItem); } else { callback.onResult(newPosts, lastItem); @@ -456,31 +483,41 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { }); } - private void loadSearchPostsInitial(@NonNull final LoadInitialCallback<String, Post> callback) { + private void loadSearchPostsInitial(@NonNull final LoadInitialCallback<String, Post> callback, String lastItem) { RedditAPI api = retrofit.create(RedditAPI.class); Call<String> getPost; - if(subredditName == null) { + if(subredditOrUserName == null) { getPost = api.searchPosts(query, null, sortType, RedditUtils.getOAuthHeader(accessToken)); } else { - getPost = api.searchPostsInSpecificSubreddit(subredditName, query, null, RedditUtils.getOAuthHeader(accessToken)); + getPost = api.searchPostsInSpecificSubreddit(subredditOrUserName, query, null, RedditUtils.getOAuthHeader(accessToken)); } getPost.enqueue(new Callback<String>() { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if(response.isSuccessful()) { - ParsePost.parsePosts(response.body(), locale, -1, + ParsePost.parsePosts(response.body(), locale, -1, filter, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { - if(newPosts.size() == 0) { - onPostFetchedCallback.noPost(); + String nextPageKey; + if(lastItem == null || lastItem.equals("") || lastItem.equals("null")) { + nextPageKey = null; } else { + nextPageKey = lastItem; + } + + if(newPosts.size() != 0) { onPostFetchedCallback.hasPost(); + } else if(nextPageKey != null) { + loadSearchPostsInitial(callback, nextPageKey); + return; + } else { + onPostFetchedCallback.noPost(); } - callback.onResult(newPosts, null, lastItem); + callback.onResult(newPosts, null, nextPageKey); initialLoadStateLiveData.postValue(NetworkState.LOADED); } @@ -504,29 +541,31 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { }); } - private void loadSearchPostsAfter(@NonNull LoadParams<String> params, @NonNull final LoadCallback<String, Post> callback) { + private void loadSearchPostsAfter(@NonNull LoadParams<String> params, @NonNull final LoadCallback<String, Post> callback, String lastItem) { + String after = lastItem == null ? params.key : lastItem; + RedditAPI api = retrofit.create(RedditAPI.class); Call<String> getPost; - if(subredditName == null) { - getPost = api.searchPosts(query, params.key, sortType, RedditUtils.getOAuthHeader(accessToken)); + if(subredditOrUserName == null) { + getPost = api.searchPosts(query, after, sortType, RedditUtils.getOAuthHeader(accessToken)); } else { - getPost = api.searchPostsInSpecificSubreddit(subredditName, query, params.key, RedditUtils.getOAuthHeader(accessToken)); + getPost = api.searchPostsInSpecificSubreddit(subredditOrUserName, query, after, RedditUtils.getOAuthHeader(accessToken)); } getPost.enqueue(new Callback<String>() { @Override public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if(response.isSuccessful()) { - ParsePost.parsePosts(response.body(), locale, -1, new ParsePost.ParsePostsListingListener() { + ParsePost.parsePosts(response.body(), locale, -1, filter, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(ArrayList<Post> newPosts, String lastItem) { - if(lastItem == null || lastItem.equals("") || lastItem.equals("null")) { - callback.onResult(newPosts, null); + if(newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { + loadSearchPostsAfter(params, callback, lastItem); } else { callback.onResult(newPosts, lastItem); + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSourceFactory.java index 79a533e0..67350b7b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSourceFactory.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSourceFactory.java @@ -15,24 +15,27 @@ class PostDataSourceFactory extends DataSource.Factory { private String query; private int postType; private String sortType; + private int filter; private PostDataSource.OnPostFetchedCallback onPostFetchedCallback; private PostDataSource postDataSource; private MutableLiveData<PostDataSource> postDataSourceLiveData; PostDataSourceFactory(Retrofit retrofit, String accessToken, Locale locale, int postType, String sortType, - PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { + int filter, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { this.retrofit = retrofit; this.accessToken = accessToken; this.locale = locale; postDataSourceLiveData = new MutableLiveData<>(); this.postType = postType; this.sortType = sortType; + this.filter = filter; this.onPostFetchedCallback = onPostFetchedCallback; } PostDataSourceFactory(Retrofit retrofit, String accessToken, Locale locale, String subredditName, - int postType, String sortType, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { + int postType, String sortType, int filter, + PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { this.retrofit = retrofit; this.accessToken = accessToken; this.locale = locale; @@ -40,22 +43,26 @@ class PostDataSourceFactory extends DataSource.Factory { postDataSourceLiveData = new MutableLiveData<>(); this.postType = postType; this.sortType = sortType; + this.filter = filter; this.onPostFetchedCallback = onPostFetchedCallback; } PostDataSourceFactory(Retrofit retrofit, String accessToken, Locale locale, String subredditName, - int postType, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { + int postType, int filter, + PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { this.retrofit = retrofit; this.accessToken = accessToken; this.locale = locale; this.subredditName = subredditName; postDataSourceLiveData = new MutableLiveData<>(); this.postType = postType; + this.filter = filter; this.onPostFetchedCallback = onPostFetchedCallback; } PostDataSourceFactory(Retrofit retrofit, String accessToken, Locale locale, String subredditName, - String query, int postType, String sortType, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { + String query, int postType, String sortType, int filter, + PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { this.retrofit = retrofit; this.accessToken = accessToken; this.locale = locale; @@ -64,19 +71,24 @@ class PostDataSourceFactory extends DataSource.Factory { postDataSourceLiveData = new MutableLiveData<>(); this.postType = postType; this.sortType = sortType; + this.filter = filter; this.onPostFetchedCallback = onPostFetchedCallback; } @Override public DataSource create() { if(postType == PostDataSource.TYPE_FRONT_PAGE) { - postDataSource = new PostDataSource(retrofit, accessToken, locale, postType, sortType, onPostFetchedCallback); + postDataSource = new PostDataSource(retrofit, accessToken, locale, postType, sortType, + filter, onPostFetchedCallback); } else if(postType == PostDataSource.TYPE_SEARCH) { - postDataSource = new PostDataSource(retrofit, accessToken, locale, subredditName, query, postType, sortType, onPostFetchedCallback); + postDataSource = new PostDataSource(retrofit, accessToken, locale, subredditName, query, + postType, sortType, filter, onPostFetchedCallback); } else if(postType == PostDataSource.TYPE_SUBREDDIT) { - postDataSource = new PostDataSource(retrofit, accessToken, locale, subredditName, postType, sortType, onPostFetchedCallback); + postDataSource = new PostDataSource(retrofit, accessToken, locale, subredditName, postType, + sortType, filter, onPostFetchedCallback); } else { - postDataSource = new PostDataSource(retrofit, accessToken, locale, subredditName, postType, onPostFetchedCallback); + postDataSource = new PostDataSource(retrofit, accessToken, locale, subredditName, postType, + filter, onPostFetchedCallback); } postDataSourceLiveData.postValue(postDataSource); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java index a5cd86ff..dce8680f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java @@ -3,6 +3,7 @@ package ml.docilealligator.infinityforreddit; import android.app.Activity; import android.content.Context; +import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.os.CountDownTimer; @@ -45,10 +46,13 @@ import retrofit2.Retrofit; */ public class PostFragment extends Fragment implements FragmentCommunicator { - static final String EXTRA_SUBREDDIT_NAME = "EN"; + static final String EXTRA_NAME = "EN"; + static final String EXTRA_USER_NAME = "EN"; static final String EXTRA_QUERY = "EQ"; static final String EXTRA_POST_TYPE = "EPT"; static final String EXTRA_SORT_TYPE = "EST"; + static final String EXTRA_FILTER = "EF"; + static final int EXTRA_NO_FILTER = -1; private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; @@ -168,6 +172,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { int postType = getArguments().getInt(EXTRA_POST_TYPE); String sortType = getArguments().getString(EXTRA_SORT_TYPE); + int filter = getArguments().getInt(EXTRA_FILTER); String accessToken = activity.getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE) .getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, ""); @@ -175,13 +180,30 @@ public class PostFragment extends Fragment implements FragmentCommunicator { PostViewModel.Factory factory; if(postType == PostDataSource.TYPE_SEARCH) { - String subredditName = getArguments().getString(EXTRA_SUBREDDIT_NAME); + String subredditName = getArguments().getString(EXTRA_NAME); String query = getArguments().getString(EXTRA_QUERY); mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, - mSharedPreferences, postType, true, () -> mPostViewModel.retryLoadingMore()); + mSharedPreferences, postType, true, new PostRecyclerViewAdapter.Callback() { + @Override + public void retryLoadingMore() { + mPostViewModel.retryLoadingMore(); + } + + @Override + public void typeChipClicked(int filter) { + Intent intent = new Intent(activity, FilteredPostsActivity.class); + intent.putExtra(FilteredPostsActivity.EXTRA_NAME, subredditName); + intent.putExtra(FilteredPostsActivity.EXTRA_QUERY, query); + intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, postType); + intent.putExtra(FilteredPostsActivity.EXTRA_SORT_TYPE, sortType); + intent.putExtra(FilteredPostsActivity.EXTRA_FILTER, filter); + startActivity(intent); + } + }); + factory = new PostViewModel.Factory(mOauthRetrofit, accessToken, - getResources().getConfiguration().locale, subredditName, query, postType, sortType, new PostDataSource.OnPostFetchedCallback() { + getResources().getConfiguration().locale, subredditName, query, postType, sortType, filter, new PostDataSource.OnPostFetchedCallback() { @Override public void hasPost() { mFetchPostInfoLinearLayout.setVisibility(View.GONE); @@ -196,14 +218,29 @@ public class PostFragment extends Fragment implements FragmentCommunicator { } }); } else if(postType == PostDataSource.TYPE_SUBREDDIT) { - String subredditName = getArguments().getString(EXTRA_SUBREDDIT_NAME); + String subredditName = getArguments().getString(EXTRA_NAME); boolean displaySubredditName = subredditName.equals("popular") || subredditName.equals("all"); mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, - mSharedPreferences, postType, displaySubredditName, () -> mPostViewModel.retryLoadingMore()); + mSharedPreferences, postType, displaySubredditName, new PostRecyclerViewAdapter.Callback() { + @Override + public void retryLoadingMore() { + mPostViewModel.retryLoadingMore(); + } + + @Override + public void typeChipClicked(int filter) { + Intent intent = new Intent(activity, FilteredPostsActivity.class); + intent.putExtra(FilteredPostsActivity.EXTRA_NAME, subredditName); + intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, postType); + intent.putExtra(FilteredPostsActivity.EXTRA_SORT_TYPE, sortType); + intent.putExtra(FilteredPostsActivity.EXTRA_FILTER, filter); + startActivity(intent); + } + }); factory = new PostViewModel.Factory(mOauthRetrofit, accessToken, - getResources().getConfiguration().locale, subredditName, postType, sortType, new PostDataSource.OnPostFetchedCallback() { + getResources().getConfiguration().locale, subredditName, postType, sortType, filter, new PostDataSource.OnPostFetchedCallback() { @Override public void hasPost() { mFetchPostInfoLinearLayout.setVisibility(View.GONE); @@ -222,13 +259,28 @@ public class PostFragment extends Fragment implements FragmentCommunicator { params.height = ViewGroup.LayoutParams.WRAP_CONTENT; mFetchPostInfoLinearLayout.setLayoutParams(params); - String subredditName = getArguments().getString(EXTRA_SUBREDDIT_NAME); + String username = getArguments().getString(EXTRA_USER_NAME); mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, - mSharedPreferences, postType, true, () -> mPostViewModel.retryLoadingMore()); + mSharedPreferences, postType, true, new PostRecyclerViewAdapter.Callback() { + @Override + public void retryLoadingMore() { + mPostViewModel.retryLoadingMore(); + } + + @Override + public void typeChipClicked(int filter) { + Intent intent = new Intent(activity, FilteredPostsActivity.class); + intent.putExtra(FilteredPostsActivity.EXTRA_NAME, username); + intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, postType); + intent.putExtra(FilteredPostsActivity.EXTRA_SORT_TYPE, sortType); + intent.putExtra(FilteredPostsActivity.EXTRA_FILTER, filter); + startActivity(intent); + } + }); factory = new PostViewModel.Factory(mOauthRetrofit, accessToken, - getResources().getConfiguration().locale, subredditName, postType, sortType, + getResources().getConfiguration().locale, username, postType, sortType, filter, new PostDataSource.OnPostFetchedCallback() { @Override public void hasPost() { @@ -245,10 +297,25 @@ public class PostFragment extends Fragment implements FragmentCommunicator { }); } else { mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, - mSharedPreferences, postType, true, () -> mPostViewModel.retryLoadingMore()); + mSharedPreferences, postType, true, new PostRecyclerViewAdapter.Callback() { + @Override + public void retryLoadingMore() { + mPostViewModel.retryLoadingMore(); + } + + @Override + public void typeChipClicked(int filter) { + Intent intent = new Intent(activity, FilteredPostsActivity.class); + intent.putExtra(FilteredPostsActivity.EXTRA_NAME, activity.getString(R.string.best)); + intent.putExtra(FilteredPostsActivity.EXTRA_POST_TYPE, postType); + intent.putExtra(FilteredPostsActivity.EXTRA_SORT_TYPE, sortType); + intent.putExtra(FilteredPostsActivity.EXTRA_FILTER, filter); + startActivity(intent); + } + }); factory = new PostViewModel.Factory(mOauthRetrofit, accessToken, - getResources().getConfiguration().locale, postType, sortType, new PostDataSource.OnPostFetchedCallback() { + getResources().getConfiguration().locale, postType, sortType, filter, new PostDataSource.OnPostFetchedCallback() { @Override public void hasPost() { mFetchPostInfoLinearLayout.setVisibility(View.GONE); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java index e5c8a896..43db7760 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java @@ -73,15 +73,16 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo private static final int VIEW_TYPE_LOADING = 2; private NetworkState networkState; - private RetryLoadingMoreCallback retryLoadingMoreCallback; + private Callback callback; - interface RetryLoadingMoreCallback { + interface Callback { void retryLoadingMore(); + void typeChipClicked(int filter); } PostRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, Retrofit retrofit, - SharedPreferences sharedPreferences, int postType, boolean displaySubredditName, - RetryLoadingMoreCallback retryLoadingMoreCallback) { + SharedPreferences sharedPreferences, int postType, + boolean displaySubredditName, Callback callback) { super(DIFF_CALLBACK); if(context != null) { mContext = context; @@ -93,7 +94,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo glide = Glide.with(mContext.getApplicationContext()); subredditDao = SubredditRoomDatabase.getDatabase(mContext.getApplicationContext()).subredditDao(); userDao = UserRoomDatabase.getDatabase(mContext.getApplicationContext()).userDao(); - this.retryLoadingMoreCallback = retryLoadingMoreCallback; + this.callback = callback; } } @@ -360,9 +361,11 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo ((DataViewHolder) holder).crosspostImageView.setVisibility(View.VISIBLE); } + ((DataViewHolder) holder).typeChip.setOnClickListener(view -> callback.typeChipClicked(post.getPostType())); + switch (post.getPostType()) { case Post.IMAGE_TYPE: - ((DataViewHolder) holder).typeChip.setText("IMAGE"); + ((DataViewHolder) holder).typeChip.setText(R.string.image); final String imageUrl = post.getUrl(); ((DataViewHolder) holder).imageView.setOnClickListener(view -> { @@ -375,7 +378,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo }); break; case Post.LINK_TYPE: - ((DataViewHolder) holder).typeChip.setText("LINK"); + ((DataViewHolder) holder).typeChip.setText(R.string.link); ((DataViewHolder) holder).linkTextView.setVisibility(View.VISIBLE); String domain = Uri.parse(post.getUrl()).getHost(); ((DataViewHolder) holder).linkTextView.setText(domain); @@ -390,7 +393,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo }); break; case Post.GIF_VIDEO_TYPE: - ((DataViewHolder) holder).typeChip.setText("GIF"); + ((DataViewHolder) holder).typeChip.setText(R.string.gif); final Uri gifVideoUri = Uri.parse(post.getVideoUrl()); ((DataViewHolder) holder).imageView.setOnClickListener(view -> { @@ -408,7 +411,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo }); break; case Post.VIDEO_TYPE: - ((DataViewHolder) holder).typeChip.setText("VIDEO"); + ((DataViewHolder) holder).typeChip.setText(R.string.video); final Uri videoUri = Uri.parse(post.getVideoUrl()); ((DataViewHolder) holder).imageView.setOnClickListener(view -> { @@ -426,7 +429,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo }); break; case Post.NO_PREVIEW_LINK_TYPE: - ((DataViewHolder) holder).typeChip.setText("LINK"); + ((DataViewHolder) holder).typeChip.setText(R.string.link); String noPreviewLinkUrl = post.getUrl(); ((DataViewHolder) holder).linkTextView.setVisibility(View.VISIBLE); String noPreviewLinkDomain = Uri.parse(noPreviewLinkUrl).getHost(); @@ -442,7 +445,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo }); break; case Post.TEXT_TYPE: - ((DataViewHolder) holder).typeChip.setText("TEXT"); + ((DataViewHolder) holder).typeChip.setText(R.string.text); break; } @@ -692,7 +695,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo super(itemView); ButterKnife.bind(this, itemView); errorTextView.setText(R.string.load_posts_error); - retryButton.setOnClickListener(view -> retryLoadingMoreCallback.retryLoadingMore()); + retryButton.setOnClickListener(view -> callback.retryLoadingMore()); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostViewModel.java index c824567f..7986d459 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostViewModel.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostViewModel.java @@ -22,8 +22,8 @@ public class PostViewModel extends ViewModel { private MutableLiveData<String> sortTypeLiveData; public PostViewModel(Retrofit retrofit, String accessToken, Locale locale, int postType, String sortType, - PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { - postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, locale, postType, sortType, onPostFetchedCallback); + int filter, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { + postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, locale, postType, sortType, filter, onPostFetchedCallback); initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), (Function<PostDataSource, LiveData<NetworkState>>) PostDataSource::getInitialLoadStateLiveData); @@ -46,8 +46,9 @@ public class PostViewModel extends ViewModel { } public PostViewModel(Retrofit retrofit, String accessToken, Locale locale, String subredditName, int postType, - String sortType, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { - postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, locale, subredditName, postType, sortType, onPostFetchedCallback); + String sortType, int filter, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { + postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, locale, subredditName, + postType, sortType, filter, onPostFetchedCallback); initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), (Function<PostDataSource, LiveData<NetworkState>>) PostDataSource::getInitialLoadStateLiveData); @@ -70,8 +71,9 @@ public class PostViewModel extends ViewModel { } public PostViewModel(Retrofit retrofit, String accessToken, Locale locale, String subredditName, int postType, - PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { - postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, locale, subredditName, postType, onPostFetchedCallback); + int filter, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { + postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, locale, subredditName, + postType, filter, onPostFetchedCallback); initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), dataSource -> dataSource.getInitialLoadStateLiveData()); @@ -88,9 +90,9 @@ public class PostViewModel extends ViewModel { } public PostViewModel(Retrofit retrofit, String accessToken, Locale locale, String subredditName, String query, - int postType, String sortType, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { + int postType, String sortType, int filter, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, locale, subredditName, - query, postType, sortType, onPostFetchedCallback); + query, postType, sortType, filter, onPostFetchedCallback); initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), dataSource -> dataSource.getInitialLoadStateLiveData()); @@ -148,41 +150,45 @@ public class PostViewModel extends ViewModel { private String query; private int postType; private String sortType; + private int filter; private PostDataSource.OnPostFetchedCallback onPostFetchedCallback; public Factory(Retrofit retrofit, String accessToken, Locale locale, int postType, String sortType, - PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { + int filter, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { this.retrofit = retrofit; this.accessToken = accessToken; this.locale = locale; this.postType = postType; this.sortType = sortType; + this.filter = filter; this.onPostFetchedCallback = onPostFetchedCallback; } public Factory(Retrofit retrofit, String accessToken, Locale locale, String subredditName, int postType, - String sortType, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { + String sortType, int filter, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { this.retrofit = retrofit; this.accessToken = accessToken; this.locale = locale; this.subredditName = subredditName; this.postType = postType; this.sortType = sortType; + this.filter = filter; this.onPostFetchedCallback = onPostFetchedCallback; } public Factory(Retrofit retrofit, String accessToken, Locale locale, String subredditName, int postType, - PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { + int filter, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { this.retrofit = retrofit; this.accessToken = accessToken; this.locale = locale; this.subredditName = subredditName; this.postType = postType; + this.filter = filter; this.onPostFetchedCallback = onPostFetchedCallback; } public Factory(Retrofit retrofit, String accessToken, Locale locale, String subredditName, String query, - int postType, String sortType, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { + int postType, String sortType, int filter, PostDataSource.OnPostFetchedCallback onPostFetchedCallback) { this.retrofit = retrofit; this.accessToken = accessToken; this.locale = locale; @@ -190,6 +196,7 @@ public class PostViewModel extends ViewModel { this.query = query; this.postType = postType; this.sortType = sortType; + this.filter = filter; this.onPostFetchedCallback = onPostFetchedCallback; } @@ -197,13 +204,13 @@ public class PostViewModel extends ViewModel { @Override public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { if(postType == PostDataSource.TYPE_FRONT_PAGE) { - return (T) new PostViewModel(retrofit, accessToken, locale, postType, sortType, onPostFetchedCallback); + return (T) new PostViewModel(retrofit, accessToken, locale, postType, sortType, filter, onPostFetchedCallback); } else if(postType == PostDataSource.TYPE_SEARCH){ - return (T) new PostViewModel(retrofit, accessToken, locale, subredditName, query, postType, sortType, onPostFetchedCallback); + return (T) new PostViewModel(retrofit, accessToken, locale, subredditName, query, postType, sortType, filter, onPostFetchedCallback); } else if(postType == PostDataSource.TYPE_SUBREDDIT) { - return (T) new PostViewModel(retrofit, accessToken, locale, subredditName, postType, sortType, onPostFetchedCallback); + return (T) new PostViewModel(retrofit, accessToken, locale, subredditName, postType, sortType, filter, onPostFetchedCallback); } else { - return (T) new PostViewModel(retrofit, accessToken, locale, subredditName, postType, onPostFetchedCallback); + return (T) new PostViewModel(retrofit, accessToken, locale, subredditName, postType, filter, onPostFetchedCallback); } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SearchResultActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SearchResultActivity.java index c8010021..27ee7708 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SearchResultActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SearchResultActivity.java @@ -102,6 +102,7 @@ public class SearchResultActivity extends AppCompatActivity implements SearchPos return true; case R.id.action_search_search_result_activity: Intent intent = new Intent(this, SearchActivity.class); + intent.putExtra(SearchActivity.EXTRA_SEARCH_ONLY_SUBREDDITS, false); finish(); startActivity(intent); return true; @@ -141,8 +142,9 @@ public class SearchResultActivity extends AppCompatActivity implements SearchPos Bundle bundle = new Bundle(); bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SEARCH); bundle.putString(PostFragment.EXTRA_SORT_TYPE, PostDataSource.SORT_TYPE_RELEVANCE); - bundle.putString(PostFragment.EXTRA_SUBREDDIT_NAME, mSubredditName); + bundle.putString(PostFragment.EXTRA_NAME, mSubredditName); bundle.putString(PostFragment.EXTRA_QUERY, mQuery); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); mFragment.setArguments(bundle); return mFragment; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SearchSubredditsResultActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SearchSubredditsResultActivity.java index e8029bf9..51003eae 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SearchSubredditsResultActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SearchSubredditsResultActivity.java @@ -3,6 +3,7 @@ package ml.docilealligator.infinityforreddit; import android.app.Activity; import android.content.Intent; import android.os.Bundle; +import android.view.MenuItem; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; @@ -59,6 +60,15 @@ public class SearchSubredditsResultActivity extends AppCompatActivity { } @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if(item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return false; + } + + @Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); if (mFragment != null) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java index 4b9a0984..6b7c67e9 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java @@ -259,9 +259,10 @@ public class ViewSubredditDetailActivity extends AppCompatActivity implements So if(savedInstanceState == null) { mFragment = new PostFragment(); Bundle bundle = new Bundle(); - bundle.putString(PostFragment.EXTRA_SUBREDDIT_NAME, subredditName); + bundle.putString(PostFragment.EXTRA_NAME, subredditName); bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); bundle.putString(PostFragment.EXTRA_SORT_TYPE, PostDataSource.SORT_TYPE_BEST); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); mFragment.setArguments(bundle); getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_view_subreddit_detail_activity, mFragment).commit(); } else { @@ -269,9 +270,10 @@ public class ViewSubredditDetailActivity extends AppCompatActivity implements So if(mFragment == null) { mFragment = new PostFragment(); Bundle bundle = new Bundle(); - bundle.putString(PostFragment.EXTRA_SUBREDDIT_NAME, subredditName); + bundle.putString(PostFragment.EXTRA_NAME, subredditName); bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); bundle.putString(PostFragment.EXTRA_SORT_TYPE, PostDataSource.SORT_TYPE_BEST); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); mFragment.setArguments(bundle); } isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java index 47c4faee..d7799bfa 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java @@ -70,7 +70,7 @@ public class ViewUserDetailActivity extends AppCompatActivity { private Menu mMenu; private AppBarLayout.LayoutParams params; - private String userName; + private String username; private boolean subscriptionReady = false; private boolean isInLazyMode = false; private int expandedTabTextColor; @@ -110,8 +110,8 @@ public class ViewUserDetailActivity extends AppCompatActivity { statusBarHeight = getResources().getDimensionPixelSize(resourceId); } - userName = getIntent().getExtras().getString(EXTRA_USER_NAME_KEY); - String title = "u/" + userName; + username = getIntent().getExtras().getString(EXTRA_USER_NAME_KEY); + String title = "u/" + username; userNameTextView.setText(title); Toolbar toolbar = findViewById(R.id.toolbar); @@ -152,7 +152,7 @@ public class ViewUserDetailActivity extends AppCompatActivity { subscribedUserDao = SubscribedUserRoomDatabase.getDatabase(this).subscribedUserDao(); glide = Glide.with(this); - userViewModel = ViewModelProviders.of(this, new UserViewModel.Factory(getApplication(), userName)) + userViewModel = ViewModelProviders.of(this, new UserViewModel.Factory(getApplication(), username)) .get(UserViewModel.class); userViewModel.getUserLiveData().observe(this, userData -> { if(userData != null) { @@ -166,7 +166,7 @@ public class ViewUserDetailActivity extends AppCompatActivity { Intent intent = new Intent(this, ViewImageActivity.class); intent.putExtra(ViewImageActivity.TITLE_KEY, title); intent.putExtra(ViewImageActivity.IMAGE_URL_KEY, userData.getBanner()); - intent.putExtra(ViewImageActivity.FILE_NAME_KEY, userName + "-banner"); + intent.putExtra(ViewImageActivity.FILE_NAME_KEY, username + "-banner"); startActivity(intent); }); } @@ -189,7 +189,7 @@ public class ViewUserDetailActivity extends AppCompatActivity { Intent intent = new Intent(this, ViewImageActivity.class); intent.putExtra(ViewImageActivity.TITLE_KEY, title); intent.putExtra(ViewImageActivity.IMAGE_URL_KEY, userData.getIconUrl()); - intent.putExtra(ViewImageActivity.FILE_NAME_KEY, userName + "-icon"); + intent.putExtra(ViewImageActivity.FILE_NAME_KEY, username + "-icon"); startActivity(intent); }); } @@ -201,7 +201,7 @@ public class ViewUserDetailActivity extends AppCompatActivity { subscriptionReady = false; if(subscribeUserChip.getText().equals(getResources().getString(R.string.follow))) { UserFollowing.followUser(mOauthRetrofit, mRetrofit, sharedPreferences, - userName, subscribedUserDao, new UserFollowing.UserFollowingListener() { + username, subscribedUserDao, new UserFollowing.UserFollowingListener() { @Override public void onUserFollowingSuccess() { subscribeUserChip.setText(R.string.unfollow); @@ -218,7 +218,7 @@ public class ViewUserDetailActivity extends AppCompatActivity { }); } else { UserFollowing.unfollowUser(mOauthRetrofit, mRetrofit, sharedPreferences, - userName, subscribedUserDao, new UserFollowing.UserFollowingListener() { + username, subscribedUserDao, new UserFollowing.UserFollowingListener() { @Override public void onUserFollowingSuccess() { subscribeUserChip.setText(R.string.follow); @@ -237,7 +237,7 @@ public class ViewUserDetailActivity extends AppCompatActivity { } }); - new CheckIsFollowingUserAsyncTask(subscribedUserDao, userName, new CheckIsFollowingUserAsyncTask.CheckIsFollowingUserListener() { + new CheckIsFollowingUserAsyncTask(subscribedUserDao, username, new CheckIsFollowingUserAsyncTask.CheckIsFollowingUserListener() { @Override public void isSubscribed() { subscribeUserChip.setText(R.string.unfollow); @@ -266,7 +266,7 @@ public class ViewUserDetailActivity extends AppCompatActivity { } }); - FetchUserData.fetchUserData(mRetrofit, userName, new FetchUserData.FetchUserDataListener() { + FetchUserData.fetchUserData(mRetrofit, username, new FetchUserData.FetchUserDataListener() { @Override public void onFetchUserDataSuccess(UserData userData) { new InsertUserDataAsyncTask(UserRoomDatabase.getDatabase(ViewUserDetailActivity.this).userDao(), userData).execute(); @@ -281,7 +281,7 @@ public class ViewUserDetailActivity extends AppCompatActivity { if(savedInstanceState == null) { /*mFragment = new PostFragment(); Bundle bundle = new Bundle(); - bundle.putString(PostFragment.EXTRA_SUBREDDIT_NAME, userName); + bundle.putString(PostFragment.EXTRA_NAME, username); bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_USER); mFragment.setArguments(bundle); getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_view_user_detail_activity, mFragment).commit();*/ @@ -290,7 +290,7 @@ public class ViewUserDetailActivity extends AppCompatActivity { if(mFragment == null) { mFragment = new PostFragment(); Bundle bundle = new Bundle(); - bundle.putString(PostFragment.EXTRA_SUBREDDIT_NAME, userName); + bundle.putString(PostFragment.EXTRA_NAME, username); bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_USER); mFragment.setArguments(bundle); }*/ @@ -326,7 +326,7 @@ public class ViewUserDetailActivity extends AppCompatActivity { return true; case R.id.action_search_view_user_detail_activity: Intent intent = new Intent(this, SearchActivity.class); - intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_NAME, userName); + intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_NAME, username); intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_IS_USER, true); intent.putExtra(SearchActivity.EXTRA_SEARCH_ONLY_SUBREDDITS, false); startActivity(intent); @@ -440,13 +440,14 @@ public class ViewUserDetailActivity extends AppCompatActivity { PostFragment fragment = new PostFragment(); Bundle bundle = new Bundle(); bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_USER); - bundle.putString(PostFragment.EXTRA_SUBREDDIT_NAME, userName); + bundle.putString(PostFragment.EXTRA_USER_NAME, username); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); fragment.setArguments(bundle); return fragment; } CommentsListingFragment fragment = new CommentsListingFragment(); Bundle bundle = new Bundle(); - bundle.putString(CommentsListingFragment.EXTRA_USERNAME_KEY, userName); + bundle.putString(CommentsListingFragment.EXTRA_USERNAME_KEY, username); fragment.setArguments(bundle); return fragment; } diff --git a/app/src/main/res/layout/activity_filtered_posts.xml b/app/src/main/res/layout/activity_filtered_posts.xml new file mode 100644 index 00000000..48c06348 --- /dev/null +++ b/app/src/main/res/layout/activity_filtered_posts.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".FilteredPostsActivity"> + + <com.google.android.material.appbar.AppBarLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:theme="@style/AppTheme.AppBarOverlay"> + + <androidx.appcompat.widget.Toolbar + android:id="@+id/toolbar_filtered_posts_activity" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + app:popupTheme="@style/AppTheme.PopupOverlay" + app:navigationIcon="?attr/homeAsUpIndicator" /> + + </com.google.android.material.appbar.AppBarLayout> + + <FrameLayout + android:id="@+id/frame_layout_filtered_posts_activity" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + +</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_subreddit_listing.xml b/app/src/main/res/layout/fragment_subreddit_listing.xml index d6fba93a..77f08627 100644 --- a/app/src/main/res/layout/fragment_subreddit_listing.xml +++ b/app/src/main/res/layout/fragment_subreddit_listing.xml @@ -13,6 +13,7 @@ android:layout_height="wrap_content" android:layout_marginTop="16dp" android:layout_marginBottom="16dp" + android:background="@color/backgroundColor" app:mlpb_progress_stoke_width="3dp" app:mlpb_progress_color="@color/colorAccent" android:layout_gravity="center_horizontal"/> diff --git a/app/src/main/res/layout/fragment_user_listing.xml b/app/src/main/res/layout/fragment_user_listing.xml index b69ed7ae..a877cac4 100644 --- a/app/src/main/res/layout/fragment_user_listing.xml +++ b/app/src/main/res/layout/fragment_user_listing.xml @@ -13,6 +13,7 @@ android:layout_height="wrap_content" android:layout_marginTop="16dp" android:layout_marginBottom="16dp" + android:background="@color/backgroundColor" app:mlpb_progress_stoke_width="3dp" app:mlpb_progress_color="@color/colorAccent" android:layout_gravity="center_horizontal"/> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 74646a29..dbe1d6c2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -152,4 +152,12 @@ <string name="no_browser_found">No browser found</string> <string name="archived_post_vote_unavailable">Archived post. Vote unavailable.</string> + + <string name="text">TEXT</string> + <string name="link">LINK</string> + <string name="image">IMAGE</string> + <string name="video">VIDEO</string> + <string name="gif">GIF</string> + <string name="best">Best</string> + <string name="search">Search</string> </resources> |