2018-01-28 07:14:38 +01:00
|
|
|
package org.schabi.newpipe.fragments.local.bookmark;
|
2018-01-17 06:12:03 +01:00
|
|
|
|
|
|
|
import android.app.Activity;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.DialogInterface;
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.os.Parcelable;
|
|
|
|
import android.support.annotation.NonNull;
|
|
|
|
import android.support.annotation.Nullable;
|
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
|
|
|
|
import org.reactivestreams.Subscriber;
|
|
|
|
import org.reactivestreams.Subscription;
|
|
|
|
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.stream.StreamStatisticsEntry;
|
|
|
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
2018-01-28 07:14:38 +01:00
|
|
|
import org.schabi.newpipe.fragments.local.BaseLocalListFragment;
|
2018-01-29 03:26:19 +01:00
|
|
|
import org.schabi.newpipe.fragments.local.OnLocalItemGesture;
|
2018-01-27 06:34:17 +01:00
|
|
|
import org.schabi.newpipe.history.HistoryRecordManager;
|
2018-01-17 06:12:03 +01:00
|
|
|
import org.schabi.newpipe.info_list.InfoItemDialog;
|
|
|
|
import org.schabi.newpipe.playlist.PlayQueue;
|
|
|
|
import org.schabi.newpipe.playlist.SinglePlayQueue;
|
|
|
|
import org.schabi.newpipe.report.UserAction;
|
|
|
|
import org.schabi.newpipe.util.NavigationHelper;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import icepick.State;
|
|
|
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
|
|
|
|
|
|
|
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
|
|
|
|
2018-01-17 23:32:09 +01:00
|
|
|
public abstract class StatisticsPlaylistFragment
|
2018-01-28 07:14:38 +01:00
|
|
|
extends BaseLocalListFragment<List<StreamStatisticsEntry>, Void> {
|
2018-01-17 06:12:03 +01:00
|
|
|
|
|
|
|
private View headerRootLayout;
|
|
|
|
private View playlistControl;
|
|
|
|
private View headerPlayAllButton;
|
|
|
|
private View headerPopupButton;
|
|
|
|
private View headerBackgroundButton;
|
|
|
|
|
|
|
|
@State
|
|
|
|
protected Parcelable itemsListState;
|
|
|
|
|
|
|
|
/* Used for independent events */
|
|
|
|
private Subscription databaseSubscription;
|
2018-01-27 06:34:17 +01:00
|
|
|
private HistoryRecordManager recordManager;
|
2018-01-17 06:12:03 +01:00
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Abstracts
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
protected abstract String getName();
|
|
|
|
|
2018-01-28 07:14:38 +01:00
|
|
|
protected abstract List<StreamStatisticsEntry> processResult(final List<StreamStatisticsEntry> results);
|
2018-01-17 06:12:03 +01:00
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Fragment LifeCycle
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onAttach(Context context) {
|
|
|
|
super.onAttach(context);
|
2018-01-27 06:34:17 +01:00
|
|
|
recordManager = new HistoryRecordManager(context);
|
2018-01-17 06:12:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
|
|
|
@Nullable ViewGroup container,
|
|
|
|
@Nullable Bundle savedInstanceState) {
|
|
|
|
return inflater.inflate(R.layout.fragment_playlist, container, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onPause() {
|
|
|
|
super.onPause();
|
|
|
|
itemsListState = itemsList.getLayoutManager().onSaveInstanceState();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroyView() {
|
|
|
|
if (databaseSubscription != null) databaseSubscription.cancel();
|
|
|
|
super.onDestroyView();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
|
|
|
if (databaseSubscription != null) databaseSubscription.cancel();
|
|
|
|
databaseSubscription = null;
|
|
|
|
recordManager = null;
|
|
|
|
|
|
|
|
super.onDestroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Fragment Views
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void initViews(View rootView, Bundle savedInstanceState) {
|
|
|
|
super.initViews(rootView, savedInstanceState);
|
|
|
|
setFragmentTitle(getName());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected View getListHeader() {
|
|
|
|
headerRootLayout = activity.getLayoutInflater().inflate(R.layout.playlist_control,
|
|
|
|
itemsList, false);
|
|
|
|
playlistControl = headerRootLayout.findViewById(R.id.playlist_control);
|
|
|
|
headerPlayAllButton = headerRootLayout.findViewById(R.id.playlist_ctrl_play_all_button);
|
|
|
|
headerPopupButton = headerRootLayout.findViewById(R.id.playlist_ctrl_play_popup_button);
|
|
|
|
headerBackgroundButton = headerRootLayout.findViewById(R.id.playlist_ctrl_play_bg_button);
|
|
|
|
|
|
|
|
return headerRootLayout;
|
|
|
|
}
|
|
|
|
|
|
|
|
@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) {
|
|
|
|
if (selectedItem instanceof StreamStatisticsEntry) {
|
|
|
|
final StreamStatisticsEntry item = (StreamStatisticsEntry) selectedItem;
|
|
|
|
NavigationHelper.openVideoDetailFragment(getFragmentManager(),
|
|
|
|
item.serviceId, item.url, item.title);
|
|
|
|
}
|
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 StreamStatisticsEntry) {
|
|
|
|
showStreamDialog((StreamStatisticsEntry) selectedItem);
|
|
|
|
}
|
2018-01-17 06:12:03 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-01-28 07:14:38 +01:00
|
|
|
private void showStreamDialog(final StreamStatisticsEntry item) {
|
2018-01-17 06:12:03 +01:00
|
|
|
final Context context = getContext();
|
|
|
|
final Activity activity = getActivity();
|
2018-01-28 07:14:38 +01:00
|
|
|
if (context == null || context.getResources() == null || getActivity() == null) return;
|
|
|
|
final StreamInfoItem infoItem = item.toStreamInfoItem();
|
2018-01-17 06:12:03 +01:00
|
|
|
|
|
|
|
final String[] commands = new String[]{
|
|
|
|
context.getResources().getString(R.string.enqueue_on_background),
|
|
|
|
context.getResources().getString(R.string.enqueue_on_popup),
|
|
|
|
context.getResources().getString(R.string.start_here_on_main),
|
|
|
|
context.getResources().getString(R.string.start_here_on_background),
|
|
|
|
context.getResources().getString(R.string.start_here_on_popup),
|
|
|
|
};
|
|
|
|
|
|
|
|
final DialogInterface.OnClickListener actions = (dialogInterface, i) -> {
|
2018-01-28 07:14:38 +01:00
|
|
|
final int index = Math.max(itemListAdapter.getItemsList().indexOf(item), 0);
|
2018-01-17 06:12:03 +01:00
|
|
|
switch (i) {
|
|
|
|
case 0:
|
2018-01-28 07:14:38 +01:00
|
|
|
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(infoItem));
|
2018-01-17 06:12:03 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
2018-01-28 07:14:38 +01:00
|
|
|
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(infoItem));
|
2018-01-17 06:12:03 +01:00
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
NavigationHelper.playOnMainPlayer(context, getPlayQueue(index));
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index));
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-01-28 07:14:38 +01:00
|
|
|
new InfoItemDialog(getActivity(), infoItem, commands, actions).show();
|
2018-01-17 06:12:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private void resetFragment() {
|
|
|
|
if (databaseSubscription != null) databaseSubscription.cancel();
|
2018-01-28 07:14:38 +01:00
|
|
|
if (itemListAdapter != null) itemListAdapter.clearStreamItemList();
|
2018-01-17 06:12:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Loader
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void showLoading() {
|
|
|
|
super.showLoading();
|
|
|
|
animateView(headerRootLayout, false, 200);
|
|
|
|
animateView(itemsList, false, 100);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void startLoading(boolean forceLoad) {
|
|
|
|
super.startLoading(forceLoad);
|
|
|
|
resetFragment();
|
|
|
|
|
2018-01-27 06:34:17 +01:00
|
|
|
recordManager.getStreamStatistics()
|
2018-01-17 06:12:03 +01:00
|
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
|
|
.subscribe(getHistoryObserver());
|
|
|
|
}
|
|
|
|
|
|
|
|
private Subscriber<List<StreamStatisticsEntry>> getHistoryObserver() {
|
|
|
|
return new Subscriber<List<StreamStatisticsEntry>>() {
|
|
|
|
@Override
|
|
|
|
public void onSubscribe(Subscription s) {
|
|
|
|
showLoading();
|
|
|
|
|
|
|
|
if (databaseSubscription != null) databaseSubscription.cancel();
|
|
|
|
databaseSubscription = s;
|
|
|
|
databaseSubscription.request(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onNext(List<StreamStatisticsEntry> streams) {
|
|
|
|
handleResult(streams);
|
|
|
|
if (databaseSubscription != null) databaseSubscription.request(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onError(Throwable exception) {
|
2018-01-17 23:32:09 +01:00
|
|
|
StatisticsPlaylistFragment.this.onError(exception);
|
2018-01-17 06:12:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onComplete() {
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void handleResult(@NonNull List<StreamStatisticsEntry> 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();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
animateView(headerRootLayout, true, 100);
|
|
|
|
animateView(itemsList, true, 300);
|
|
|
|
|
2018-01-28 07:14:38 +01:00
|
|
|
itemListAdapter.addInfoItemList(processResult(result));
|
2018-01-17 06:12:03 +01:00
|
|
|
if (itemsListState != null) {
|
|
|
|
itemsList.getLayoutManager().onRestoreInstanceState(itemsListState);
|
|
|
|
itemsListState = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
playlistControl.setVisibility(View.VISIBLE);
|
|
|
|
headerPlayAllButton.setOnClickListener(view ->
|
|
|
|
NavigationHelper.playOnMainPlayer(activity, getPlayQueue()));
|
|
|
|
headerPopupButton.setOnClickListener(view ->
|
|
|
|
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue()));
|
|
|
|
headerBackgroundButton.setOnClickListener(view ->
|
|
|
|
NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue()));
|
|
|
|
hideLoading();
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Fragment Error Handling
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected boolean onError(Throwable exception) {
|
|
|
|
resetFragment();
|
|
|
|
if (super.onError(exception)) return true;
|
|
|
|
|
|
|
|
onUnrecoverableError(exception, UserAction.SOMETHING_ELSE,
|
2018-01-29 08:01:06 +01:00
|
|
|
"none", "History Statistics", R.string.general_error);
|
2018-01-17 06:12:03 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Utils
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
|
|
|
protected void setFragmentTitle(final String title) {
|
|
|
|
if (activity.getSupportActionBar() != null) {
|
|
|
|
activity.getSupportActionBar().setTitle(title);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private PlayQueue getPlayQueue() {
|
|
|
|
return getPlayQueue(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
private PlayQueue getPlayQueue(final int index) {
|
2018-01-28 07:14:38 +01:00
|
|
|
final List<LocalItem> infoItems = itemListAdapter.getItemsList();
|
2018-01-17 06:12:03 +01:00
|
|
|
List<StreamInfoItem> streamInfoItems = new ArrayList<>(infoItems.size());
|
2018-01-28 07:14:38 +01:00
|
|
|
for (final LocalItem item : infoItems) {
|
|
|
|
if (item instanceof StreamStatisticsEntry) {
|
|
|
|
streamInfoItems.add(((StreamStatisticsEntry) item).toStreamInfoItem());
|
|
|
|
}
|
2018-01-17 06:12:03 +01:00
|
|
|
}
|
|
|
|
return new SinglePlayQueue(streamInfoItems, index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|