diff options
5 files changed, 199 insertions, 12 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java index 79b2961b..e2dfa1d4 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java @@ -68,6 +68,7 @@ import ml.docilealligator.infinityforreddit.fragments.CommentsListingFragment; import ml.docilealligator.infinityforreddit.fragments.FollowedUsersListingFragment; import ml.docilealligator.infinityforreddit.fragments.HistoryPostFragment; import ml.docilealligator.infinityforreddit.fragments.InboxFragment; +import ml.docilealligator.infinityforreddit.fragments.MorePostsInfoFragment; import ml.docilealligator.infinityforreddit.fragments.MultiRedditListingFragment; import ml.docilealligator.infinityforreddit.fragments.PostFragment; import ml.docilealligator.infinityforreddit.fragments.SidebarFragment; @@ -306,4 +307,6 @@ public interface AppComponent { void inject(HistoryPostFragment historyPostFragment); void inject(HistoryActivity historyActivity); + + void inject(MorePostsInfoFragment morePostsInfoFragment); } 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 3a59798d..44fe148c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java @@ -9,6 +9,7 @@ import android.content.res.ColorStateList; import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.os.Looper; import android.view.KeyEvent; import android.view.MenuItem; import android.view.View; @@ -72,6 +73,7 @@ import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.events.NeedForPostListFromPostFragmentEvent; import ml.docilealligator.infinityforreddit.events.ProvidePostListToViewPostDetailActivityEvent; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.fragments.MorePostsInfoFragment; import ml.docilealligator.infinityforreddit.fragments.ViewPostDetailFragment; import ml.docilealligator.infinityforreddit.post.HistoryPostPagingSource; import ml.docilealligator.infinityforreddit.post.ParsePost; @@ -373,7 +375,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageSelected(int position) { - if (posts != null && position > posts.size() - 5) { + if (posts != null && position > posts.size() - 2) { fetchMorePosts(); } } @@ -516,7 +518,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele isFetchingMorePosts = true; fetchMorePostsFailed = false; - Handler handler = new Handler(); + Handler handler = new Handler(Looper.getMainLooper()); if (postType != HistoryPostPagingSource.TYPE_READ_POSTS) { mExecutor.execute(() -> { @@ -639,27 +641,53 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele String responseString = response.body(); LinkedHashSet<Post> newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostList); if (newPosts == null) { - noMorePosts = true; + handler.post(() -> { + noMorePosts = true; + MorePostsInfoFragment fragment = sectionsPagerAdapter.getMorePostsInfoFragment(); + if (fragment != null) { + fragment.setStatus(MorePostsInfoFragment.Status.NO_MORE_POSTS); + } + }); } else { LinkedHashSet<Post> postLinkedHashSet = new LinkedHashSet<>(posts); int currentPostsSize = postLinkedHashSet.size(); postLinkedHashSet.addAll(newPosts); if (currentPostsSize == postLinkedHashSet.size()) { - noMorePosts = true; + handler.post(() -> { + noMorePosts = true; + MorePostsInfoFragment fragment = sectionsPagerAdapter.getMorePostsInfoFragment(); + if (fragment != null) { + fragment.setStatus(MorePostsInfoFragment.Status.NO_MORE_POSTS); + } + }); } else { posts = new ArrayList<>(postLinkedHashSet); handler.post(() -> sectionsPagerAdapter.notifyItemRangeInserted(currentPostsSize, postLinkedHashSet.size() - currentPostsSize)); } } } else { - fetchMorePostsFailed = true; + handler.post(() -> { + fetchMorePostsFailed = true; + MorePostsInfoFragment fragment = sectionsPagerAdapter.getMorePostsInfoFragment(); + if (fragment != null) { + fragment.setStatus(MorePostsInfoFragment.Status.FAILED); + } + }); } } catch (IOException e) { e.printStackTrace(); - fetchMorePostsFailed = true; + handler.post(() -> { + fetchMorePostsFailed = true; + MorePostsInfoFragment fragment = sectionsPagerAdapter.getMorePostsInfoFragment(); + if (fragment != null) { + fragment.setStatus(MorePostsInfoFragment.Status.FAILED); + } + }); } - isFetchingMorePosts = false; + handler.post(() -> { + isFetchingMorePosts = false; + }); }); } else { mExecutor.execute((Runnable) () -> { @@ -686,25 +714,53 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele String responseString = response.body(); LinkedHashSet<Post> newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, null); if (newPosts == null || newPosts.isEmpty()) { - noMorePosts = true; + handler.post(() -> { + noMorePosts = true; + MorePostsInfoFragment fragment = sectionsPagerAdapter.getMorePostsInfoFragment(); + if (fragment != null) { + fragment.setStatus(MorePostsInfoFragment.Status.NO_MORE_POSTS); + } + }); } else { LinkedHashSet<Post> postLinkedHashSet = new LinkedHashSet<>(posts); int currentPostsSize = postLinkedHashSet.size(); postLinkedHashSet.addAll(newPosts); if (currentPostsSize == postLinkedHashSet.size()) { - noMorePosts = true; + handler.post(() -> { + noMorePosts = true; + MorePostsInfoFragment fragment = sectionsPagerAdapter.getMorePostsInfoFragment(); + if (fragment != null) { + fragment.setStatus(MorePostsInfoFragment.Status.NO_MORE_POSTS); + } + }); } else { posts = new ArrayList<>(postLinkedHashSet); handler.post(() -> sectionsPagerAdapter.notifyItemRangeInserted(currentPostsSize, postLinkedHashSet.size() - currentPostsSize)); } } } else { - fetchMorePostsFailed = true; + handler.post(() -> { + fetchMorePostsFailed = true; + MorePostsInfoFragment fragment = sectionsPagerAdapter.getMorePostsInfoFragment(); + if (fragment != null) { + fragment.setStatus(MorePostsInfoFragment.Status.NO_MORE_POSTS); + } + }); } } catch (IOException e) { e.printStackTrace(); - fetchMorePostsFailed = true; + handler.post(() -> { + fetchMorePostsFailed = true; + MorePostsInfoFragment fragment = sectionsPagerAdapter.getMorePostsInfoFragment(); + if (fragment != null) { + fragment.setStatus(MorePostsInfoFragment.Status.NO_MORE_POSTS); + } + }); } + + handler.post(() -> { + isFetchingMorePosts = false; + }); }); } } @@ -877,6 +933,13 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele bundle.putString(ViewPostDetailFragment.EXTRA_CONTEXT_NUMBER, getIntent().getStringExtra(EXTRA_CONTEXT_NUMBER)); bundle.putString(ViewPostDetailFragment.EXTRA_MESSAGE_FULLNAME, getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME)); } else { + if (position >= posts.size()) { + MorePostsInfoFragment morePostsInfoFragment = new MorePostsInfoFragment(); + Bundle moreBundle = new Bundle(); + moreBundle.putInt(MorePostsInfoFragment.EXTRA_STATUS, MorePostsInfoFragment.Status.LOADING); + morePostsInfoFragment.setArguments(moreBundle); + return morePostsInfoFragment; + } bundle.putParcelable(ViewPostDetailFragment.EXTRA_POST_DATA, posts.get(position)); bundle.putInt(ViewPostDetailFragment.EXTRA_POST_LIST_POSITION, position); } @@ -897,7 +960,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele @Override public int getItemCount() { - return posts == null ? 1 : posts.size(); + return posts == null ? 1 : posts.size() + 1; } @Nullable @@ -911,5 +974,17 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele } return null; } + + @Nullable + MorePostsInfoFragment getMorePostsInfoFragment() { + if (posts == null || fragmentManager == null) { + return null; + } + Fragment fragment = fragmentManager.findFragmentByTag("f" + posts.size()); + if (fragment instanceof MorePostsInfoFragment) { + return (MorePostsInfoFragment) fragment; + } + return null; + } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/MorePostsInfoFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/MorePostsInfoFragment.java new file mode 100644 index 00000000..499c30ff --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/MorePostsInfoFragment.java @@ -0,0 +1,84 @@ +package ml.docilealligator.infinityforreddit.fragments; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.IntDef; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.inject.Inject; + +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.activities.BaseActivity; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.databinding.FragmentMorePostsInfoBinding; + +public class MorePostsInfoFragment extends Fragment { + + public static final String EXTRA_STATUS = "ES"; + + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private FragmentMorePostsInfoBinding binding; + private BaseActivity mActivity; + @Status + int status; + + public MorePostsInfoFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); + + binding = FragmentMorePostsInfoBinding.inflate(inflater, container, false); + + applyTheme(); + + setStatus(getArguments().getInt(EXTRA_STATUS, Status.LOADING)); + + return binding.getRoot(); + } + + public void setStatus(@Status int status) { + this.status = status; + switch (status) { + case Status.LOADING: + binding.infoTextViewMorePostsInfoFragment.setText(R.string.loading); + break; + case Status.FAILED: + binding.infoTextViewMorePostsInfoFragment.setText(R.string.load_more_posts_failed); + break; + case Status.NO_MORE_POSTS: + binding.infoTextViewMorePostsInfoFragment.setText(R.string.no_more_posts); + } + } + + private void applyTheme() { + binding.infoTextViewMorePostsInfoFragment.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + mActivity = (BaseActivity) context; + } + + @IntDef({Status.LOADING, Status.FAILED, Status.NO_MORE_POSTS}) + @Retention(RetentionPolicy.SOURCE) + public @interface Status { + int LOADING = 0; + int FAILED = 1; + int NO_MORE_POSTS = 2; + } +}
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_more_posts_info.xml b/app/src/main/res/layout/fragment_more_posts_info.xml new file mode 100644 index 00000000..bb36362c --- /dev/null +++ b/app/src/main/res/layout/fragment_more_posts_info.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" + tools:context=".fragments.MorePostsInfoFragment"> + + <TextView + android:id="@+id/info_text_view_more_posts_info_fragment" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="16dp" + android:textSize="?attr/font_default" + android:fontFamily="?attr/font_family" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" /> + + +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 519e92ac..8d983cae 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1312,4 +1312,7 @@ <string name="invalid_regex">Invalid regex pattern</string> + <string name="load_more_posts_failed">Failed to load more posts</string> + <string name="no_more_posts">No more posts</string> + </resources> |