diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostFragment.java index 4e5bfa9b..e4f6dd94 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostFragment.java @@ -51,6 +51,7 @@ import com.bumptech.glide.RequestManager; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; +import java.util.ArrayList; import java.util.Locale; import javax.inject.Inject; @@ -102,6 +103,8 @@ import ml.docilealligator.infinityforreddit.Post.PostViewModel; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SubredditFilter.FetchSubredditFilters; +import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilter; import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.Utils.Utils; import retrofit2.Retrofit; @@ -127,6 +130,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; private static final String RECYCLER_VIEW_POSITION_STATE = "RVPS"; + private static final String SUBREDDIT_FILTER_LIST_STATE = "SFLS"; @BindView(R.id.swipe_refresh_layout_post_fragment) SwipeRefreshLayout mSwipeRefreshLayout; @@ -203,6 +207,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { private Drawable drawableRight; private float swipeActionThreshold = 0.3f; private ItemTouchHelper touchHelper; + private ArrayList subredditFilterList; public PostFragment() { // Required empty public constructor @@ -363,6 +368,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { } isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); + subredditFilterList = savedInstanceState.getParcelableArrayList(SUBREDDIT_FILTER_LIST_STATE); } mPostRecyclerView.setOnTouchListener((view, motionEvent) -> { @@ -503,9 +509,26 @@ public class PostFragment extends Fragment implements FragmentCommunicator { } }); - mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, - accountName, getResources().getConfiguration().locale, mSharedPreferences, - postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw)).get(PostViewModel.class); + if (subredditName.equals("all") || subredditName.equals("popular")) { + if (subredditFilterList != null) { + mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, + accountName, getResources().getConfiguration().locale, mSharedPreferences, + postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw, subredditFilterList)).get(PostViewModel.class); + } else { + FetchSubredditFilters.fetchSubredditFilters(mRedditDataRoomDatabase, subredditFilters -> { + subredditFilterList = subredditFilters; + mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, + accountName, getResources().getConfiguration().locale, mSharedPreferences, + postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw, subredditFilters)).get(PostViewModel.class); + + bindPostViewModel(); + }); + } + } else { + mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, + accountName, getResources().getConfiguration().locale, mSharedPreferences, + postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw)).get(PostViewModel.class); + } } else if(postType == PostDataSource.TYPE_MULTI_REDDIT) { multiRedditPath = getArguments().getString(EXTRA_NAME); String sort; @@ -776,6 +799,14 @@ public class PostFragment extends Fragment implements FragmentCommunicator { return new PlaybackInfo(INDEX_UNSET, TIME_UNSET, volumeInfo); }); + if (mPostViewModel != null) { + bindPostViewModel(); + } + + return rootView; + } + + private void bindPostViewModel() { mPostViewModel.getPosts().observe(getViewLifecycleOwner(), posts -> mAdapter.submitList(posts)); mPostViewModel.hasPost().observe(getViewLifecycleOwner(), hasPost -> { @@ -807,8 +838,6 @@ public class PostFragment extends Fragment implements FragmentCommunicator { }); mPostViewModel.getPaginationNetworkState().observe(getViewLifecycleOwner(), networkState -> mAdapter.setNetworkState(networkState)); - - return rootView; } public void changeSortType(SortType sortType) { @@ -869,6 +898,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); + outState.putParcelableArrayList(SUBREDDIT_FILTER_LIST_STATE, subredditFilterList); if (mLinearLayoutManager != null) { outState.putInt(RECYCLER_VIEW_POSITION_STATE, mLinearLayoutManager.findFirstVisibleItemPosition()); } else if (mStaggeredGridLayoutManager != null) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/ParsePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/ParsePost.java index 99bd969f..1a83fc16 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/ParsePost.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/ParsePost.java @@ -3,6 +3,7 @@ package ml.docilealligator.infinityforreddit.Post; import android.net.Uri; import android.os.AsyncTask; import android.text.Html; +import android.util.Log; import org.json.JSONArray; import org.json.JSONException; @@ -10,8 +11,10 @@ import org.json.JSONObject; import java.util.ArrayList; import java.util.LinkedHashSet; +import java.util.List; import ml.docilealligator.infinityforreddit.Fragment.PostFragment; +import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilter; import ml.docilealligator.infinityforreddit.Utils.JSONUtils; import ml.docilealligator.infinityforreddit.Utils.Utils; @@ -25,6 +28,11 @@ public class ParsePost { new ParsePostDataAsyncTask(response, nPosts, filter, nsfw, parsePostsListingListener).execute(); } + public static void parsePosts(String response, int nPosts, int filter, boolean nsfw, + List subredditFilterList, ParsePostsListingListener parsePostsListingListener) { + new ParsePostDataAsyncTask(response, nPosts, filter, nsfw, subredditFilterList, parsePostsListingListener).execute(); + } + public static void parsePost(String response, ParsePostListener parsePostListener) { new ParsePostDataAsyncTask(response, true, parsePostListener).execute(); } @@ -473,6 +481,7 @@ public class ParsePost { private int nPosts; private int filter; private boolean nsfw; + private List subredditFilterList; private ParsePostsListingListener parsePostsListingListener; private ParsePostListener parsePostListener; private LinkedHashSet newPosts; @@ -498,6 +507,12 @@ public class ParsePost { } } + ParsePostDataAsyncTask(String response, int nPosts, int filter, boolean nsfw, + List subredditFilterList, ParsePostsListingListener parsePostsListingListener) { + this(response, nPosts, filter, nsfw, parsePostsListingListener); + this.subredditFilterList = subredditFilterList; + } + ParsePostDataAsyncTask(String response, boolean nsfw, ParsePostListener parsePostListener) { this.parsePostListener = parsePostListener; @@ -545,7 +560,17 @@ public class ParsePost { if (allData.getJSONObject(i).getString(JSONUtils.KIND_KEY).equals("t3")) { JSONObject data = allData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); Post post = parseBasicData(data); - if (!(!nsfw && post.isNSFW())) { + boolean availablePost = true; + if (subredditFilterList != null) { + for (SubredditFilter subredditFilter : subredditFilterList) { + Log.i("sasdfasdf", subredditFilter.getSubredditName() + " " + post.getSubredditName()); + if (subredditFilter.getSubredditName().equals(post.getSubredditName())) { + availablePost = false; + break; + } + } + } + if (availablePost && !(!nsfw && post.isNSFW())) { if (filter == PostFragment.EXTRA_NO_FILTER) { newPosts.add(post); } else if (filter == post.getPostType()) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSource.java index b42d710e..480e96b1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSource.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSource.java @@ -14,6 +14,7 @@ import java.util.Locale; import ml.docilealligator.infinityforreddit.API.RedditAPI; import ml.docilealligator.infinityforreddit.NetworkState; import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilter; import ml.docilealligator.infinityforreddit.Utils.APIUtils; import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; import retrofit2.Call; @@ -47,6 +48,7 @@ public class PostDataSource extends PageKeyedDataSource { private SortType sortType; private boolean nsfw; private int filter; + private List subredditFilterList; private String userWhere; private String multiRedditPath; private LinkedHashSet postLinkedHashSet; @@ -78,8 +80,8 @@ public class PostDataSource extends PageKeyedDataSource { } PostDataSource(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String path, int postType, - SortType sortType, int filter, boolean nsfw) { + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, + String path, int postType, SortType sortType, int filter, boolean nsfw, List subredditFilterList) { this.retrofit = retrofit; this.accessToken = accessToken; this.accountName = accountName; @@ -114,6 +116,7 @@ public class PostDataSource extends PageKeyedDataSource { } this.filter = filter; this.nsfw = nsfw; + this.subredditFilterList = subredditFilterList; postLinkedHashSet = new LinkedHashSet<>(); } @@ -370,7 +373,7 @@ public class PostDataSource extends PageKeyedDataSource { @Override public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, filter, nsfw, + ParsePost.parsePosts(response.body(), -1, filter, nsfw, subredditFilterList, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { @@ -444,7 +447,7 @@ public class PostDataSource extends PageKeyedDataSource { @Override public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, filter, nsfw, + ParsePost.parsePosts(response.body(), -1, filter, nsfw, subredditFilterList, new ParsePost.ParsePostsListingListener() { @Override public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSourceFactory.java index 39c4d6b1..02bc58c3 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSourceFactory.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSourceFactory.java @@ -6,9 +6,11 @@ import androidx.annotation.NonNull; import androidx.lifecycle.MutableLiveData; import androidx.paging.DataSource; +import java.util.List; import java.util.Locale; import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilter; import retrofit2.Retrofit; class PostDataSourceFactory extends DataSource.Factory { @@ -25,6 +27,7 @@ class PostDataSourceFactory extends DataSource.Factory { private String userWhere; private int filter; private boolean nsfw; + private List subredditFilterList; private PostDataSource postDataSource; private MutableLiveData postDataSourceLiveData; @@ -47,7 +50,8 @@ class PostDataSourceFactory extends DataSource.Factory { PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, Locale locale, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, - String subredditName, int postType, SortType sortType, int filter, boolean nsfw) { + String subredditName, int postType, SortType sortType, int filter, boolean nsfw, + List subredditFilterList) { this.retrofit = retrofit; this.accessToken = accessToken; this.accountName = accountName; @@ -60,6 +64,7 @@ class PostDataSourceFactory extends DataSource.Factory { this.sortType = sortType; this.filter = filter; this.nsfw = nsfw; + this.subredditFilterList = subredditFilterList; } PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, Locale locale, @@ -111,7 +116,7 @@ class PostDataSourceFactory extends DataSource.Factory { sharedPreferences, postFeedScrolledPositionSharedPreferences, subredditName, query, postType, sortType, filter, nsfw); } else if (postType == PostDataSource.TYPE_SUBREDDIT || postType == PostDataSource.TYPE_MULTI_REDDIT) { postDataSource = new PostDataSource(retrofit, accessToken, accountName, locale, - sharedPreferences, postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw); + sharedPreferences, postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw, subredditFilterList); } else { postDataSource = new PostDataSource(retrofit, accessToken, accountName, locale, sharedPreferences, postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, userWhere, filter, nsfw); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostViewModel.java index c141aa8a..44496d04 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostViewModel.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostViewModel.java @@ -13,10 +13,12 @@ import androidx.lifecycle.ViewModelProvider; import androidx.paging.LivePagedListBuilder; import androidx.paging.PagedList; +import java.util.List; import java.util.Locale; import ml.docilealligator.infinityforreddit.NetworkState; import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilter; import retrofit2.Retrofit; public class PostViewModel extends ViewModel { @@ -63,9 +65,9 @@ public class PostViewModel extends ViewModel { public PostViewModel(Retrofit retrofit, String accessToken, String accountName, Locale locale, SharedPreferences sharedPreferences, SharedPreferences cache, String subredditName, - int postType, SortType sortType, int filter, boolean nsfw) { + int postType, SortType sortType, int filter, boolean nsfw, List subredditFilterList) { postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, locale, - sharedPreferences, cache, subredditName, postType, sortType, filter, nsfw); + sharedPreferences, cache, subredditName, postType, sortType, filter, nsfw, subredditFilterList); initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), PostDataSource::getInitialLoadStateLiveData); @@ -205,6 +207,7 @@ public class PostViewModel extends ViewModel { private String userWhere; private int filter; private boolean nsfw; + private List subredditFilterList; public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, @@ -237,6 +240,24 @@ public class PostViewModel extends ViewModel { this.nsfw = nsfw; } + //With subreddit filter + public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditName, + int postType, SortType sortType, int filter, boolean nsfw, List subredditFilterList) { + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.locale = locale; + this.sharedPreferences = sharedPreferences; + this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; + this.subredditName = subredditName; + this.postType = postType; + this.sortType = sortType; + this.filter = filter; + this.nsfw = nsfw; + this.subredditFilterList = subredditFilterList; + } + //User posts public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditName, @@ -284,7 +305,7 @@ public class PostViewModel extends ViewModel { postFeedScrolledPositionSharedPreferences, subredditName, query, postType, sortType, filter, nsfw); } else if (postType == PostDataSource.TYPE_SUBREDDIT || postType == PostDataSource.TYPE_MULTI_REDDIT) { return (T) new PostViewModel(retrofit, accessToken, accountName, locale, sharedPreferences, - postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw); + postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw, subredditFilterList); } else { return (T) new PostViewModel(retrofit, accessToken, accountName, locale, sharedPreferences, postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, userWhere, filter, nsfw); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/FetchSubredditFilters.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/FetchSubredditFilters.java new file mode 100644 index 00000000..74864fc7 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/FetchSubredditFilters.java @@ -0,0 +1,42 @@ +package ml.docilealligator.infinityforreddit.SubredditFilter; + +import android.os.AsyncTask; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class FetchSubredditFilters { + public interface FetchSubredditFiltersListener { + void success(ArrayListsubredditFilters); + } + + public static void fetchSubredditFilters(RedditDataRoomDatabase redditDataRoomDatabase, + FetchSubredditFiltersListener fetchSubredditFiltersListener) { + new FetchSubredditFiltersAsyncTask(redditDataRoomDatabase, fetchSubredditFiltersListener).execute(); + } + + private static class FetchSubredditFiltersAsyncTask extends AsyncTask { + private RedditDataRoomDatabase redditDataRoomDatabase; + private ArrayList subredditFilters; + private FetchSubredditFiltersListener fetchSubredditFiltersListener; + + FetchSubredditFiltersAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, + FetchSubredditFiltersListener fetchSubredditFiltersListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.fetchSubredditFiltersListener = fetchSubredditFiltersListener; + } + + @Override + protected Void doInBackground(Void... voids) { + subredditFilters = (ArrayList) redditDataRoomDatabase.subredditFilterDao().getAllSubredditFilters(); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + fetchSubredditFiltersListener.success(subredditFilters); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilter.java index 88ef79f7..ddfa01f0 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilter.java @@ -1,11 +1,14 @@ package ml.docilealligator.infinityforreddit.SubredditFilter; +import android.os.Parcel; +import android.os.Parcelable; + import androidx.annotation.NonNull; import androidx.room.ColumnInfo; import androidx.room.Entity; @Entity(tableName = "subreddit_filter", primaryKeys = {"subreddit_name", "type"}) -public class SubredditFilter { +public class SubredditFilter implements Parcelable { public static int TYPE_POPULAR_AND_ALL = 0; @NonNull @ColumnInfo(name = "subreddit_name") @@ -18,6 +21,23 @@ public class SubredditFilter { this.type = type; } + protected SubredditFilter(Parcel in) { + subredditName = in.readString(); + type = in.readInt(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public SubredditFilter createFromParcel(Parcel in) { + return new SubredditFilter(in); + } + + @Override + public SubredditFilter[] newArray(int size) { + return new SubredditFilter[size]; + } + }; + @NonNull public String getSubredditName() { return subredditName; @@ -34,4 +54,15 @@ public class SubredditFilter { public void setType(int type) { this.type = type; } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(subredditName); + parcel.writeInt(type); + } } diff --git a/app/src/main/res/xml/filter_preferences.xml b/app/src/main/res/xml/filter_preferences.xml index a0e2a991..f0e4fa62 100644 --- a/app/src/main/res/xml/filter_preferences.xml +++ b/app/src/main/res/xml/filter_preferences.xml @@ -1,6 +1,11 @@ + +