mirror of
https://github.com/TeamNewPipe/NewPipe.git
synced 2024-11-22 02:53:09 +01:00
Fix inconsistency when LocalPlaylist is used as MainFragment tab
This commit is contained in:
parent
1cf670dad9
commit
3d5a8af52b
@ -38,6 +38,7 @@ import org.schabi.newpipe.R;
|
|||||||
import org.schabi.newpipe.databinding.FragmentMainBinding;
|
import org.schabi.newpipe.databinding.FragmentMainBinding;
|
||||||
import org.schabi.newpipe.error.ErrorUtil;
|
import org.schabi.newpipe.error.ErrorUtil;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
|
import org.schabi.newpipe.local.playlist.LocalPlaylistFragment;
|
||||||
import org.schabi.newpipe.settings.tabs.Tab;
|
import org.schabi.newpipe.settings.tabs.Tab;
|
||||||
import org.schabi.newpipe.settings.tabs.TabsManager;
|
import org.schabi.newpipe.settings.tabs.TabsManager;
|
||||||
import org.schabi.newpipe.util.NavigationHelper;
|
import org.schabi.newpipe.util.NavigationHelper;
|
||||||
@ -217,6 +218,12 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
|
|||||||
setTitle(tabsList.get(tabPosition).getTabName(requireContext()));
|
setTitle(tabsList.get(tabPosition).getTabName(requireContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void commitPlaylistTabs() {
|
||||||
|
pagerAdapter.getLocalPlaylistFragments()
|
||||||
|
.stream()
|
||||||
|
.forEach(LocalPlaylistFragment::commitChanges);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateTabLayoutPosition() {
|
private void updateTabLayoutPosition() {
|
||||||
final ScrollableTabLayout tabLayout = binding.mainTabLayout;
|
final ScrollableTabLayout tabLayout = binding.mainTabLayout;
|
||||||
final ViewPager viewPager = binding.pager;
|
final ViewPager viewPager = binding.pager;
|
||||||
@ -268,10 +275,18 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
|
|||||||
updateTitleForTab(tab.getPosition());
|
updateTitleForTab(tab.getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class SelectedTabsPagerAdapter
|
public static final class SelectedTabsPagerAdapter
|
||||||
extends FragmentStatePagerAdapterMenuWorkaround {
|
extends FragmentStatePagerAdapterMenuWorkaround {
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final List<Tab> internalTabsList;
|
private final List<Tab> internalTabsList;
|
||||||
|
/**
|
||||||
|
* Keep reference to LocalPlaylistFragments, because their data can be modified by the user
|
||||||
|
* during runtime and changes are not committed immediately. However, in some cases,
|
||||||
|
* the changes need to be committed immediately by calling
|
||||||
|
* {@link LocalPlaylistFragment#commitChanges()}.
|
||||||
|
* The fragments are removed when {@link LocalPlaylistFragment#onDestroy()} is called.
|
||||||
|
*/
|
||||||
|
private final List<LocalPlaylistFragment> localPlaylistFragments = new ArrayList<>();
|
||||||
|
|
||||||
private SelectedTabsPagerAdapter(final Context context,
|
private SelectedTabsPagerAdapter(final Context context,
|
||||||
final FragmentManager fragmentManager,
|
final FragmentManager fragmentManager,
|
||||||
@ -298,9 +313,17 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
|
|||||||
((BaseFragment) fragment).useAsFrontPage(true);
|
((BaseFragment) fragment).useAsFrontPage(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fragment instanceof LocalPlaylistFragment) {
|
||||||
|
localPlaylistFragments.add((LocalPlaylistFragment) fragment);
|
||||||
|
}
|
||||||
|
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<LocalPlaylistFragment> getLocalPlaylistFragments() {
|
||||||
|
return localPlaylistFragments;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemPosition(@NonNull final Object object) {
|
public int getItemPosition(@NonNull final Object object) {
|
||||||
// Causes adapter to reload all Fragments when
|
// Causes adapter to reload all Fragments when
|
||||||
|
@ -85,6 +85,7 @@ import org.schabi.newpipe.extractor.stream.VideoStream;
|
|||||||
import org.schabi.newpipe.fragments.BackPressable;
|
import org.schabi.newpipe.fragments.BackPressable;
|
||||||
import org.schabi.newpipe.fragments.BaseStateFragment;
|
import org.schabi.newpipe.fragments.BaseStateFragment;
|
||||||
import org.schabi.newpipe.fragments.EmptyFragment;
|
import org.schabi.newpipe.fragments.EmptyFragment;
|
||||||
|
import org.schabi.newpipe.fragments.MainFragment;
|
||||||
import org.schabi.newpipe.fragments.list.comments.CommentsFragment;
|
import org.schabi.newpipe.fragments.list.comments.CommentsFragment;
|
||||||
import org.schabi.newpipe.fragments.list.videos.RelatedItemsFragment;
|
import org.schabi.newpipe.fragments.list.videos.RelatedItemsFragment;
|
||||||
import org.schabi.newpipe.ktx.AnimationType;
|
import org.schabi.newpipe.ktx.AnimationType;
|
||||||
@ -482,6 +483,8 @@ public final class VideoDetailFragment
|
|||||||
// commit previous pending changes to database
|
// commit previous pending changes to database
|
||||||
if (fragment instanceof LocalPlaylistFragment) {
|
if (fragment instanceof LocalPlaylistFragment) {
|
||||||
((LocalPlaylistFragment) fragment).commitChanges();
|
((LocalPlaylistFragment) fragment).commitChanges();
|
||||||
|
} else if (fragment instanceof MainFragment) {
|
||||||
|
((MainFragment) fragment).commitPlaylistTabs();
|
||||||
}
|
}
|
||||||
|
|
||||||
disposables.add(PlaylistDialog.createCorrespondingDialog(requireContext(),
|
disposables.add(PlaylistDialog.createCorrespondingDialog(requireContext(),
|
||||||
|
@ -41,6 +41,7 @@ import org.schabi.newpipe.databinding.PlaylistControlBinding;
|
|||||||
import org.schabi.newpipe.error.ErrorInfo;
|
import org.schabi.newpipe.error.ErrorInfo;
|
||||||
import org.schabi.newpipe.error.UserAction;
|
import org.schabi.newpipe.error.UserAction;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||||
|
import org.schabi.newpipe.fragments.MainFragment;
|
||||||
import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder;
|
import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder;
|
||||||
import org.schabi.newpipe.info_list.dialog.InfoItemDialog;
|
import org.schabi.newpipe.info_list.dialog.InfoItemDialog;
|
||||||
import org.schabi.newpipe.info_list.dialog.StreamDialogDefaultEntry;
|
import org.schabi.newpipe.info_list.dialog.StreamDialogDefaultEntry;
|
||||||
@ -71,7 +72,7 @@ import io.reactivex.rxjava3.subjects.PublishSubject;
|
|||||||
|
|
||||||
public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistStreamEntry>, Void>
|
public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistStreamEntry>, Void>
|
||||||
implements PlaylistControlViewHolder {
|
implements PlaylistControlViewHolder {
|
||||||
// Save the list 10 seconds after the last change occurred
|
/** Save the list 10 seconds after the last change occurred. */
|
||||||
private static final long SAVE_DEBOUNCE_MILLIS = 10000;
|
private static final long SAVE_DEBOUNCE_MILLIS = 10000;
|
||||||
private static final int MINIMUM_INITIAL_DRAG_VELOCITY = 12;
|
private static final int MINIMUM_INITIAL_DRAG_VELOCITY = 12;
|
||||||
@State
|
@State
|
||||||
@ -92,13 +93,20 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
|
|||||||
private PublishSubject<Long> debouncedSaveSignal;
|
private PublishSubject<Long> debouncedSaveSignal;
|
||||||
private CompositeDisposable disposables;
|
private CompositeDisposable disposables;
|
||||||
|
|
||||||
/* Has the playlist been fully loaded from db */
|
/** Whether the playlist has been fully loaded from db. */
|
||||||
private AtomicBoolean isLoadingComplete;
|
private AtomicBoolean isLoadingComplete;
|
||||||
/* Has the playlist been modified (e.g. items reordered or deleted) */
|
/** Whether the playlist has been modified (e.g. items reordered or deleted) */
|
||||||
private AtomicBoolean isModified;
|
private AtomicBoolean isModified;
|
||||||
/* Flag to prevent simultaneous rewrites of the playlist */
|
/** Flag to prevent simultaneous rewrites of the playlist. */
|
||||||
private boolean isRewritingPlaylist = false;
|
private boolean isRewritingPlaylist = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The pager adapter that the fragment is created from when it is used as frontpage, i.e.
|
||||||
|
* {@link #useAsFrontPage} is {@link true}.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private MainFragment.SelectedTabsPagerAdapter tabsPagerAdapter = null;
|
||||||
|
|
||||||
public static LocalPlaylistFragment getInstance(final long playlistId, final String name) {
|
public static LocalPlaylistFragment getInstance(final long playlistId, final String name) {
|
||||||
final LocalPlaylistFragment instance = new LocalPlaylistFragment();
|
final LocalPlaylistFragment instance = new LocalPlaylistFragment();
|
||||||
instance.setInitialData(playlistId, name);
|
instance.setInitialData(playlistId, name);
|
||||||
@ -158,9 +166,11 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
|
|||||||
return headerBinding;
|
return headerBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit changes immediately when the user turns to the player.
|
/**
|
||||||
// Delete operations will be committed to ensure that the database
|
* <p>Commit changes immediately if the playlist has been modified.</p>
|
||||||
// is up to date when the user adds the just deleted stream by the player.
|
* Delete operations and other modifications will be committed to ensure that the database
|
||||||
|
* is up to date, e.g. when the user adds the just deleted stream from another fragment.
|
||||||
|
*/
|
||||||
public void commitChanges() {
|
public void commitChanges() {
|
||||||
if (isModified != null && isModified.get()) {
|
if (isModified != null && isModified.get()) {
|
||||||
saveImmediate();
|
saveImmediate();
|
||||||
@ -300,6 +310,9 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
|
|||||||
if (disposables != null) {
|
if (disposables != null) {
|
||||||
disposables.dispose();
|
disposables.dispose();
|
||||||
}
|
}
|
||||||
|
if (tabsPagerAdapter != null) {
|
||||||
|
tabsPagerAdapter.getLocalPlaylistFragments().remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
debouncedSaveSignal = null;
|
debouncedSaveSignal = null;
|
||||||
playlistManager = null;
|
playlistManager = null;
|
||||||
@ -886,5 +899,10 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
|
|||||||
)
|
)
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTabsPagerAdapter(
|
||||||
|
@Nullable final MainFragment.SelectedTabsPagerAdapter tabsPagerAdapter) {
|
||||||
|
this.tabsPagerAdapter = tabsPagerAdapter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user