Load more posts in ViewPostDetailActivity for post feed in PostFragment.

This commit is contained in:
Docile-Alligator 2022-11-05 00:33:12 +11:00
parent eb40bad3ef
commit 0a286cd9ba
6 changed files with 354 additions and 33 deletions

View File

@ -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<Post> 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<String> readPostList;
@State
Post post;
@State
boolean isFetchingMorePosts;
@State
boolean noMorePosts;
@State
boolean fetchMorePostsFailed;
public Map<String, String> 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<String> 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<String> response = call.execute();
if (response.isSuccessful()) {
String responseString = response.body();
LinkedHashSet<Post> newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostList);
if (newPosts == null) {
noMorePosts = true;
} else {
LinkedHashSet<Post> 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();

View File

@ -49,14 +49,6 @@ public interface RedditAPI {
@GET("comments/{id}.json?raw_json=1")
Call<String> getPost(@Path("id") String id);
@GET("user/{username}/submitted.json?raw_json=1&limit=25")
Call<String> getUserPosts(@Path("username") String username, @Query("after") String lastItem,
@Query("sort") String sortType);
@GET("user/{username}/submitted.json?raw_json=1&limit=25")
Call<String> 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<String> getUserData(@Path("username") String username);
@ -212,26 +204,6 @@ public interface RedditAPI {
@POST("/api/multi/favorite?raw_json=1&gilding_detail=1")
Call<String> favoriteMultiReddit(@HeaderMap Map<String, String> headers, @FieldMap Map<String, String> params);
@GET("/api/multi/user/{username}")
Call<String> getUserMultiReddits(@Path("username") String username);
@GET("{multipath}?raw_json=1")
Call<String> getMultiRedditPosts(@Path(value = "multipath", encoded = true) String multiPath,
@Query("after") String after);
@GET("{multipath}?raw_json=1")
Call<String> getMultiRedditPosts(@Path(value = "multipath", encoded = true) String multiPath,
@Query("after") String after, @Query("t") String sortTime);
@GET("{multipath}.json?raw_json=1")
Call<String> getMultiRedditPostsOauth(@Path(value = "multipath", encoded = true) String multiPath,
@Query("after") String after, @Query("t") String sortTime,
@HeaderMap Map<String, String> headers);
@GET("{multipath}.json?raw_json=1")
Call<String> getMultiRedditPostsOauth(@Path(value = "multipath", encoded = true) String multiPath,
@Query("after") String after, @HeaderMap Map<String, String> headers);
@FormUrlEncoded
@POST("/api/multi/multipath")
Call<String> createMultiReddit(@HeaderMap Map<String, String> headers, @FieldMap Map<String, String> params);
@ -408,6 +380,107 @@ public interface RedditAPI {
ListenableFuture<Response<String>> getMultiRedditPostsOauthListenableFuture(@Path(value = "multipath", encoded = true) String multiPath,
@Query("after") String after, @HeaderMap Map<String, String> headers);
@GET("{sortType}?raw_json=1")
Call<String> getBestPosts(@Path("sortType") String sortType, @Query("after") String lastItem, @HeaderMap Map<String, String> headers);
@GET("{sortType}?raw_json=1")
Call<String> getBestPosts(@Path("sortType") String sortType, @Query("t") String sortTime,
@Query("after") String lastItem, @HeaderMap Map<String, String> headers);
@GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25&always_show_media=1")
Call<String> getSubredditBestPostsOauth(@Path("subredditName") String subredditName, @Path("sortType") String sortType,
@Query("after") String lastItem, @HeaderMap Map<String, String> headers);
@GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25&always_show_media=1")
Call<String> getSubredditBestPostsOauth(@Path("subredditName") String subredditName, @Path("sortType") String sortType,
@Query("t") String sortTime, @Query("after") String lastItem,
@HeaderMap Map<String, String> headers);
@GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25&always_show_media=1")
Call<String> 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<String> 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<String> getUserPostsOauth(@Path("username") String username, @Path("where") String where,
@Query("after") String lastItem, @Query("sort") String sortType, @HeaderMap Map<String, String> headers);
@GET("user/{username}/{where}.json?&type=links&raw_json=1&limit=25")
Call<String> getUserPostsOauth(@Path("username") String username, @Path("where") String where,
@Query("after") String lastItem, @Query("sort") String sortType,
@Query("t") String sortTime, @HeaderMap Map<String, String> headers);
@GET("user/{username}/submitted.json?raw_json=1&limit=25")
Call<String> getUserPosts(@Path("username") String username, @Query("after") String lastItem,
@Query("sort") String sortType);
@GET("user/{username}/submitted.json?raw_json=1&limit=25")
Call<String> 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<String> searchPostsOauth(@Query("q") String query, @Query("after") String after,
@Query("sort") String sort, @Query("source") String source,
@HeaderMap Map<String, String> headers);
@GET("search.json?include_over_18=1&raw_json=1&type=link")
Call<String> searchPostsOauth(@Query("q") String query, @Query("after") String after,
@Query("sort") String sort, @Query("t") String sortTime,
@Query("source") String source,
@HeaderMap Map<String, String> headers);
@GET("search.json?include_over_18=1&raw_json=1&type=link")
Call<String> 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<String> 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<String> searchPostsInSpecificSubredditOauth(@Path("subredditName") String subredditName,
@Query("q") String query, @Query("sort") String sort,
@Query("after") String after,
@HeaderMap Map<String, String> headers);
@GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true")
Call<String> searchPostsInSpecificSubredditOauth(@Path("subredditName") String subredditName,
@Query("q") String query, @Query("sort") String sort,
@Query("t") String sortTime, @Query("after") String after,
@HeaderMap Map<String, String> headers);
@GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true")
Call<String> 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<String> 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<String> getMultiRedditPosts(@Path(value = "multipath", encoded = true) String multiPath,
@Query("after") String after);
@GET("{multipath}?raw_json=1")
Call<String> getMultiRedditPosts(@Path(value = "multipath", encoded = true) String multiPath,
@Query("after") String after, @Query("t") String sortTime);
@GET("{multipath}.json?raw_json=1")
Call<String> getMultiRedditPostsOauth(@Path(value = "multipath", encoded = true) String multiPath,
@Query("after") String after, @Query("t") String sortTime,
@HeaderMap Map<String, String> headers);
@GET("{multipath}.json?raw_json=1")
Call<String> getMultiRedditPostsOauth(@Path(value = "multipath", encoded = true) String multiPath,
@Query("after") String after, @HeaderMap Map<String, String> headers);
@POST("r/{subredditName}/api/delete_sr_icon")
Call<String> deleteSrIcon(@HeaderMap Map<String, String> headers, @Path("subredditName") String subredditName);

View File

@ -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<Post> 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<String> readPostList;
public ProvidePostListToViewPostDetailActivityEvent(long postFragmentId, ArrayList<Post> posts) {
public ProvidePostListToViewPostDetailActivityEvent(long postFragmentId, ArrayList<Post> posts, int postType,
String subredditName, String username, String userWhere,
String multiPath, String query, String trendingSource,
PostFilter postFilter, SortType sortType, ArrayList<String> 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;
}
}

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -28,7 +28,7 @@ import retrofit2.Response;
import retrofit2.Retrofit;
public class HistoryPostPagingSource extends ListenableFuturePagingSource<String, Post> {
public static final int TYPE_READ_POSTS = 0;
public static final int TYPE_READ_POSTS = 100;
private Retrofit retrofit;
private Executor executor;