Fix scrolling to correct comment after closing replies
This commit is contained in:
parent
b4016c91c1
commit
d76e9b0bd8
3 changed files with 80 additions and 44 deletions
|
@ -44,6 +44,7 @@ import android.widget.FrameLayout;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.ActionBar;
|
import androidx.appcompat.app.ActionBar;
|
||||||
import androidx.appcompat.app.ActionBarDrawerToggle;
|
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
@ -51,6 +52,7 @@ import androidx.core.app.ActivityCompat;
|
||||||
import androidx.core.view.GravityCompat;
|
import androidx.core.view.GravityCompat;
|
||||||
import androidx.drawerlayout.widget.DrawerLayout;
|
import androidx.drawerlayout.widget.DrawerLayout;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentContainerView;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
|
@ -64,6 +66,7 @@ import org.schabi.newpipe.databinding.ToolbarLayoutBinding;
|
||||||
import org.schabi.newpipe.error.ErrorUtil;
|
import org.schabi.newpipe.error.ErrorUtil;
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
|
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
import org.schabi.newpipe.extractor.services.peertube.PeertubeInstance;
|
import org.schabi.newpipe.extractor.services.peertube.PeertubeInstance;
|
||||||
import org.schabi.newpipe.fragments.BackPressable;
|
import org.schabi.newpipe.fragments.BackPressable;
|
||||||
|
@ -561,9 +564,7 @@ public class MainActivity extends AppCompatActivity {
|
||||||
// Expand DetailsFragment if CommentRepliesFragment was opened
|
// Expand DetailsFragment if CommentRepliesFragment was opened
|
||||||
// and no other CommentRepliesFragments are on top of the back stack
|
// and no other CommentRepliesFragments are on top of the back stack
|
||||||
// to show the top level comments again.
|
// to show the top level comments again.
|
||||||
final FragmentManager.BackStackEntry bse = fm.getBackStackEntryAt(
|
openDetailFragmentFromCommentReplies(fm, false);
|
||||||
fm.getBackStackEntryCount() - 2); // current fragment is at the top
|
|
||||||
openDetailFragmentFromCommentReplies(fm, bse);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -646,10 +647,7 @@ public class MainActivity extends AppCompatActivity {
|
||||||
// Expand DetailsFragment if CommentRepliesFragment was opened
|
// Expand DetailsFragment if CommentRepliesFragment was opened
|
||||||
// and no other CommentRepliesFragments are on top of the back stack
|
// and no other CommentRepliesFragments are on top of the back stack
|
||||||
// to show the top level comments again.
|
// to show the top level comments again.
|
||||||
fm.popBackStackImmediate();
|
openDetailFragmentFromCommentReplies(fm, true);
|
||||||
final FragmentManager.BackStackEntry bse = fm.getBackStackEntryAt(
|
|
||||||
fm.getBackStackEntryCount() - 1);
|
|
||||||
openDetailFragmentFromCommentReplies(fm, bse);
|
|
||||||
} else if (!NavigationHelper.tryGotoSearchFragment(fm)) {
|
} else if (!NavigationHelper.tryGotoSearchFragment(fm)) {
|
||||||
// If search fragment wasn't found in the backstack go to the main fragment
|
// If search fragment wasn't found in the backstack go to the main fragment
|
||||||
NavigationHelper.gotoMainFragment(fm);
|
NavigationHelper.gotoMainFragment(fm);
|
||||||
|
@ -850,38 +848,64 @@ public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private void openDetailFragmentFromCommentReplies(
|
private void openDetailFragmentFromCommentReplies(
|
||||||
@NonNull final FragmentManager fm,
|
@NonNull final FragmentManager fm,
|
||||||
@NonNull final FragmentManager.BackStackEntry bse) {
|
final boolean popBackStack
|
||||||
if (!CommentRepliesFragment.TAG.equals(bse.getName())) {
|
) {
|
||||||
final CommentRepliesFragment commentRepliesFragment =
|
// obtain the name of the fragment under the replies fragment that's going to be popped
|
||||||
(CommentRepliesFragment) fm.findFragmentByTag(
|
@Nullable final String fragmentUnderEntryName;
|
||||||
CommentRepliesFragment.TAG);
|
if (fm.getBackStackEntryCount() < 2) {
|
||||||
final BottomSheetBehavior bsb = BottomSheetBehavior
|
fragmentUnderEntryName = null;
|
||||||
.from(mainBinding.fragmentPlayerHolder);
|
} else {
|
||||||
bsb.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
|
fragmentUnderEntryName = fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 2)
|
||||||
@Override
|
.getName();
|
||||||
public void onStateChanged(@NonNull final View bottomSheet,
|
|
||||||
final int newState) {
|
|
||||||
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
|
|
||||||
final Fragment detailFragment = fm.findFragmentById(
|
|
||||||
R.id.fragment_player_holder);
|
|
||||||
if (detailFragment instanceof VideoDetailFragment
|
|
||||||
&& commentRepliesFragment != null) {
|
|
||||||
// should always be the case
|
|
||||||
((VideoDetailFragment) detailFragment).scrollToComment(
|
|
||||||
commentRepliesFragment.getCommentsInfoItem());
|
|
||||||
}
|
|
||||||
bsb.removeBottomSheetCallback(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSlide(@NonNull final View bottomSheet,
|
|
||||||
final float slideOffset) {
|
|
||||||
// not needed, listener is removed once the sheet is expanded
|
|
||||||
}
|
|
||||||
});
|
|
||||||
bsb.setState(BottomSheetBehavior.STATE_EXPANDED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the root comment is the comment for which the user opened the replies page
|
||||||
|
@Nullable final CommentRepliesFragment repliesFragment =
|
||||||
|
(CommentRepliesFragment) fm.findFragmentByTag(CommentRepliesFragment.TAG);
|
||||||
|
@Nullable final CommentsInfoItem rootComment =
|
||||||
|
repliesFragment == null ? null : repliesFragment.getCommentsInfoItem();
|
||||||
|
|
||||||
|
// sometimes this function pops the backstack, other times it's handled by the system
|
||||||
|
if (popBackStack) {
|
||||||
|
fm.popBackStackImmediate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// only expand the bottom sheet back if there are no more nested comment replies fragments
|
||||||
|
// stacked under the one that is currently being popped
|
||||||
|
if (CommentRepliesFragment.TAG.equals(fragmentUnderEntryName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final BottomSheetBehavior<FragmentContainerView> behavior = BottomSheetBehavior
|
||||||
|
.from(mainBinding.fragmentPlayerHolder);
|
||||||
|
// do not return to the comment if the details fragment was closed
|
||||||
|
if (behavior.getState() == BottomSheetBehavior.STATE_HIDDEN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// scroll to the root comment once the bottom sheet expansion animation is finished
|
||||||
|
behavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
|
||||||
|
@Override
|
||||||
|
public void onStateChanged(@NonNull final View bottomSheet,
|
||||||
|
final int newState) {
|
||||||
|
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
|
||||||
|
final Fragment detailFragment = fm.findFragmentById(
|
||||||
|
R.id.fragment_player_holder);
|
||||||
|
if (detailFragment instanceof VideoDetailFragment && rootComment != null) {
|
||||||
|
// should always be the case
|
||||||
|
((VideoDetailFragment) detailFragment).scrollToComment(rootComment);
|
||||||
|
}
|
||||||
|
behavior.removeBottomSheetCallback(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSlide(@NonNull final View bottomSheet, final float slideOffset) {
|
||||||
|
// not needed, listener is removed once the sheet is expanded
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean bottomSheetHiddenOrCollapsed() {
|
private boolean bottomSheetHiddenOrCollapsed() {
|
||||||
|
|
|
@ -1014,10 +1014,16 @@ public final class VideoDetailFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scrollToComment(final CommentsInfoItem comment) {
|
public void scrollToComment(final CommentsInfoItem comment) {
|
||||||
final Fragment fragment = pageAdapter.getItem(
|
final int commentsTabPos = pageAdapter.getItemPositionByTitle(COMMENTS_TAB_TAG);
|
||||||
pageAdapter.getItemPositionByTitle(COMMENTS_TAB_TAG));
|
final Fragment fragment = pageAdapter.getItem(commentsTabPos);
|
||||||
if (fragment instanceof CommentsFragment) {
|
if (!(fragment instanceof CommentsFragment)) {
|
||||||
((CommentsFragment) fragment).scrollToComment(comment);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unexpand the app bar only if scrolling to the comment succeeded
|
||||||
|
if (((CommentsFragment) fragment).scrollToComment(comment)) {
|
||||||
|
binding.appBarLayout.setExpanded(false, false);
|
||||||
|
binding.viewPager.setCurrentItem(commentsTabPos, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,13 @@ public class CommentsFragment extends BaseListInfoFragment<CommentsInfoItem, Com
|
||||||
return ItemViewMode.LIST;
|
return ItemViewMode.LIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scrollToComment(final CommentsInfoItem comment) {
|
public boolean scrollToComment(final CommentsInfoItem comment) {
|
||||||
itemsList.scrollToPosition(infoListAdapter.getItemsList().indexOf(comment));
|
final int position = infoListAdapter.getItemsList().indexOf(comment);
|
||||||
|
if (position < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
itemsList.scrollToPosition(position);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue