2018-01-28 07:14:38 +01:00
|
|
|
package org.schabi.newpipe.fragments.local.bookmark;
|
2018-01-17 06:12:03 +01:00
|
|
|
|
2018-01-28 07:14:38 +01:00
|
|
|
import android.app.AlertDialog;
|
2018-01-17 06:12:03 +01:00
|
|
|
import android.content.Context;
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.os.Parcelable;
|
|
|
|
import android.support.annotation.NonNull;
|
|
|
|
import android.support.annotation.Nullable;
|
|
|
|
import android.support.v7.widget.LinearLayoutManager;
|
|
|
|
import android.support.v7.widget.RecyclerView;
|
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
|
|
import org.reactivestreams.Subscriber;
|
|
|
|
import org.reactivestreams.Subscription;
|
|
|
|
import org.schabi.newpipe.NewPipeDatabase;
|
|
|
|
import org.schabi.newpipe.R;
|
2018-01-28 07:14:38 +01:00
|
|
|
import org.schabi.newpipe.database.LocalItem;
|
2018-01-17 06:12:03 +01:00
|
|
|
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
|
|
|
|
import org.schabi.newpipe.fragments.BaseStateFragment;
|
2018-01-28 07:14:38 +01:00
|
|
|
import org.schabi.newpipe.fragments.local.LocalItemListAdapter;
|
|
|
|
import org.schabi.newpipe.fragments.local.LocalPlaylistManager;
|
2018-01-29 03:26:19 +01:00
|
|
|
import org.schabi.newpipe.fragments.local.OnLocalItemGesture;
|
2018-01-17 06:12:03 +01:00
|
|
|
import org.schabi.newpipe.report.UserAction;
|
|
|
|
import org.schabi.newpipe.util.NavigationHelper;
|
|
|
|
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import icepick.State;
|
|
|
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
|
|
|
import io.reactivex.disposables.CompositeDisposable;
|
|
|
|
|
|
|
|
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
|
|
|
|
|
|
|
public class BookmarkFragment extends BaseStateFragment<List<PlaylistMetadataEntry>> {
|
|
|
|
private View watchHistoryButton;
|
|
|
|
private View mostWatchedButton;
|
|
|
|
|
2018-01-28 07:14:38 +01:00
|
|
|
private LocalItemListAdapter itemListAdapter;
|
2018-01-17 06:12:03 +01:00
|
|
|
private RecyclerView itemsList;
|
|
|
|
|
|
|
|
@State
|
|
|
|
protected Parcelable itemsListState;
|
|
|
|
|
|
|
|
private Subscription databaseSubscription;
|
|
|
|
private CompositeDisposable disposables = new CompositeDisposable();
|
|
|
|
private LocalPlaylistManager localPlaylistManager;
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Fragment LifeCycle
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setUserVisibleHint(boolean isVisibleToUser) {
|
|
|
|
super.setUserVisibleHint(isVisibleToUser);
|
|
|
|
if(isVisibleToUser && activity != null && activity.getSupportActionBar() != null) {
|
|
|
|
activity.getSupportActionBar().setTitle(R.string.tab_bookmarks);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onAttach(Context context) {
|
|
|
|
super.onAttach(context);
|
2018-01-28 07:14:38 +01:00
|
|
|
itemListAdapter = new LocalItemListAdapter(activity);
|
2018-01-17 06:12:03 +01:00
|
|
|
localPlaylistManager = new LocalPlaylistManager(NewPipeDatabase.getInstance(context));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
@Override
|
|
|
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
|
|
|
@Nullable ViewGroup container,
|
|
|
|
Bundle savedInstanceState) {
|
|
|
|
if (activity.getSupportActionBar() != null) {
|
|
|
|
activity.getSupportActionBar().setDisplayShowTitleEnabled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
activity.setTitle(R.string.tab_bookmarks);
|
|
|
|
if(useAsFrontPage) {
|
|
|
|
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
|
|
|
}
|
|
|
|
return inflater.inflate(R.layout.fragment_bookmarks, container, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onPause() {
|
|
|
|
super.onPause();
|
|
|
|
itemsListState = itemsList.getLayoutManager().onSaveInstanceState();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroyView() {
|
|
|
|
if (disposables != null) disposables.clear();
|
|
|
|
if (databaseSubscription != null) databaseSubscription.cancel();
|
|
|
|
|
|
|
|
super.onDestroyView();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
|
|
|
if (disposables != null) disposables.dispose();
|
|
|
|
if (databaseSubscription != null) databaseSubscription.cancel();
|
|
|
|
|
|
|
|
disposables = null;
|
|
|
|
databaseSubscription = null;
|
|
|
|
localPlaylistManager = null;
|
|
|
|
|
|
|
|
super.onDestroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Fragment Views
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void initViews(View rootView, Bundle savedInstanceState) {
|
|
|
|
super.initViews(rootView, savedInstanceState);
|
|
|
|
|
|
|
|
itemsList = rootView.findViewById(R.id.items_list);
|
|
|
|
itemsList.setLayoutManager(new LinearLayoutManager(activity));
|
|
|
|
|
|
|
|
final View headerRootLayout = activity.getLayoutInflater()
|
|
|
|
.inflate(R.layout.bookmark_header, itemsList, false);
|
|
|
|
watchHistoryButton = headerRootLayout.findViewById(R.id.watchHistory);
|
|
|
|
mostWatchedButton = headerRootLayout.findViewById(R.id.mostWatched);
|
|
|
|
|
2018-01-28 07:14:38 +01:00
|
|
|
itemListAdapter.setHeader(headerRootLayout);
|
2018-01-17 06:12:03 +01:00
|
|
|
|
2018-01-28 07:14:38 +01:00
|
|
|
itemsList.setAdapter(itemListAdapter);
|
2018-01-17 06:12:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void initListeners() {
|
|
|
|
super.initListeners();
|
|
|
|
|
2018-01-29 03:26:19 +01:00
|
|
|
itemListAdapter.setSelectedListener(new OnLocalItemGesture<LocalItem>() {
|
2018-01-17 06:12:03 +01:00
|
|
|
@Override
|
2018-01-28 07:14:38 +01:00
|
|
|
public void selected(LocalItem selectedItem) {
|
2018-01-17 06:12:03 +01:00
|
|
|
// Requires the parent fragment to find holder for fragment replacement
|
2018-01-28 07:14:38 +01:00
|
|
|
if (selectedItem instanceof PlaylistMetadataEntry && getParentFragment() != null) {
|
|
|
|
final PlaylistMetadataEntry entry = ((PlaylistMetadataEntry) selectedItem);
|
2018-01-17 06:12:03 +01:00
|
|
|
NavigationHelper.openLocalPlaylistFragment(
|
2018-01-28 07:14:38 +01:00
|
|
|
getParentFragment().getFragmentManager(), entry.uid, entry.name);
|
2018-01-17 06:12:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2018-01-28 07:14:38 +01:00
|
|
|
public void held(LocalItem selectedItem) {
|
|
|
|
if (selectedItem instanceof PlaylistMetadataEntry) {
|
|
|
|
showDeleteDialog((PlaylistMetadataEntry) selectedItem);
|
2018-01-17 06:12:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
watchHistoryButton.setOnClickListener(view -> {
|
|
|
|
if (getParentFragment() != null) {
|
|
|
|
NavigationHelper.openWatchHistoryFragment(getParentFragment().getFragmentManager());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
mostWatchedButton.setOnClickListener(view -> {
|
|
|
|
if (getParentFragment() != null) {
|
|
|
|
NavigationHelper.openMostPlayedFragment(getParentFragment().getFragmentManager());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-01-28 07:14:38 +01:00
|
|
|
private void showDeleteDialog(final PlaylistMetadataEntry item) {
|
|
|
|
new AlertDialog.Builder(activity)
|
|
|
|
.setTitle(item.name)
|
|
|
|
.setMessage(R.string.delete_playlist_prompt)
|
|
|
|
.setCancelable(true)
|
|
|
|
.setPositiveButton(R.string.delete, (dialog, i) -> {
|
2018-01-29 08:01:06 +01:00
|
|
|
final Toast deleteSuccessful = Toast.makeText(getContext(),
|
|
|
|
R.string.playlist_delete_success, Toast.LENGTH_SHORT);
|
2018-01-28 07:14:38 +01:00
|
|
|
disposables.add(localPlaylistManager.deletePlaylist(item.uid)
|
2018-01-17 06:12:03 +01:00
|
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
|
|
.subscribe(ignored -> deleteSuccessful.show()));
|
2018-01-28 07:14:38 +01:00
|
|
|
})
|
|
|
|
.setNegativeButton(R.string.cancel, null)
|
|
|
|
.show();
|
2018-01-17 06:12:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private void resetFragment() {
|
|
|
|
if (disposables != null) disposables.clear();
|
2018-01-28 07:14:38 +01:00
|
|
|
if (itemListAdapter != null) itemListAdapter.clearStreamItemList();
|
2018-01-17 06:12:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Subscriptions Loader
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void startLoading(boolean forceLoad) {
|
|
|
|
super.startLoading(forceLoad);
|
|
|
|
resetFragment();
|
|
|
|
|
|
|
|
localPlaylistManager.getPlaylists()
|
|
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
|
|
.subscribe(getSubscriptionSubscriber());
|
|
|
|
}
|
|
|
|
|
|
|
|
private Subscriber<List<PlaylistMetadataEntry>> getSubscriptionSubscriber() {
|
|
|
|
return new Subscriber<List<PlaylistMetadataEntry>>() {
|
|
|
|
@Override
|
|
|
|
public void onSubscribe(Subscription s) {
|
|
|
|
showLoading();
|
|
|
|
if (databaseSubscription != null) databaseSubscription.cancel();
|
|
|
|
databaseSubscription = s;
|
|
|
|
databaseSubscription.request(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onNext(List<PlaylistMetadataEntry> subscriptions) {
|
|
|
|
handleResult(subscriptions);
|
|
|
|
if (databaseSubscription != null) databaseSubscription.request(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onError(Throwable exception) {
|
|
|
|
BookmarkFragment.this.onError(exception);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onComplete() {
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void handleResult(@NonNull List<PlaylistMetadataEntry> result) {
|
|
|
|
super.handleResult(result);
|
|
|
|
|
2018-01-28 07:14:38 +01:00
|
|
|
itemListAdapter.clearStreamItemList();
|
2018-01-17 06:12:03 +01:00
|
|
|
|
|
|
|
if (result.isEmpty()) {
|
|
|
|
showEmptyState();
|
|
|
|
} else {
|
2018-01-30 03:06:48 +01:00
|
|
|
itemListAdapter.addItems(infoItemsOf(result));
|
2018-01-17 06:12:03 +01:00
|
|
|
if (itemsListState != null) {
|
|
|
|
itemsList.getLayoutManager().onRestoreInstanceState(itemsListState);
|
|
|
|
itemsListState = null;
|
|
|
|
}
|
|
|
|
hideLoading();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-01-28 07:14:38 +01:00
|
|
|
private List<PlaylistMetadataEntry> infoItemsOf(List<PlaylistMetadataEntry> playlists) {
|
|
|
|
Collections.sort(playlists, (o1, o2) -> o1.name.compareToIgnoreCase(o2.name));
|
|
|
|
return playlists;
|
2018-01-17 06:12:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Contract
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void showLoading() {
|
|
|
|
super.showLoading();
|
|
|
|
animateView(itemsList, false, 100);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void hideLoading() {
|
|
|
|
super.hideLoading();
|
|
|
|
animateView(itemsList, true, 200);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void showEmptyState() {
|
|
|
|
super.showEmptyState();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Fragment Error Handling
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected boolean onError(Throwable exception) {
|
|
|
|
resetFragment();
|
|
|
|
if (super.onError(exception)) return true;
|
|
|
|
|
|
|
|
onUnrecoverableError(exception, UserAction.SOMETHING_ELSE,
|
|
|
|
"none", "Bookmark", R.string.general_error);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|