diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java index 7d287bde..0f3b02a9 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java @@ -45,8 +45,10 @@ import com.r0adkll.slidr.model.SlidrInterface; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.Map; import java.util.concurrent.Executor; @@ -62,6 +64,7 @@ import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.SaveThing; import ml.docilealligator.infinityforreddit.SortType; import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.asynctasks.SwitchAccount; import ml.docilealligator.infinityforreddit.comment.Comment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; @@ -69,8 +72,15 @@ import ml.docilealligator.infinityforreddit.events.NeedForPostListFromPostFragme import ml.docilealligator.infinityforreddit.events.ProvidePostListToViewPostDetailActivityEvent; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.fragments.ViewPostDetailFragment; +import ml.docilealligator.infinityforreddit.post.HistoryPostPagingSource; +import ml.docilealligator.infinityforreddit.post.ParsePost; import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.post.PostPagingSource; +import ml.docilealligator.infinityforreddit.postfilter.PostFilter; +import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Call; +import retrofit2.Response; import retrofit2.Retrofit; public class ViewPostDetailActivity extends BaseActivity implements SortTypeSelectionCallback, ActivityToolbarInterface { @@ -113,6 +123,9 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele @BindView(R.id.close_search_panel_image_view_view_post_detail_activity) ImageView closeSearchPanelImageView; @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject @Named("oauth") Retrofit mOauthRetrofit; @Inject @@ -130,7 +143,35 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele @State ArrayList posts; @State + int postType; + @State + String subredditName; + @State + String username; + @State + String userWhere; + @State + String multiPath; + @State + String query; + @State + String trendingSource; + @State + PostFilter postFilter; + @State + String sortType; + @State + String sortTime; + @State + ArrayList readPostList; + @State Post post; + @State + boolean isFetchingMorePosts; + @State + boolean noMorePosts; + @State + boolean fetchMorePostsFailed; public Map authorIcons = new HashMap<>(); private FragmentManager fragmentManager; private SlidrInterface mSlidrInterface; @@ -327,6 +368,14 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele if (savedInstanceState == null) { viewPager2.setCurrentItem(getIntent().getIntExtra(EXTRA_POST_LIST_POSITION, 0), false); } + viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { + @Override + public void onPageSelected(int position) { + if (position > posts.size() - 5) { + fetchMorePosts(); + } + } + }); searchPanelMaterialCardView.setOnClickListener(null); @@ -457,6 +506,164 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele } } + public void fetchMorePosts() { + if (isFetchingMorePosts || noMorePosts) { + return; + } + + isFetchingMorePosts = true; + fetchMorePostsFailed = false; + + Handler handler = new Handler(); + + if (postType != HistoryPostPagingSource.TYPE_READ_POSTS) { + mExecutor.execute(() -> { + RedditAPI api = (mAccessToken == null ? mRetrofit : mOauthRetrofit).create(RedditAPI.class); + Call call; + String afterKey = posts.isEmpty() ? null : posts.get(posts.size() - 1).getFullName(); + switch (postType) { + case PostPagingSource.TYPE_SUBREDDIT: + if (mAccessToken == null) { + if (sortTime != null) { + call = api.getSubredditBestPosts(subredditName, sortType, sortTime, afterKey); + } else { + call = api.getSubredditBestPosts(subredditName, sortType, afterKey); + } + } else { + if (sortTime != null) { + call = api.getSubredditBestPostsOauth(subredditName, sortType, + sortTime, afterKey, APIUtils.getOAuthHeader(mAccessToken)); + } else { + call = api.getSubredditBestPostsOauth(subredditName, sortType, + afterKey, APIUtils.getOAuthHeader(mAccessToken)); + } + } + break; + case PostPagingSource.TYPE_USER: + if (mAccessToken == null) { + if (sortTime != null) { + call = api.getUserPosts(username, afterKey, sortType, + sortTime); + } else { + call = api.getUserPosts(username, afterKey, sortType); + } + } else { + if (sortTime != null) { + call = api.getUserPostsOauth(username, userWhere, afterKey, sortType, + sortTime, APIUtils.getOAuthHeader(mAccessToken)); + } else { + call = api.getUserPostsOauth(username, userWhere, afterKey, sortType, + APIUtils.getOAuthHeader(mAccessToken)); + } + } + break; + case PostPagingSource.TYPE_SEARCH: + if (subredditName == null) { + if (mAccessToken == null) { + if (sortTime != null) { + call = api.searchPosts(query, afterKey, sortType, sortTime, + trendingSource); + } else { + call = api.searchPosts(query, afterKey, sortType, trendingSource); + } + } else { + if (sortTime != null) { + call = api.searchPostsOauth(query, afterKey, sortType, + sortTime, trendingSource, APIUtils.getOAuthHeader(mAccessToken)); + } else { + call = api.searchPostsOauth(query, afterKey, sortType, trendingSource, + APIUtils.getOAuthHeader(mAccessToken)); + } + } + } else { + if (mAccessToken == null) { + if (sortTime != null) { + call = api.searchPostsInSpecificSubreddit(subredditName, query, + sortType, sortTime, afterKey); + } else { + call = api.searchPostsInSpecificSubreddit(subredditName, query, + sortType, afterKey); + } + } else { + if (sortTime != null) { + call = api.searchPostsInSpecificSubredditOauth(subredditName, query, + sortType, sortTime, afterKey, + APIUtils.getOAuthHeader(mAccessToken)); + } else { + call = api.searchPostsInSpecificSubredditOauth(subredditName, query, + sortType, afterKey, + APIUtils.getOAuthHeader(mAccessToken)); + } + } + } + break; + case PostPagingSource.TYPE_MULTI_REDDIT: + if (mAccessToken == null) { + if (sortTime != null) { + call = api.getMultiRedditPosts(multiPath, afterKey, sortTime); + } else { + call = api.getMultiRedditPosts(multiPath, afterKey); + } + } else { + if (sortTime != null) { + call = api.getMultiRedditPostsOauth(multiPath, afterKey, + sortTime, APIUtils.getOAuthHeader(mAccessToken)); + } else { + call = api.getMultiRedditPostsOauth(multiPath, afterKey, + APIUtils.getOAuthHeader(mAccessToken)); + } + } + break; + case PostPagingSource.TYPE_ANONYMOUS_FRONT_PAGE: + //case PostPagingSource.TYPE_ANONYMOUS_MULTIREDDIT + if (sortTime != null) { + call = api.getSubredditBestPosts(subredditName, sortType, sortTime, afterKey); + } else { + call = api.getSubredditBestPosts(subredditName, sortType, afterKey); + } + break; + default: + if (sortTime != null) { + call = api.getBestPosts(sortType, sortTime, afterKey, + APIUtils.getOAuthHeader(mAccessToken)); + } else { + call = api.getBestPosts(sortType, afterKey, APIUtils.getOAuthHeader(mAccessToken)); + } + } + + try { + Response response = call.execute(); + if (response.isSuccessful()) { + String responseString = response.body(); + LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostList); + if (newPosts == null) { + noMorePosts = true; + } else { + LinkedHashSet postLinkedHashSet = new LinkedHashSet<>(posts); + int currentPostsSize = postLinkedHashSet.size(); + postLinkedHashSet.addAll(newPosts); + if (currentPostsSize == postLinkedHashSet.size()) { + noMorePosts = true; + } else { + posts = new ArrayList<>(postLinkedHashSet); + handler.post(() -> sectionsPagerAdapter.notifyItemRangeInserted(currentPostsSize, postLinkedHashSet.size() - currentPostsSize)); + } + } + } else { + fetchMorePostsFailed = true; + } + } catch (IOException e) { + e.printStackTrace(); + fetchMorePostsFailed = true; + } + + isFetchingMorePosts = false; + }); + } else { + + } + } + @Subscribe public void onAccountSwitchEvent(SwitchAccountEvent event) { if (!getClass().getName().equals(event.excludeActivityClassName)) { @@ -467,7 +674,19 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele @Subscribe public void onProvidePostListToViewPostDetailActivityEvent(ProvidePostListToViewPostDetailActivityEvent event) { if (event.postFragmentId == postFragmentId && posts == null) { - posts = event.posts; + this.posts = event.posts; + this.postType = event.postType; + this.subredditName = event.subredditName; + this.username = event.username; + this.userWhere = event.userWhere; + this.multiPath = event.multiPath; + this.query = event.query; + this.trendingSource = event.trendingSource; + this.postFilter = event.postFilter; + this.sortType = event.sortType.getType().value; + this.sortTime = event.sortType.getTime() == null ? null : event.sortType.getTime().value; + this.readPostList = event.readPostList; + if (sectionsPagerAdapter != null) { if (postListPosition > 0) sectionsPagerAdapter.notifyDataSetChanged(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java index 9cb8246b..5638863a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java @@ -49,14 +49,6 @@ public interface RedditAPI { @GET("comments/{id}.json?raw_json=1") Call getPost(@Path("id") String id); - @GET("user/{username}/submitted.json?raw_json=1&limit=25") - Call getUserPosts(@Path("username") String username, @Query("after") String lastItem, - @Query("sort") String sortType); - - @GET("user/{username}/submitted.json?raw_json=1&limit=25") - Call getUserPosts(@Path("username") String username, @Query("after") String lastItem, - @Query("sort") String sortType, @Query("t") String sortTime); - @GET("user/{username}/about.json?raw_json=1") Call getUserData(@Path("username") String username); @@ -212,26 +204,6 @@ public interface RedditAPI { @POST("/api/multi/favorite?raw_json=1&gilding_detail=1") Call favoriteMultiReddit(@HeaderMap Map headers, @FieldMap Map params); - @GET("/api/multi/user/{username}") - Call getUserMultiReddits(@Path("username") String username); - - @GET("{multipath}?raw_json=1") - Call getMultiRedditPosts(@Path(value = "multipath", encoded = true) String multiPath, - @Query("after") String after); - - @GET("{multipath}?raw_json=1") - Call getMultiRedditPosts(@Path(value = "multipath", encoded = true) String multiPath, - @Query("after") String after, @Query("t") String sortTime); - - @GET("{multipath}.json?raw_json=1") - Call getMultiRedditPostsOauth(@Path(value = "multipath", encoded = true) String multiPath, - @Query("after") String after, @Query("t") String sortTime, - @HeaderMap Map headers); - - @GET("{multipath}.json?raw_json=1") - Call getMultiRedditPostsOauth(@Path(value = "multipath", encoded = true) String multiPath, - @Query("after") String after, @HeaderMap Map headers); - @FormUrlEncoded @POST("/api/multi/multipath") Call createMultiReddit(@HeaderMap Map headers, @FieldMap Map params); @@ -408,6 +380,107 @@ public interface RedditAPI { ListenableFuture> getMultiRedditPostsOauthListenableFuture(@Path(value = "multipath", encoded = true) String multiPath, @Query("after") String after, @HeaderMap Map headers); + @GET("{sortType}?raw_json=1") + Call getBestPosts(@Path("sortType") String sortType, @Query("after") String lastItem, @HeaderMap Map headers); + + @GET("{sortType}?raw_json=1") + Call getBestPosts(@Path("sortType") String sortType, @Query("t") String sortTime, + @Query("after") String lastItem, @HeaderMap Map headers); + + @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25&always_show_media=1") + Call getSubredditBestPostsOauth(@Path("subredditName") String subredditName, @Path("sortType") String sortType, + @Query("after") String lastItem, @HeaderMap Map headers); + + @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25&always_show_media=1") + Call getSubredditBestPostsOauth(@Path("subredditName") String subredditName, @Path("sortType") String sortType, + @Query("t") String sortTime, @Query("after") String lastItem, + @HeaderMap Map headers); + + @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25&always_show_media=1") + Call getSubredditBestPosts(@Path("subredditName") String subredditName, @Path("sortType") String sortType, + @Query("after") String lastItem); + + @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25&always_show_media=1") + Call getSubredditBestPosts(@Path("subredditName") String subredditName, @Path("sortType") String sortType, + @Query("t") String sortTime, @Query("after") String lastItem); + + @GET("user/{username}/{where}.json?&type=links&raw_json=1&limit=25") + Call getUserPostsOauth(@Path("username") String username, @Path("where") String where, + @Query("after") String lastItem, @Query("sort") String sortType, @HeaderMap Map headers); + + @GET("user/{username}/{where}.json?&type=links&raw_json=1&limit=25") + Call getUserPostsOauth(@Path("username") String username, @Path("where") String where, + @Query("after") String lastItem, @Query("sort") String sortType, + @Query("t") String sortTime, @HeaderMap Map headers); + + @GET("user/{username}/submitted.json?raw_json=1&limit=25") + Call getUserPosts(@Path("username") String username, @Query("after") String lastItem, + @Query("sort") String sortType); + + @GET("user/{username}/submitted.json?raw_json=1&limit=25") + Call getUserPosts(@Path("username") String username, @Query("after") String lastItem, + @Query("sort") String sortType, @Query("t") String sortTime); + + @GET("search.json?include_over_18=1&raw_json=1&type=link") + Call searchPostsOauth(@Query("q") String query, @Query("after") String after, + @Query("sort") String sort, @Query("source") String source, + @HeaderMap Map headers); + + @GET("search.json?include_over_18=1&raw_json=1&type=link") + Call searchPostsOauth(@Query("q") String query, @Query("after") String after, + @Query("sort") String sort, @Query("t") String sortTime, + @Query("source") String source, + @HeaderMap Map headers); + + @GET("search.json?include_over_18=1&raw_json=1&type=link") + Call searchPosts(@Query("q") String query, @Query("after") String after, + @Query("sort") String sort, @Query("source") String source); + + @GET("search.json?include_over_18=1&raw_json=1&type=link") + Call searchPosts(@Query("q") String query, @Query("after") String after, + @Query("sort") String sort, @Query("t") String sortTime, + @Query("source") String source); + + @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") + Call searchPostsInSpecificSubredditOauth(@Path("subredditName") String subredditName, + @Query("q") String query, @Query("sort") String sort, + @Query("after") String after, + @HeaderMap Map headers); + + @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") + Call searchPostsInSpecificSubredditOauth(@Path("subredditName") String subredditName, + @Query("q") String query, @Query("sort") String sort, + @Query("t") String sortTime, @Query("after") String after, + @HeaderMap Map headers); + + @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") + + Call searchPostsInSpecificSubreddit(@Path("subredditName") String subredditName, + @Query("q") String query, @Query("sort") String sort, + @Query("after") String after); + + @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") + Call searchPostsInSpecificSubreddit(@Path("subredditName") String subredditName, + @Query("q") String query, @Query("sort") String sort, + @Query("t") String sortTime, @Query("after") String after); + + @GET("{multipath}?raw_json=1") + Call getMultiRedditPosts(@Path(value = "multipath", encoded = true) String multiPath, + @Query("after") String after); + + @GET("{multipath}?raw_json=1") + Call getMultiRedditPosts(@Path(value = "multipath", encoded = true) String multiPath, + @Query("after") String after, @Query("t") String sortTime); + + @GET("{multipath}.json?raw_json=1") + Call getMultiRedditPostsOauth(@Path(value = "multipath", encoded = true) String multiPath, + @Query("after") String after, @Query("t") String sortTime, + @HeaderMap Map headers); + + @GET("{multipath}.json?raw_json=1") + Call getMultiRedditPostsOauth(@Path(value = "multipath", encoded = true) String multiPath, + @Query("after") String after, @HeaderMap Map headers); + @POST("r/{subredditName}/api/delete_sr_icon") Call deleteSrIcon(@HeaderMap Map headers, @Path("subredditName") String subredditName); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ProvidePostListToViewPostDetailActivityEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ProvidePostListToViewPostDetailActivityEvent.java index 40fc7bab..15c37ff1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ProvidePostListToViewPostDetailActivityEvent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ProvidePostListToViewPostDetailActivityEvent.java @@ -2,14 +2,39 @@ package ml.docilealligator.infinityforreddit.events; import java.util.ArrayList; +import ml.docilealligator.infinityforreddit.SortType; import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.postfilter.PostFilter; public class ProvidePostListToViewPostDetailActivityEvent { public long postFragmentId; public ArrayList posts; + public int postType; + public String subredditName; + public String username; + public String userWhere; + public String multiPath; + public String query; + public String trendingSource; + public PostFilter postFilter; + public SortType sortType; + public ArrayList readPostList; - public ProvidePostListToViewPostDetailActivityEvent(long postFragmentId, ArrayList posts) { + public ProvidePostListToViewPostDetailActivityEvent(long postFragmentId, ArrayList posts, int postType, + String subredditName, String username, String userWhere, + String multiPath, String query, String trendingSource, + PostFilter postFilter, SortType sortType, ArrayList readPostList) { this.postFragmentId = postFragmentId; this.posts = posts; + this.postType = postType; + this.subredditName = subredditName; + this.username = username; + this.userWhere = userWhere; + this.multiPath = multiPath; + this.query = query; + this.trendingSource = trendingSource; + this.postFilter = postFilter; + this.sortType = sortType; + this.readPostList = readPostList; } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/HistoryPostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/HistoryPostFragment.java index 06ef97e9..596c2c79 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/HistoryPostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/HistoryPostFragment.java @@ -1264,7 +1264,9 @@ public class HistoryPostFragment extends Fragment implements FragmentCommunicato @Subscribe public void onNeedForPostListFromPostRecyclerViewAdapterEvent(NeedForPostListFromPostFragmentEvent event) { if (historyPostFragmentId == event.postFragmentTimeId && mAdapter != null) { - EventBus.getDefault().post(new ProvidePostListToViewPostDetailActivityEvent(historyPostFragmentId, new ArrayList<>(mAdapter.snapshot()))); + EventBus.getDefault().post(new ProvidePostListToViewPostDetailActivityEvent(historyPostFragmentId, + new ArrayList<>(mAdapter.snapshot()), postType, null, null, null, + null, null, null, postFilter, null, null)); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java index 7eb5756a..fd6ed675 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java @@ -2035,7 +2035,9 @@ public class PostFragment extends Fragment implements FragmentCommunicator { @Subscribe public void onNeedForPostListFromPostRecyclerViewAdapterEvent(NeedForPostListFromPostFragmentEvent event) { if (postFragmentId == event.postFragmentTimeId && mAdapter != null) { - EventBus.getDefault().post(new ProvidePostListToViewPostDetailActivityEvent(postFragmentId, new ArrayList<>(mAdapter.snapshot()))); + EventBus.getDefault().post(new ProvidePostListToViewPostDetailActivityEvent(postFragmentId, + new ArrayList<>(mAdapter.snapshot()), postType, subredditName, username, where, + multiRedditPath, query, trendingSource, postFilter, sortType, readPosts)); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/HistoryPostPagingSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/HistoryPostPagingSource.java index 7f773d29..c89f7161 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/post/HistoryPostPagingSource.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/HistoryPostPagingSource.java @@ -28,7 +28,7 @@ import retrofit2.Response; import retrofit2.Retrofit; public class HistoryPostPagingSource extends ListenableFuturePagingSource { - public static final int TYPE_READ_POSTS = 0; + public static final int TYPE_READ_POSTS = 100; private Retrofit retrofit; private Executor executor;