Merge remote-tracking branch 'origin/dev' into dev

pull/1371/head
Weblate 2018-04-30 14:42:49 +02:00
commit 2bfa165cdc
100 zmienionych plików z 528 dodań i 1223 usunięć

Wyświetl plik

@ -41,7 +41,7 @@ android {
}
ext {
supportLibVersion = '27.1.0'
supportLibVersion = '27.1.1'
exoPlayerLibVersion = '2.7.3'
roomDbLibVersion = '1.0.0'
leakCanaryLibVersion = '1.5.4'
@ -56,7 +56,6 @@ dependencies {
implementation 'com.github.TeamNewPipe:NewPipeExtractor:77a74b8'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:1.10.19'
@ -66,7 +65,6 @@ dependencies {
implementation "com.android.support:recyclerview-v7:$supportLibVersion"
implementation "com.android.support:preference-v14:$supportLibVersion"
implementation 'com.google.code.gson:gson:2.8.2'
implementation 'ch.acra:acra:4.9.2'
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'

Wyświetl plik

@ -80,8 +80,8 @@
android:name=".history.HistoryActivity"
android:label="@string/title_activity_history"/>
<service android:name=".subscription.services.SubscriptionsImportService"/>
<service android:name=".subscription.services.SubscriptionsExportService"/>
<service android:name=".local.subscription.services.SubscriptionsImportService"/>
<service android:name=".local.subscription.services.SubscriptionsExportService"/>
<activity
android:name=".PanicResponderActivity"

Wyświetl plik

@ -151,7 +151,8 @@ public class MainActivity extends AppCompatActivity {
settings.setOnClickListener(view -> NavigationHelper.openSettings(this));
downloads.setOnClickListener(view ->NavigationHelper.openDownloads(this));
history.setOnClickListener(view -> NavigationHelper.openHistory(this));
history.setOnClickListener(view ->
NavigationHelper.openStatisticFragment(getSupportFragmentManager()));
}
private void setupDrawerHeader() {
@ -327,16 +328,16 @@ public class MainActivity extends AppCompatActivity {
case android.R.id.home:
onHomeButtonPressed();
return true;
case R.id.action_settings:
NavigationHelper.openSettings(this);
return true;
case R.id.action_show_downloads:
return NavigationHelper.openDownloads(this);
case R.id.action_history:
NavigationHelper.openStatisticFragment(getSupportFragmentManager());
return true;
case R.id.action_about:
NavigationHelper.openAbout(this);
return true;
case R.id.action_history:
NavigationHelper.openHistory(this);
case R.id.action_settings:
NavigationHelper.openSettings(this);
return true;
default:
return super.onOptionsItemSelected(item);

Wyświetl plik

@ -32,10 +32,10 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.playlist.ChannelPlayQueue;
import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.playlist.PlaylistPlayQueue;
import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.player.playqueue.ChannelPlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.NavigationHelper;

Wyświetl plik

@ -32,7 +32,6 @@ public class AboutActivity extends AppCompatActivity {
new SoftwareComponent("Giga Get", "2014", "Peter Cai", "https://github.com/PaperAirplane-Dev-Team/GigaGet", StandardLicenses.GPL2),
new SoftwareComponent("NewPipe Extractor", "2017", "Christian Schabesberger", "https://github.com/TeamNewPipe/NewPipeExtractor", StandardLicenses.GPL3),
new SoftwareComponent("Jsoup", "2017", "Jonathan Hedley", "https://github.com/jhy/jsoup", StandardLicenses.MIT),
new SoftwareComponent("Google Gson", "2008", "Google Inc", "https://github.com/google/gson", StandardLicenses.APACHE2),
new SoftwareComponent("Rhino", "2015", "Mozilla", "https://www.mozilla.org/rhino/", StandardLicenses.MPL2),
new SoftwareComponent("ACRA", "2013", "Kevin Gaudin", "http://www.acra.ch", StandardLicenses.APACHE2),
new SoftwareComponent("Universal Image Loader", "2011 - 2015", "Sergey Tarasevich", "https://github.com/nostra13/Android-Universal-Image-Loader", StandardLicenses.APACHE2),

Wyświetl plik

@ -9,7 +9,7 @@ import android.arch.persistence.room.PrimaryKey;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.util.Constants;
import java.io.Serializable;

Wyświetl plik

@ -239,7 +239,8 @@ public abstract class BaseStateFragment<I> extends BaseFragment implements ViewC
if (rootView == null && getView() != null) rootView = getView();
if (rootView == null) return;
ErrorActivity.reportError(getContext(), exception, MainActivity.class, rootView, ErrorActivity.ErrorInfo.make(userAction, serviceName, request, errorId));
ErrorActivity.reportError(getContext(), exception, MainActivity.class, rootView,
ErrorActivity.ErrorInfo.make(userAction, serviceName, request, errorId));
}
/*//////////////////////////////////////////////////////////////////////////

Wyświetl plik

@ -27,10 +27,10 @@ import org.schabi.newpipe.extractor.ServiceList;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.kiosk.KioskList;
import org.schabi.newpipe.fragments.list.channel.ChannelFragment;
import org.schabi.newpipe.fragments.list.feed.FeedFragment;
import org.schabi.newpipe.local.feed.FeedFragment;
import org.schabi.newpipe.fragments.list.kiosk.KioskFragment;
import org.schabi.newpipe.fragments.local.bookmark.BookmarkFragment;
import org.schabi.newpipe.fragments.subscription.SubscriptionFragment;
import org.schabi.newpipe.local.bookmark.BookmarkFragment;
import org.schabi.newpipe.local.subscription.SubscriptionFragment;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.KioskTranslator;

Wyświetl plik

@ -64,15 +64,15 @@ import org.schabi.newpipe.fragments.BackPressable;
import org.schabi.newpipe.fragments.BaseStateFragment;
import org.schabi.newpipe.util.StreamItemAdapter;
import org.schabi.newpipe.util.StreamItemAdapter.StreamSizeWrapper;
import org.schabi.newpipe.fragments.local.dialog.PlaylistAppendDialog;
import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.info_list.InfoItemDialog;
import org.schabi.newpipe.player.MainVideoPlayer;
import org.schabi.newpipe.player.PopupVideoPlayer;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.player.old.PlayVideoActivity;
import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.ExtractorHelper;

Wyświetl plik

@ -20,10 +20,10 @@ import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.fragments.BaseStateFragment;
import org.schabi.newpipe.fragments.OnScrollBelowItemsListener;
import org.schabi.newpipe.fragments.local.dialog.PlaylistAppendDialog;
import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
import org.schabi.newpipe.info_list.InfoItemDialog;
import org.schabi.newpipe.info_list.InfoListAdapter;
import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.OnClickGesture;
import org.schabi.newpipe.util.StateSaver;
@ -140,9 +140,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
infoListAdapter.setOnStreamSelectedListener(new OnClickGesture<StreamInfoItem>() {
@Override
public void selected(StreamInfoItem selectedItem) {
onItemSelected(selectedItem);
NavigationHelper.openVideoDetailFragment(useAsFrontPage ? getParentFragment().getFragmentManager() : getFragmentManager(),
selectedItem.getServiceId(), selectedItem.getUrl(), selectedItem.getName());
onStreamSelected(selectedItem);
}
@Override
@ -178,6 +176,12 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
});
}
private void onStreamSelected(StreamInfoItem selectedItem) {
onItemSelected(selectedItem);
NavigationHelper.openVideoDetailFragment(useAsFrontPage ? getParentFragment().getFragmentManager() : getFragmentManager(),
selectedItem.getServiceId(), selectedItem.getUrl(), selectedItem.getName());
}
protected void onScrollToBottom() {
if (hasMoreItems() && !isLoading.get()) {
loadMoreItems();
@ -216,6 +220,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
new InfoItemDialog(getActivity(), item, commands, actions).show();
}
/*//////////////////////////////////////////////////////////////////////////
// Menu
//////////////////////////////////////////////////////////////////////////*/

Wyświetl plik

@ -32,17 +32,15 @@ import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.stream.Stream;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
import org.schabi.newpipe.fragments.local.dialog.PlaylistAppendDialog;
import org.schabi.newpipe.info_list.InfoItemDialog;
import org.schabi.newpipe.playlist.ChannelPlayQueue;
import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
import org.schabi.newpipe.player.playqueue.ChannelPlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.subscription.SubscriptionService;
import org.schabi.newpipe.local.subscription.SubscriptionService;
import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.ImageDisplayConstants;

Wyświetl plik

@ -27,14 +27,13 @@ import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
import org.schabi.newpipe.fragments.local.RemotePlaylistManager;
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
import org.schabi.newpipe.info_list.InfoItemDialog;
import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.playlist.PlaylistPlayQueue;
import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.ImageDisplayConstants;

Wyświetl plik

@ -41,7 +41,7 @@ import org.schabi.newpipe.extractor.search.SearchEngine;
import org.schabi.newpipe.extractor.search.SearchResult;
import org.schabi.newpipe.fragments.BackPressable;
import org.schabi.newpipe.fragments.list.BaseListFragment;
import org.schabi.newpipe.history.HistoryRecordManager;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.AnimationUtils;
@ -544,7 +544,7 @@ public class SearchFragment
howManyDeleted -> suggestionPublisher
.onNext(searchEditText.getText().toString()),
throwable -> showSnackBarError(throwable,
UserAction.SOMETHING_ELSE, "none",
UserAction.DELETE_FROM_HISTORY, "none",
"Deleting item failed", R.string.general_error)
);
disposables.add(onDelete);

Wyświetl plik

@ -63,24 +63,15 @@ public class SuggestionListAdapter extends RecyclerView.Adapter<SuggestionListAd
public void onBindViewHolder(SuggestionItemHolder holder, int position) {
final SuggestionItem currentItem = getItem(position);
holder.updateFrom(currentItem);
holder.queryView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) listener.onSuggestionItemSelected(currentItem);
}
holder.queryView.setOnClickListener(v -> {
if (listener != null) listener.onSuggestionItemSelected(currentItem);
});
holder.queryView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
holder.queryView.setOnLongClickListener(v -> {
if (listener != null) listener.onSuggestionItemLongClick(currentItem);
return true;
}
});
holder.insertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) listener.onSuggestionItemInserted(currentItem);
}
holder.insertView.setOnClickListener(v -> {
if (listener != null) listener.onSuggestionItemInserted(currentItem);
});
}

Wyświetl plik

@ -1,21 +0,0 @@
package org.schabi.newpipe.fragments.local.bookmark;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.stream.StreamStatisticsEntry;
import java.util.Collections;
import java.util.List;
public final class LastPlayedFragment extends StatisticsPlaylistFragment {
@Override
protected String getName() {
return getString(R.string.title_last_played);
}
@Override
protected List<StreamStatisticsEntry> processResult(List<StreamStatisticsEntry> results) {
Collections.sort(results, (left, right) ->
right.latestAccessDate.compareTo(left.latestAccessDate));
return results;
}
}

Wyświetl plik

@ -1,22 +0,0 @@
package org.schabi.newpipe.fragments.local.bookmark;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.stream.StreamStatisticsEntry;
import java.util.Collections;
import java.util.List;
public final class MostPlayedFragment extends StatisticsPlaylistFragment {
@Override
protected String getName() {
return getString(R.string.title_most_played);
}
@Override
protected List<StreamStatisticsEntry> processResult(List<StreamStatisticsEntry> results) {
Collections.sort(results, (left, right) ->
((Long) right.watchCount).compareTo(left.watchCount));
return results;
}
}

Wyświetl plik

@ -1,141 +0,0 @@
package org.schabi.newpipe.history;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import com.jakewharton.rxbinding2.view.RxView;
import org.schabi.newpipe.R;
import org.schabi.newpipe.settings.SettingsActivity;
import org.schabi.newpipe.util.ThemeHelper;
import io.reactivex.android.schedulers.AndroidSchedulers;
public class HistoryActivity extends AppCompatActivity {
private static final String TAG = "HistoryActivity";
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThemeHelper.setTheme(this);
setContentView(R.layout.activity_history);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(R.string.title_activity_history);
}
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
final FloatingActionButton fab = findViewById(R.id.fab);
RxView.clicks(fab)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(ignored -> {
int currentItem = mViewPager.getCurrentItem();
HistoryFragment fragment = (HistoryFragment) mSectionsPagerAdapter
.instantiateItem(mViewPager, currentItem);
fragment.onHistoryCleared();
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_history, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.action_settings:
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
Fragment fragment;
switch (position) {
case 0:
fragment = SearchHistoryFragment.newInstance();
break;
case 1:
fragment = WatchHistoryFragment.newInstance();
break;
default:
throw new IllegalArgumentException("position: " + position);
}
return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getString(R.string.title_history_search);
case 1:
return getString(R.string.title_history_view);
}
throw new IllegalArgumentException("position: " + position);
}
@Override
public int getCount() {
// Show 3 total pages.
return 2;
}
}
}

Wyświetl plik

@ -1,286 +0,0 @@
package org.schabi.newpipe.history;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Parcelable;
import android.preference.PreferenceManager;
import android.support.annotation.CallSuper;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import org.schabi.newpipe.BaseFragment;
import org.schabi.newpipe.R;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import icepick.State;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import static org.schabi.newpipe.util.AnimationUtils.animateView;
public abstract class HistoryFragment<E> extends BaseFragment
implements HistoryEntryAdapter.OnHistoryItemClickListener<E> {
private SharedPreferences mSharedPreferences;
private String mHistoryIsEnabledKey;
private boolean mHistoryIsEnabled;
private HistoryIsEnabledChangeListener mHistoryIsEnabledChangeListener;
private View mDisabledView;
private View mEmptyHistoryView;
@State
Parcelable mRecyclerViewState;
private RecyclerView mRecyclerView;
private HistoryEntryAdapter<E, ? extends RecyclerView.ViewHolder> mHistoryAdapter;
private Subscription historySubscription;
protected HistoryRecordManager historyRecordManager;
protected CompositeDisposable disposables;
@StringRes
abstract int getEnabledConfigKey();
@CallSuper
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHistoryIsEnabledKey = getString(getEnabledConfigKey());
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
// Read history enabled from preferences
mHistoryIsEnabled = isHistoryEnabled();
// Register history enabled listener
mSharedPreferences.registerOnSharedPreferenceChangeListener(mHistoryIsEnabledChangeListener);
historyRecordManager = new HistoryRecordManager(getContext());
disposables = new CompositeDisposable();
}
@NonNull
protected abstract HistoryEntryAdapter<E, ? extends RecyclerView.ViewHolder> createAdapter();
protected abstract Single<List<Long>> insert(final Collection<E> entries);
protected abstract Single<Integer> delete(final Collection<E> entries);
@NonNull
protected abstract Flowable<List<E>> getAll();
@Override
public void onResume() {
super.onResume();
getAll().observeOn(AndroidSchedulers.mainThread()).subscribe(getHistorySubscriber());
final boolean newEnabled = isHistoryEnabled();
if (newEnabled != mHistoryIsEnabled) {
onHistoryIsEnabledChanged(newEnabled);
}
}
@NonNull
private Subscriber<List<E>> getHistorySubscriber() {
return new Subscriber<List<E>>() {
@Override
public void onSubscribe(Subscription s) {
if (historySubscription != null) historySubscription.cancel();
historySubscription = s;
historySubscription.request(1);
}
@Override
public void onNext(List<E> entries) {
if (!entries.isEmpty()) {
mHistoryAdapter.setEntries(entries);
animateView(mEmptyHistoryView, false, 200);
if (mRecyclerViewState != null) {
mRecyclerView.getLayoutManager().onRestoreInstanceState(mRecyclerViewState);
mRecyclerViewState = null;
}
} else {
mHistoryAdapter.clear();
showEmptyHistory();
}
if (historySubscription != null) historySubscription.request(1);
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
}
};
}
private boolean isHistoryEnabled() {
return mSharedPreferences.getBoolean(mHistoryIsEnabledKey, false);
}
/**
* Called when the history is cleared to update the views
*/
@MainThread
public void onHistoryCleared() {
if (getContext() == null) return;
new AlertDialog.Builder(getContext())
.setTitle(R.string.delete_all)
.setMessage(R.string.delete_all_history_prompt)
.setCancelable(true)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.delete_all, (dialog, i) -> clearHistory())
.show();
}
protected void makeSnackbar(@StringRes final int text) {
if (getActivity() == null) return;
View view = getActivity().findViewById(R.id.main_content);
if (view == null) view = mRecyclerView.getRootView();
Snackbar.make(view, text, Snackbar.LENGTH_LONG).show();
}
private void clearHistory() {
final Collection<E> itemsToDelete = new ArrayList<>(mHistoryAdapter.getItems());
final Disposable deletion = delete(itemsToDelete)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
ignored -> Log.d(TAG, "Clear history deleted [" +
itemsToDelete.size() + "] items."),
error -> Log.e(TAG, "Clear history delete step failed", error)
);
final Disposable cleanUp = historyRecordManager.removeOrphanedRecords()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
ignored -> Log.d(TAG, "Clear history deleted orphaned stream records"),
error -> Log.e(TAG, "Clear history remove orphaned records failed", error)
);
disposables.addAll(deletion, cleanUp);
makeSnackbar(R.string.history_cleared);
mHistoryAdapter.clear();
showEmptyHistory();
}
private void showEmptyHistory() {
if (mHistoryIsEnabled) {
animateView(mEmptyHistoryView, true, 200);
}
}
@Nullable
@CallSuper
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_history, container, false);
mRecyclerView = rootView.findViewById(R.id.history_view);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext(),
LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(layoutManager);
mHistoryAdapter = createAdapter();
mHistoryAdapter.setOnHistoryItemClickListener(this);
mRecyclerView.setAdapter(mHistoryAdapter);
mDisabledView = rootView.findViewById(R.id.history_disabled_view);
mEmptyHistoryView = rootView.findViewById(R.id.history_empty);
if (mHistoryIsEnabled) {
mRecyclerView.setVisibility(View.VISIBLE);
} else {
mRecyclerView.setVisibility(View.GONE);
mDisabledView.setVisibility(View.VISIBLE);
}
return rootView;
}
@CallSuper
@Override
public void onDestroy() {
super.onDestroy();
if (disposables != null) disposables.dispose();
if (historySubscription != null) historySubscription.cancel();
mSharedPreferences.unregisterOnSharedPreferenceChangeListener(mHistoryIsEnabledChangeListener);
mSharedPreferences = null;
mHistoryIsEnabledChangeListener = null;
mHistoryIsEnabledKey = null;
historySubscription = null;
disposables = null;
}
@Override
public void onPause() {
super.onPause();
mRecyclerViewState = mRecyclerView.getLayoutManager().onSaveInstanceState();
}
/**
* Called when history enabled flag is changed.
*
* @param historyIsEnabled the new value
*/
@CallSuper
public void onHistoryIsEnabledChanged(boolean historyIsEnabled) {
mHistoryIsEnabled = historyIsEnabled;
if (historyIsEnabled) {
animateView(mRecyclerView, true, 300);
animateView(mDisabledView, false, 300);
if (mHistoryAdapter.isEmpty()) {
animateView(mEmptyHistoryView, true, 300);
}
} else {
animateView(mRecyclerView, false, 300);
animateView(mDisabledView, true, 300);
animateView(mEmptyHistoryView, false, 300);
}
}
private class HistoryIsEnabledChangeListener
implements SharedPreferences.OnSharedPreferenceChangeListener {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(mHistoryIsEnabledKey)) {
boolean enabled = sharedPreferences.getBoolean(key, false);
if (mHistoryIsEnabled != enabled) {
onHistoryIsEnabledChanged(enabled);
}
}
}
}
}

Wyświetl plik

@ -1,145 +0,0 @@
package org.schabi.newpipe.history;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.history.model.SearchHistoryEntry;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
public class SearchHistoryFragment extends HistoryFragment<SearchHistoryEntry> {
@NonNull
public static SearchHistoryFragment newInstance() {
return new SearchHistoryFragment();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@NonNull
@Override
protected SearchHistoryAdapter createAdapter() {
return new SearchHistoryAdapter(getContext());
}
@Override
protected Single<List<Long>> insert(Collection<SearchHistoryEntry> entries) {
return historyRecordManager.insertSearches(entries);
}
@Override
protected Single<Integer> delete(Collection<SearchHistoryEntry> entries) {
return historyRecordManager.deleteSearches(entries);
}
@NonNull
@Override
protected Flowable<List<SearchHistoryEntry>> getAll() {
return historyRecordManager.getSearchHistory();
}
@StringRes
@Override
int getEnabledConfigKey() {
return R.string.enable_search_history_key;
}
@Override
public void onHistoryItemClick(final SearchHistoryEntry historyItem) {
NavigationHelper.openSearch(getContext(), historyItem.getServiceId(),
historyItem.getSearch());
}
@Override
public void onHistoryItemLongClick(final SearchHistoryEntry item) {
if (activity == null) return;
new AlertDialog.Builder(activity)
.setTitle(item.getSearch())
.setMessage(R.string.delete_item_search_history)
.setCancelable(true)
.setNeutralButton(R.string.cancel, null)
.setPositiveButton(R.string.delete_one, (dialog, i) -> {
final Disposable onDelete = historyRecordManager
.deleteSearches(Collections.singleton(item))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
ignored -> {/*successful*/},
error -> Log.e(TAG, "Search history Delete One failed:", error)
);
disposables.add(onDelete);
makeSnackbar(R.string.item_deleted);
})
.setNegativeButton(R.string.delete_all, (dialog, i) -> {
final Disposable onDeleteAll = historyRecordManager
.deleteSearchHistory(item.getSearch())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
ignored -> {/*successful*/},
error -> Log.e(TAG, "Search history Delete All failed:", error)
);
disposables.add(onDeleteAll);
makeSnackbar(R.string.item_deleted);
})
.show();
}
private static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView search;
private final TextView info;
public ViewHolder(View itemView) {
super(itemView);
search = itemView.findViewById(R.id.search);
info = itemView.findViewById(R.id.info);
}
}
protected class SearchHistoryAdapter extends HistoryEntryAdapter<SearchHistoryEntry, ViewHolder> {
SearchHistoryAdapter(Context context) {
super(context);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View rootView = inflater.inflate(R.layout.item_search_history, parent, false);
return new ViewHolder(rootView);
}
@Override
void onBindViewHolder(ViewHolder holder, SearchHistoryEntry entry, int position) {
holder.search.setText(entry.getSearch());
final String info = Localization.concatenateStrings(
getFormattedDate(entry.getCreationDate()),
NewPipe.getNameOfService(entry.getServiceId()));
holder.info.setText(info);
}
}
}

Wyświetl plik

@ -1,171 +0,0 @@
package org.schabi.newpipe.history;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.nostra13.universalimageloader.core.ImageLoader;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.history.model.StreamHistoryEntry;
import org.schabi.newpipe.info_list.holder.StreamInfoItemHolder;
import org.schabi.newpipe.util.ImageDisplayConstants;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
public class WatchHistoryFragment extends HistoryFragment<StreamHistoryEntry> {
@NonNull
public static WatchHistoryFragment newInstance() {
return new WatchHistoryFragment();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@StringRes
@Override
int getEnabledConfigKey() {
return R.string.enable_watch_history_key;
}
@NonNull
@Override
protected StreamHistoryAdapter createAdapter() {
return new StreamHistoryAdapter(getContext());
}
@Override
protected Single<List<Long>> insert(Collection<StreamHistoryEntry> entries) {
return historyRecordManager.insertStreamHistory(entries);
}
@Override
protected Single<Integer> delete(Collection<StreamHistoryEntry> entries) {
return historyRecordManager.deleteStreamHistory(entries);
}
@NonNull
@Override
protected Flowable<List<StreamHistoryEntry>> getAll() {
return historyRecordManager.getStreamHistory();
}
@Override
public void onHistoryItemClick(StreamHistoryEntry historyItem) {
NavigationHelper.openVideoDetail(getContext(), historyItem.serviceId, historyItem.url,
historyItem.title);
}
@Override
public void onHistoryItemLongClick(StreamHistoryEntry item) {
new AlertDialog.Builder(activity)
.setTitle(item.title)
.setMessage(R.string.delete_stream_history_prompt)
.setCancelable(true)
.setNeutralButton(R.string.cancel, null)
.setPositiveButton(R.string.delete_one, (dialog, i) -> {
final Disposable onDelete = historyRecordManager
.deleteStreamHistory(Collections.singleton(item))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
ignored -> {/*successful*/},
error -> Log.e(TAG, "Watch history Delete One failed:", error)
);
disposables.add(onDelete);
makeSnackbar(R.string.item_deleted);
})
.setNegativeButton(R.string.delete_all, (dialog, i) -> {
final Disposable onDeleteAll = historyRecordManager
.deleteStreamHistory(item.streamId)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
ignored -> {/*successful*/},
error -> Log.e(TAG, "Watch history Delete All failed:", error)
);
disposables.add(onDeleteAll);
makeSnackbar(R.string.item_deleted);
})
.show();
}
private static class StreamHistoryAdapter extends HistoryEntryAdapter<StreamHistoryEntry, ViewHolder> {
StreamHistoryAdapter(Context context) {
super(context);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(R.layout.list_stream_item, parent, false);
return new ViewHolder(itemView);
}
@Override
public void onViewRecycled(ViewHolder holder) {
holder.itemView.setOnClickListener(null);
ImageLoader.getInstance()
.cancelDisplayTask(holder.thumbnailView);
}
@Override
void onBindViewHolder(ViewHolder holder, StreamHistoryEntry entry, int position) {
final String formattedDate = getFormattedDate(entry.accessDate);
final String info;
if (entry.repeatCount > 1) {
info = Localization.concatenateStrings(formattedDate,
getFormattedViewString(entry.repeatCount));
} else {
info = formattedDate;
}
holder.info.setText(info);
holder.streamTitle.setText(entry.title);
holder.uploader.setText(entry.uploader);
holder.duration.setText(Localization.getDurationString(entry.duration));
ImageLoader.getInstance().displayImage(entry.thumbnailUrl, holder.thumbnailView,
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS);
}
}
private static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView info;
private final TextView streamTitle;
private final ImageView thumbnailView;
private final TextView uploader;
private final TextView duration;
public ViewHolder(View itemView) {
super(itemView);
thumbnailView = itemView.findViewById(R.id.itemThumbnailView);
info = itemView.findViewById(R.id.itemAdditionalDetails);
streamTitle = itemView.findViewById(R.id.itemVideoTitleView);
uploader = itemView.findViewById(R.id.itemUploaderView);
duration = itemView.findViewById(R.id.itemDurationView);
}
}
}

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local.bookmark;
package org.schabi.newpipe.local;
import android.os.Bundle;
import android.support.v4.app.Fragment;
@ -13,7 +13,6 @@ import android.view.View;
import org.schabi.newpipe.R;
import org.schabi.newpipe.fragments.BaseStateFragment;
import org.schabi.newpipe.fragments.list.ListViewContract;
import org.schabi.newpipe.fragments.local.LocalItemListAdapter;
import static org.schabi.newpipe.util.AnimationUtils.animateView;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local;
package org.schabi.newpipe.local;
import android.support.v7.widget.RecyclerView;
import android.view.View;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local;
package org.schabi.newpipe.local;
import android.content.Context;
import android.widget.ImageView;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local;
package org.schabi.newpipe.local;
import android.app.Activity;
import android.support.v7.widget.RecyclerView;
@ -7,11 +7,13 @@ import android.view.View;
import android.view.ViewGroup;
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.fragments.local.holder.LocalItemHolder;
import org.schabi.newpipe.fragments.local.holder.LocalPlaylistItemHolder;
import org.schabi.newpipe.fragments.local.holder.LocalPlaylistStreamItemHolder;
import org.schabi.newpipe.fragments.local.holder.LocalStatisticStreamItemHolder;
import org.schabi.newpipe.fragments.local.holder.RemotePlaylistItemHolder;
import org.schabi.newpipe.local.HeaderFooterHolder;
import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.local.holder.LocalItemHolder;
import org.schabi.newpipe.local.holder.LocalPlaylistItemHolder;
import org.schabi.newpipe.local.holder.LocalPlaylistStreamItemHolder;
import org.schabi.newpipe.local.holder.LocalStatisticStreamItemHolder;
import org.schabi.newpipe.local.holder.RemotePlaylistItemHolder;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.OnClickGesture;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local.bookmark;
package org.schabi.newpipe.local.bookmark;
import android.app.AlertDialog;
import android.os.Bundle;
@ -19,8 +19,9 @@ import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.playlist.PlaylistLocalItem;
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity;
import org.schabi.newpipe.fragments.local.LocalPlaylistManager;
import org.schabi.newpipe.fragments.local.RemotePlaylistManager;
import org.schabi.newpipe.local.BaseLocalListFragment;
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.OnClickGesture;
@ -38,9 +39,6 @@ import io.reactivex.disposables.CompositeDisposable;
public final class BookmarkFragment
extends BaseLocalListFragment<List<PlaylistLocalItem>, Void> {
private View lastPlayedButton;
private View mostPlayedButton;
@State
protected Parcelable itemsListState;
@ -94,15 +92,6 @@ public final class BookmarkFragment
super.initViews(rootView, savedInstanceState);
}
@Override
protected View getListHeader() {
final View headerRootLayout = activity.getLayoutInflater()
.inflate(R.layout.bookmark_header, itemsList, false);
lastPlayedButton = headerRootLayout.findViewById(R.id.lastPlayed);
mostPlayedButton = headerRootLayout.findViewById(R.id.mostPlayed);
return headerRootLayout;
}
@Override
protected void initListeners() {
super.initListeners();
@ -136,18 +125,6 @@ public final class BookmarkFragment
}
}
});
lastPlayedButton.setOnClickListener(view -> {
if (getParentFragment() != null) {
NavigationHelper.openLastPlayedFragment(getParentFragment().getFragmentManager());
}
});
mostPlayedButton.setOnClickListener(view -> {
if (getParentFragment() != null) {
NavigationHelper.openMostPlayedFragment(getParentFragment().getFragmentManager());
}
});
}
///////////////////////////////////////////////////////////////////////////
@ -180,8 +157,6 @@ public final class BookmarkFragment
@Override
public void onDestroyView() {
super.onDestroyView();
if (mostPlayedButton != null) mostPlayedButton.setOnClickListener(null);
if (lastPlayedButton != null) lastPlayedButton.setOnClickListener(null);
if (disposables != null) disposables.clear();
if (databaseSubscription != null) databaseSubscription.cancel();

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local.dialog;
package org.schabi.newpipe.local.dialog;
import android.annotation.SuppressLint;
import android.os.Bundle;
@ -18,9 +18,9 @@ import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.fragments.local.LocalItemListAdapter;
import org.schabi.newpipe.fragments.local.LocalPlaylistManager;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.local.LocalItemListAdapter;
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.util.OnClickGesture;
import java.util.ArrayList;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local.dialog;
package org.schabi.newpipe.local.dialog;
import android.app.AlertDialog;
import android.app.Dialog;
@ -12,7 +12,7 @@ import android.widget.Toast;
import org.schabi.newpipe.NewPipeDatabase;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.fragments.local.LocalPlaylistManager;
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
import java.util.List;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local.dialog;
package org.schabi.newpipe.local.dialog;
import android.os.Bundle;
import android.support.annotation.NonNull;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.list.feed;
package org.schabi.newpipe.local.feed;
import android.os.Bundle;
import android.os.Handler;
@ -22,7 +22,7 @@ import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.fragments.list.BaseListFragment;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.subscription.SubscriptionService;
import org.schabi.newpipe.local.subscription.SubscriptionService;
import java.util.Collections;
import java.util.HashSet;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.history;
package org.schabi.newpipe.local.history;
import android.content.Context;
import android.content.res.Resources;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.history;
package org.schabi.newpipe.local.history;
import android.support.annotation.Nullable;

Wyświetl plik

@ -1,4 +1,22 @@
package org.schabi.newpipe.history;
package org.schabi.newpipe.local.history;
/*
* Copyright (C) Mauricio Colli 2018
* HistoryRecordManager.java is part of NewPipe.
*
* NewPipe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NewPipe is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/
import android.content.Context;
import android.content.SharedPreferences;
@ -27,6 +45,7 @@ import java.util.List;
import io.reactivex.Flowable;
import io.reactivex.Maybe;
import io.reactivex.Scheduler;
import io.reactivex.Single;
import io.reactivex.schedulers.Schedulers;
@ -80,6 +99,11 @@ public class HistoryRecordManager {
.subscribeOn(Schedulers.io());
}
public Single<Integer> deleteWholeStreamHistory() {
return Single.fromCallable(() -> streamHistoryTable.deleteAll())
.subscribeOn(Schedulers.io());
}
public Flowable<List<StreamHistoryEntry>> getStreamHistory() {
return streamHistoryTable.getHistory().subscribeOn(Schedulers.io());
}
@ -114,20 +138,6 @@ public class HistoryRecordManager {
// Search History
///////////////////////////////////////////////////////
public Single<List<Long>> insertSearches(final Collection<SearchHistoryEntry> entries) {
return Single.fromCallable(() -> searchHistoryTable.insertAll(entries))
.subscribeOn(Schedulers.io());
}
public Single<Integer> deleteSearches(final Collection<SearchHistoryEntry> entries) {
return Single.fromCallable(() -> searchHistoryTable.delete(entries))
.subscribeOn(Schedulers.io());
}
public Flowable<List<SearchHistoryEntry>> getSearchHistory() {
return searchHistoryTable.getAll();
}
public Maybe<Long> onSearched(final int serviceId, final String search) {
if (!isSearchHistoryEnabled()) return Maybe.empty();
@ -150,6 +160,11 @@ public class HistoryRecordManager {
.subscribeOn(Schedulers.io());
}
public Single<Integer> deleteWholeSearchHistory() {
return Single.fromCallable(() -> searchHistoryTable.deleteAll())
.subscribeOn(Schedulers.io());
}
public Flowable<List<SearchHistoryEntry>> getRelatedSearches(final String query,
final int similarQueryLimit,
final int uniqueQueryLimit) {

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local.bookmark;
package org.schabi.newpipe.local.history;
import android.app.Activity;
import android.content.Context;
@ -7,9 +7,13 @@ import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
@ -17,13 +21,14 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.stream.StreamStatisticsEntry;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.history.HistoryRecordManager;
import org.schabi.newpipe.local.BaseLocalListFragment;
import org.schabi.newpipe.info_list.InfoItemDialog;
import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.OnClickGesture;
import org.schabi.newpipe.util.ThemeHelper;
import java.util.ArrayList;
import java.util.Collections;
@ -31,13 +36,19 @@ import java.util.List;
import icepick.State;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
public abstract class StatisticsPlaylistFragment
public class StatisticsPlaylistFragment
extends BaseLocalListFragment<List<StreamStatisticsEntry>, Void> {
private View headerPlayAllButton;
private View headerPopupButton;
private View headerBackgroundButton;
private View playlistCtrl;
private View sortButton;
private ImageView sortButtonIcon;
private TextView sortButtonText;
@State
protected Parcelable itemsListState;
@ -45,14 +56,28 @@ public abstract class StatisticsPlaylistFragment
/* Used for independent events */
private Subscription databaseSubscription;
private HistoryRecordManager recordManager;
private CompositeDisposable disposables = new CompositeDisposable();
///////////////////////////////////////////////////////////////////////////
// Abstracts
///////////////////////////////////////////////////////////////////////////
private enum StatisticSortMode {
LAST_PLAYED,
MOST_PLAYED,
}
protected abstract String getName();
StatisticSortMode sortMode = StatisticSortMode.LAST_PLAYED;
protected abstract List<StreamStatisticsEntry> processResult(final List<StreamStatisticsEntry> results);
protected List<StreamStatisticsEntry> processResult(final List<StreamStatisticsEntry> results) {
switch (sortMode) {
case LAST_PLAYED:
Collections.sort(results, (left, right) ->
right.latestAccessDate.compareTo(left.latestAccessDate));
return results;
case MOST_PLAYED:
Collections.sort(results, (left, right) ->
((Long) right.watchCount).compareTo(left.watchCount));
return results;
default: return null;
}
}
///////////////////////////////////////////////////////////////////////////
// Fragment LifeCycle - Creation
@ -78,16 +103,20 @@ public abstract class StatisticsPlaylistFragment
@Override
protected void initViews(View rootView, Bundle savedInstanceState) {
super.initViews(rootView, savedInstanceState);
setTitle(getName());
setTitle(getString(R.string.title_last_played));
}
@Override
protected View getListHeader() {
final View headerRootLayout = activity.getLayoutInflater().inflate(R.layout.playlist_control,
final View headerRootLayout = activity.getLayoutInflater().inflate(R.layout.statistic_playlist_control,
itemsList, false);
playlistCtrl = 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);
sortButton = headerRootLayout.findViewById(R.id.sortButton);
sortButtonIcon = headerRootLayout.findViewById(R.id.sortButtonIcon);
sortButtonText = headerRootLayout.findViewById(R.id.sortButtonText);
return headerRootLayout;
}
@ -193,6 +222,8 @@ public abstract class StatisticsPlaylistFragment
super.handleResult(result);
if (itemListAdapter == null) return;
playlistCtrl.setVisibility(View.VISIBLE);
itemListAdapter.clearStreamItemList();
if (result.isEmpty()) {
@ -212,6 +243,7 @@ public abstract class StatisticsPlaylistFragment
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue()));
headerBackgroundButton.setOnClickListener(view ->
NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue()));
sortButton.setOnClickListener(view -> toggleSortMode());
hideLoading();
}
@ -238,6 +270,21 @@ public abstract class StatisticsPlaylistFragment
// Utils
//////////////////////////////////////////////////////////////////////////*/
private void toggleSortMode() {
if(sortMode == StatisticSortMode.LAST_PLAYED) {
sortMode = StatisticSortMode.MOST_PLAYED;
setTitle(getString(R.string.title_most_played));
sortButtonIcon.setImageResource(ThemeHelper.getIconByAttr(R.attr.history, getContext()));
sortButtonText.setText(R.string.title_last_played);
} else {
sortMode = StatisticSortMode.LAST_PLAYED;
setTitle(getString(R.string.title_last_played));
sortButtonIcon.setImageResource(ThemeHelper.getIconByAttr(R.attr.filter, getContext()));
sortButtonText.setText(R.string.title_most_played);
}
startLoading(true);
}
private void showStreamDialog(final StreamStatisticsEntry item) {
final Context context = getContext();
final Activity activity = getActivity();
@ -250,6 +297,7 @@ public abstract class StatisticsPlaylistFragment
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),
context.getResources().getString(R.string.delete),
};
final DialogInterface.OnClickListener actions = (dialogInterface, i) -> {
@ -270,6 +318,9 @@ public abstract class StatisticsPlaylistFragment
case 4:
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index));
break;
case 5:
deleteEntry(index);
break;
default:
break;
}
@ -278,6 +329,32 @@ public abstract class StatisticsPlaylistFragment
new InfoItemDialog(getActivity(), infoItem, commands, actions).show();
}
private void deleteEntry(final int index) {
final LocalItem infoItem = itemListAdapter.getItemsList()
.get(index);
if(infoItem instanceof StreamStatisticsEntry) {
final StreamStatisticsEntry entry = (StreamStatisticsEntry) infoItem;
final Disposable onDelete = recordManager.deleteStreamHistory(entry.streamId)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
howManyDelted -> {
if(getView() != null) {
Snackbar.make(getView(), R.string.one_item_deleted,
Snackbar.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(),
R.string.one_item_deleted,
Toast.LENGTH_SHORT).show();
}
},
throwable -> showSnackBarError(throwable,
UserAction.DELETE_FROM_HISTORY, "none",
"Deleting item failed", R.string.general_error));
disposables.add(onDelete);
}
}
private PlayQueue getPlayQueue() {
return getPlayQueue(0);
}

Wyświetl plik

@ -1,11 +1,11 @@
package org.schabi.newpipe.fragments.local.holder;
package org.schabi.newpipe.local.holder;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.fragments.local.LocalItemBuilder;
import org.schabi.newpipe.local.LocalItemBuilder;
import java.text.DateFormat;

Wyświetl plik

@ -1,11 +1,11 @@
package org.schabi.newpipe.fragments.local.holder;
package org.schabi.newpipe.local.holder;
import android.view.View;
import android.view.ViewGroup;
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
import org.schabi.newpipe.fragments.local.LocalItemBuilder;
import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.util.ImageDisplayConstants;
import java.text.DateFormat;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local.holder;
package org.schabi.newpipe.local.holder;
import android.support.v4.content.ContextCompat;
import android.view.MotionEvent;
@ -11,7 +11,7 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.playlist.PlaylistStreamEntry;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.fragments.local.LocalItemBuilder;
import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.util.ImageDisplayConstants;
import org.schabi.newpipe.util.Localization;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local.holder;
package org.schabi.newpipe.local.holder;
import android.support.v4.content.ContextCompat;
import android.view.View;
@ -10,7 +10,7 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.stream.StreamStatisticsEntry;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.fragments.local.LocalItemBuilder;
import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.util.ImageDisplayConstants;
import org.schabi.newpipe.util.Localization;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local.holder;
package org.schabi.newpipe.local.holder;
import android.view.ViewGroup;
import android.widget.ImageView;
@ -6,7 +6,7 @@ import android.widget.TextView;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.fragments.local.LocalItemBuilder;
import org.schabi.newpipe.local.LocalItemBuilder;
import java.text.DateFormat;

Wyświetl plik

@ -1,11 +1,11 @@
package org.schabi.newpipe.fragments.local.holder;
package org.schabi.newpipe.local.holder;
import android.view.ViewGroup;
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.fragments.local.LocalItemBuilder;
import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.util.ImageDisplayConstants;
import org.schabi.newpipe.util.Localization;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local.bookmark;
package org.schabi.newpipe.local.playlist;
import android.app.Activity;
import android.content.Context;
@ -26,10 +26,10 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.playlist.PlaylistStreamEntry;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.fragments.local.LocalPlaylistManager;
import org.schabi.newpipe.local.BaseLocalListFragment;
import org.schabi.newpipe.info_list.InfoItemDialog;
import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
@ -173,7 +173,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
@Override
public void held(LocalItem selectedItem) {
if (selectedItem instanceof PlaylistStreamEntry) {
showStreamDialog((PlaylistStreamEntry) selectedItem);
showStreamItemDialog((PlaylistStreamEntry) selectedItem);
}
}
@ -506,7 +506,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
// Utils
//////////////////////////////////////////////////////////////////////////*/
protected void showStreamDialog(final PlaylistStreamEntry item) {
protected void showStreamItemDialog(final PlaylistStreamEntry item) {
final Context context = getContext();
final Activity activity = getActivity();
if (context == null || context.getResources() == null || getActivity() == null) return;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local;
package org.schabi.newpipe.local.playlist;
import android.support.annotation.Nullable;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.local;
package org.schabi.newpipe.local.playlist;
import org.schabi.newpipe.database.AppDatabase;
import org.schabi.newpipe.database.playlist.dao.PlaylistRemoteDAO;
@ -13,11 +13,9 @@ import io.reactivex.schedulers.Schedulers;
public class RemotePlaylistManager {
private final AppDatabase database;
private final PlaylistRemoteDAO playlistRemoteTable;
public RemotePlaylistManager(final AppDatabase db) {
database = db;
playlistRemoteTable = db.playlistRemoteDAO();
}

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.subscription;
package org.schabi.newpipe.local.subscription;
import android.app.AlertDialog;
import android.app.Dialog;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.subscription;
package org.schabi.newpipe.local.subscription;
public interface ImportExportEventListener {
/**

Wyświetl plik

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.schabi.newpipe.subscription;
package org.schabi.newpipe.local.subscription;
import android.support.annotation.Nullable;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.subscription;
package org.schabi.newpipe.local.subscription;
import android.app.Activity;
import android.content.BroadcastReceiver;
@ -39,9 +39,8 @@ import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
import org.schabi.newpipe.fragments.BaseStateFragment;
import org.schabi.newpipe.info_list.InfoListAdapter;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.subscription.SubscriptionService;
import org.schabi.newpipe.subscription.services.SubscriptionsExportService;
import org.schabi.newpipe.subscription.services.SubscriptionsImportService;
import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService;
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService;
import org.schabi.newpipe.util.FilePickerActivityHelper;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.OnClickGesture;
@ -53,7 +52,6 @@ import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;
@ -65,9 +63,9 @@ import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import static org.schabi.newpipe.subscription.services.SubscriptionsImportService.KEY_MODE;
import static org.schabi.newpipe.subscription.services.SubscriptionsImportService.KEY_VALUE;
import static org.schabi.newpipe.subscription.services.SubscriptionsImportService.PREVIOUS_EXPORT_MODE;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_MODE;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_VALUE;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.PREVIOUS_EXPORT_MODE;
import static org.schabi.newpipe.util.AnimationUtils.animateRotation;
import static org.schabi.newpipe.util.AnimationUtils.animateView;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.subscription;
package org.schabi.newpipe.local.subscription;
import android.content.Context;
import android.support.annotation.NonNull;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.fragments.subscription;
package org.schabi.newpipe.local.subscription;
import android.app.Activity;
import android.content.Intent;
@ -26,7 +26,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.subscription.services.SubscriptionsImportService;
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.FilePickerActivityHelper;
import org.schabi.newpipe.util.ServiceHelper;
@ -37,10 +37,10 @@ import java.util.List;
import icepick.State;
import static org.schabi.newpipe.extractor.subscription.SubscriptionExtractor.ContentSource.CHANNEL_URL;
import static org.schabi.newpipe.subscription.services.SubscriptionsImportService.CHANNEL_URL_MODE;
import static org.schabi.newpipe.subscription.services.SubscriptionsImportService.INPUT_STREAM_MODE;
import static org.schabi.newpipe.subscription.services.SubscriptionsImportService.KEY_MODE;
import static org.schabi.newpipe.subscription.services.SubscriptionsImportService.KEY_VALUE;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.CHANNEL_URL_MODE;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.INPUT_STREAM_MODE;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_MODE;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_VALUE;
public class SubscriptionsImportFragment extends BaseFragment {
private static final int REQUEST_IMPORT_FILE_CODE = 666;

Wyświetl plik

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.schabi.newpipe.subscription.services;
package org.schabi.newpipe.local.subscription.services;
import android.app.Service;
import android.content.Intent;
@ -36,8 +36,8 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.subscription.ImportExportEventListener;
import org.schabi.newpipe.subscription.SubscriptionService;
import org.schabi.newpipe.local.subscription.ImportExportEventListener;
import org.schabi.newpipe.local.subscription.SubscriptionService;
import java.io.FileNotFoundException;
import java.io.IOException;

Wyświetl plik

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.schabi.newpipe.subscription.services;
package org.schabi.newpipe.local.subscription.services;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
@ -29,7 +29,7 @@ import org.reactivestreams.Subscription;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
import org.schabi.newpipe.extractor.subscription.SubscriptionItem;
import org.schabi.newpipe.subscription.ImportExportJsonHelper;
import org.schabi.newpipe.local.subscription.ImportExportJsonHelper;
import java.io.File;
import java.io.FileNotFoundException;
@ -49,7 +49,7 @@ public class SubscriptionsExportService extends BaseImportExportService {
/**
* A {@link LocalBroadcastManager local broadcast} will be made with this action when the export is successfully completed.
*/
public static final String EXPORT_COMPLETE_ACTION = "org.schabi.newpipe.subscription.services.SubscriptionsExportService.EXPORT_COMPLETE";
public static final String EXPORT_COMPLETE_ACTION = "org.schabi.newpipe.local.subscription.services.SubscriptionsExportService.EXPORT_COMPLETE";
private Subscription subscription;
private File outFile;

Wyświetl plik

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.schabi.newpipe.subscription.services;
package org.schabi.newpipe.local.subscription.services;
import android.content.Intent;
import android.support.annotation.NonNull;
@ -33,7 +33,7 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.subscription.SubscriptionItem;
import org.schabi.newpipe.subscription.ImportExportJsonHelper;
import org.schabi.newpipe.local.subscription.ImportExportJsonHelper;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.ExtractorHelper;
@ -64,7 +64,7 @@ public class SubscriptionsImportService extends BaseImportExportService {
/**
* A {@link LocalBroadcastManager local broadcast} will be made with this action when the import is successfully completed.
*/
public static final String IMPORT_COMPLETE_ACTION = "org.schabi.newpipe.subscription.services.SubscriptionsImportService.IMPORT_COMPLETE";
public static final String IMPORT_COMPLETE_ACTION = "org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.IMPORT_COMPLETE";
private Subscription subscription;
private int currentMode;

Wyświetl plik

@ -48,7 +48,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.player.event.PlayerEventListener;
import org.schabi.newpipe.player.helper.LockManager;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ThemeHelper;

Wyświetl plik

@ -58,7 +58,7 @@ import org.schabi.newpipe.Downloader;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.history.HistoryRecordManager;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.player.helper.AudioReactor;
import org.schabi.newpipe.player.helper.LoadController;
import org.schabi.newpipe.player.helper.MediaSessionManager;
@ -69,9 +69,9 @@ import org.schabi.newpipe.player.playback.BasePlayerMediaSession;
import org.schabi.newpipe.player.playback.CustomTrackSelector;
import org.schabi.newpipe.player.playback.MediaSourceManager;
import org.schabi.newpipe.player.playback.PlaybackListener;
import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.playlist.PlayQueueAdapter;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueueAdapter;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.util.SerializedCache;
import java.io.IOException;

Wyświetl plik

@ -62,10 +62,10 @@ import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.fragments.OnScrollBelowItemsListener;
import org.schabi.newpipe.player.helper.PlaybackParameterDialog;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.playlist.PlayQueueItemBuilder;
import org.schabi.newpipe.playlist.PlayQueueItemHolder;
import org.schabi.newpipe.playlist.PlayQueueItemTouchCallback;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.PlayQueueItemBuilder;
import org.schabi.newpipe.player.playqueue.PlayQueueItemHolder;
import org.schabi.newpipe.player.playqueue.PlayQueueItemTouchCallback;
import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper;
@ -847,10 +847,12 @@ public final class MainVideoPlayer extends AppCompatActivity
if (DEBUG) Log.d(TAG, "onDoubleTap() called with: e = [" + e + "]" + "rawXy = " + e.getRawX() + ", " + e.getRawY() + ", xy = " + e.getX() + ", " + e.getY());
if (!playerImpl.isPlaying()) return false;
if (e.getX() > playerImpl.getRootView().getWidth() / 2) {
if (e.getX() > playerImpl.getRootView().getWidth() * 2 / 3) {
playerImpl.onFastForward();
} else {
} else if (e.getX() < playerImpl.getRootView().getWidth() / 3) {
playerImpl.onFastRewind();
} else {
playerImpl.getPlayPauseButton().performClick();
}
return true;

Wyświetl plik

@ -2,17 +2,12 @@ package org.schabi.newpipe.player;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import java.io.Serializable;
public class PlayerState implements Serializable {
private final static String TAG = "PlayerState";
@NonNull private final PlayQueue playQueue;
private final int repeatMode;
@ -41,21 +36,6 @@ public class PlayerState implements Serializable {
// Serdes
//////////////////////////////////////////////////////////////////////////*/
@Nullable
public static PlayerState fromJson(@NonNull final String json) {
try {
return new Gson().fromJson(json, PlayerState.class);
} catch (JsonSyntaxException error) {
Log.e(TAG, "Failed to deserialize PlayerState from json=[" + json + "]", error);
return null;
}
}
@NonNull
public String toJson() {
return new Gson().toJson(this);
}
/*//////////////////////////////////////////////////////////////////////////
// Getters
//////////////////////////////////////////////////////////////////////////*/

Wyświetl plik

@ -64,7 +64,7 @@ import org.schabi.newpipe.player.event.PlayerEventListener;
import org.schabi.newpipe.player.helper.LockManager;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.player.old.PlayVideoActivity;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ThemeHelper;

Wyświetl plik

@ -29,14 +29,14 @@ import com.google.android.exoplayer2.Player;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.fragments.OnScrollBelowItemsListener;
import org.schabi.newpipe.fragments.local.dialog.PlaylistAppendDialog;
import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
import org.schabi.newpipe.player.event.PlayerEventListener;
import org.schabi.newpipe.player.helper.PlaybackParameterDialog;
import org.schabi.newpipe.playlist.PlayQueueAdapter;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.playlist.PlayQueueItemBuilder;
import org.schabi.newpipe.playlist.PlayQueueItemHolder;
import org.schabi.newpipe.playlist.PlayQueueItemTouchCallback;
import org.schabi.newpipe.player.playqueue.PlayQueueAdapter;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.PlayQueueItemBuilder;
import org.schabi.newpipe.player.playqueue.PlayQueueItemHolder;
import org.schabi.newpipe.player.playqueue.PlayQueueItemTouchCallback;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ThemeHelper;

Wyświetl plik

@ -68,7 +68,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.ListHelper;

Wyświetl plik

@ -24,9 +24,9 @@ import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.SubtitlesFormat;
import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import java.text.DecimalFormat;
import java.text.NumberFormat;

Wyświetl plik

@ -7,7 +7,7 @@ import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.upstream.Allocator;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import java.io.IOException;

Wyświetl plik

@ -7,7 +7,7 @@ import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.upstream.Allocator;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import java.io.IOException;

Wyświetl plik

@ -4,7 +4,7 @@ import android.support.annotation.NonNull;
import com.google.android.exoplayer2.source.MediaSource;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
public interface ManagedMediaSource extends MediaSource {
/**

Wyświetl plik

@ -6,7 +6,7 @@ import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.upstream.Allocator;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import java.io.IOException;

Wyświetl plik

@ -5,7 +5,7 @@ import android.support.v4.media.MediaDescriptionCompat;
import org.schabi.newpipe.player.BasePlayer;
import org.schabi.newpipe.player.mediasession.MediaSessionCallback;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
public class BasePlayerMediaSession implements MediaSessionCallback {
private BasePlayer player;

Wyświetl plik

@ -16,12 +16,12 @@ import org.schabi.newpipe.player.mediasource.LoadedMediaSource;
import org.schabi.newpipe.player.mediasource.ManagedMediaSource;
import org.schabi.newpipe.player.mediasource.ManagedMediaSourcePlaylist;
import org.schabi.newpipe.player.mediasource.PlaceholderMediaSource;
import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.playlist.events.MoveEvent;
import org.schabi.newpipe.playlist.events.PlayQueueEvent;
import org.schabi.newpipe.playlist.events.RemoveEvent;
import org.schabi.newpipe.playlist.events.ReorderEvent;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.events.MoveEvent;
import org.schabi.newpipe.player.playqueue.events.PlayQueueEvent;
import org.schabi.newpipe.player.playqueue.events.RemoveEvent;
import org.schabi.newpipe.player.playqueue.events.ReorderEvent;
import org.schabi.newpipe.util.ServiceHelper;
import java.util.ArrayList;
@ -45,7 +45,7 @@ import io.reactivex.subjects.PublishSubject;
import static org.schabi.newpipe.player.mediasource.FailedMediaSource.MediaSourceResolutionException;
import static org.schabi.newpipe.player.mediasource.FailedMediaSource.StreamInfoLoadException;
import static org.schabi.newpipe.playlist.PlayQueue.DEBUG;
import static org.schabi.newpipe.player.playqueue.PlayQueue.DEBUG;
public class MediaSourceManager {
@NonNull private final String TAG = "MediaSourceManager@" + hashCode();

Wyświetl plik

@ -6,7 +6,7 @@ import android.support.annotation.Nullable;
import com.google.android.exoplayer2.source.MediaSource;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import java.util.List;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist;
package org.schabi.newpipe.player.playqueue;
import android.util.Log;

Wyświetl plik

@ -1,6 +1,6 @@
package org.schabi.newpipe.playlist;
package org.schabi.newpipe.player.playqueue;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist;
package org.schabi.newpipe.player.playqueue;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -6,15 +6,15 @@ import android.util.Log;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import org.schabi.newpipe.playlist.events.AppendEvent;
import org.schabi.newpipe.playlist.events.ErrorEvent;
import org.schabi.newpipe.playlist.events.InitEvent;
import org.schabi.newpipe.playlist.events.MoveEvent;
import org.schabi.newpipe.playlist.events.PlayQueueEvent;
import org.schabi.newpipe.playlist.events.RecoveryEvent;
import org.schabi.newpipe.playlist.events.RemoveEvent;
import org.schabi.newpipe.playlist.events.ReorderEvent;
import org.schabi.newpipe.playlist.events.SelectEvent;
import org.schabi.newpipe.player.playqueue.events.AppendEvent;
import org.schabi.newpipe.player.playqueue.events.ErrorEvent;
import org.schabi.newpipe.player.playqueue.events.InitEvent;
import org.schabi.newpipe.player.playqueue.events.MoveEvent;
import org.schabi.newpipe.player.playqueue.events.PlayQueueEvent;
import org.schabi.newpipe.player.playqueue.events.RecoveryEvent;
import org.schabi.newpipe.player.playqueue.events.RemoveEvent;
import org.schabi.newpipe.player.playqueue.events.ReorderEvent;
import org.schabi.newpipe.player.playqueue.events.SelectEvent;
import java.io.Serializable;
import java.util.ArrayList;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist;
package org.schabi.newpipe.player.playqueue;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
@ -8,12 +8,12 @@ import android.view.View;
import android.view.ViewGroup;
import org.schabi.newpipe.R;
import org.schabi.newpipe.playlist.events.AppendEvent;
import org.schabi.newpipe.playlist.events.ErrorEvent;
import org.schabi.newpipe.playlist.events.MoveEvent;
import org.schabi.newpipe.playlist.events.PlayQueueEvent;
import org.schabi.newpipe.playlist.events.RemoveEvent;
import org.schabi.newpipe.playlist.events.SelectEvent;
import org.schabi.newpipe.player.playqueue.events.AppendEvent;
import org.schabi.newpipe.player.playqueue.events.ErrorEvent;
import org.schabi.newpipe.player.playqueue.events.MoveEvent;
import org.schabi.newpipe.player.playqueue.events.PlayQueueEvent;
import org.schabi.newpipe.player.playqueue.events.RemoveEvent;
import org.schabi.newpipe.player.playqueue.events.SelectEvent;
import java.util.List;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist;
package org.schabi.newpipe.player.playqueue;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist;
package org.schabi.newpipe.player.playqueue;
import android.content.Context;
import android.text.TextUtils;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist;
package org.schabi.newpipe.player.playqueue;
import android.support.v7.widget.RecyclerView;
import android.view.View;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist;
package org.schabi.newpipe.player.playqueue;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;

Wyświetl plik

@ -1,6 +1,5 @@
package org.schabi.newpipe.playlist;
package org.schabi.newpipe.player.playqueue;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist;
package org.schabi.newpipe.player.playqueue;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist.events;
package org.schabi.newpipe.player.playqueue.events;
public class AppendEvent implements PlayQueueEvent {

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist.events;
package org.schabi.newpipe.player.playqueue.events;
public class ErrorEvent implements PlayQueueEvent {

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist.events;
package org.schabi.newpipe.player.playqueue.events;
public class InitEvent implements PlayQueueEvent {
@Override

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist.events;
package org.schabi.newpipe.player.playqueue.events;
public class MoveEvent implements PlayQueueEvent {
final private int fromIndex;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist.events;
package org.schabi.newpipe.player.playqueue.events;
import java.io.Serializable;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist.events;
package org.schabi.newpipe.player.playqueue.events;
public enum PlayQueueEventType {
INIT,

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist.events;
package org.schabi.newpipe.player.playqueue.events;
public class RecoveryEvent implements PlayQueueEvent {

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist.events;
package org.schabi.newpipe.player.playqueue.events;
public class RemoveEvent implements PlayQueueEvent {

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist.events;
package org.schabi.newpipe.player.playqueue.events;
public class ReorderEvent implements PlayQueueEvent {
private final int fromSelectedIndex;

Wyświetl plik

@ -1,4 +1,4 @@
package org.schabi.newpipe.playlist.events;
package org.schabi.newpipe.player.playqueue.events;
public class SelectEvent implements PlayQueueEvent {

Wyświetl plik

@ -14,7 +14,8 @@ public enum UserAction {
REQUESTED_STREAM("requested stream"),
REQUESTED_CHANNEL("requested channel"),
REQUESTED_PLAYLIST("requested playlist"),
REQUESTED_KIOSK("requested kiosk");
REQUESTED_KIOSK("requested kiosk"),
DELETE_FROM_HISTORY("delete from history");
private final String message;

Wyświetl plik

@ -1,20 +1,45 @@
package org.schabi.newpipe.settings;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.support.v7.preference.Preference;
import android.util.Log;
import android.widget.Toast;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.InfoCache;
import java.util.ArrayList;
import java.util.Collection;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.disposables.Disposables;
public class HistorySettingsFragment extends BasePreferenceFragment {
private String cacheWipeKey;
private String viewsHistroyClearKey;
private String searchHistoryClearKey;
private HistoryRecordManager recordManager;
private CompositeDisposable disposables;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
cacheWipeKey = getString(R.string.metadata_cache_wipe_key);
viewsHistroyClearKey = getString(R.string.clear_views_history_key);
searchHistoryClearKey = getString(R.string.clear_search_history_key);
recordManager = new HistoryRecordManager(getActivity());
disposables = new CompositeDisposable();
}
@Override
@ -30,6 +55,70 @@ public class HistorySettingsFragment extends BasePreferenceFragment {
Toast.LENGTH_SHORT).show();
}
if (preference.getKey().equals(viewsHistroyClearKey)) {
new AlertDialog.Builder(getActivity())
.setTitle(R.string.delete_view_history_alert)
.setNegativeButton(R.string.cancel, ((dialog, which) -> dialog.dismiss()))
.setPositiveButton(R.string.delete, ((dialog, which) -> {
final Disposable onDelete = recordManager.deleteWholeStreamHistory()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
howManyDeleted -> Toast.makeText(getActivity(),
R.string.view_history_deleted,
Toast.LENGTH_SHORT).show(),
throwable -> ErrorActivity.reportError(getContext(),
throwable,
SettingsActivity.class, null,
ErrorActivity.ErrorInfo.make(
UserAction.DELETE_FROM_HISTORY,
"none",
"Delete view history",
R.string.general_error)));
final Disposable onClearOrphans = recordManager.removeOrphanedRecords()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
howManyDeleted -> {},
throwable -> ErrorActivity.reportError(getContext(),
throwable,
SettingsActivity.class, null,
ErrorActivity.ErrorInfo.make(
UserAction.DELETE_FROM_HISTORY,
"none",
"Delete search history",
R.string.general_error)));
disposables.add(onClearOrphans);
disposables.add(onDelete);
}))
.create()
.show();
}
if (preference.getKey().equals(searchHistoryClearKey)) {
new AlertDialog.Builder(getActivity())
.setTitle(R.string.delete_search_history_alert)
.setNegativeButton(R.string.cancel, ((dialog, which) -> dialog.dismiss()))
.setPositiveButton(R.string.delete, ((dialog, which) -> {
final Disposable onDelete = recordManager.deleteWholeSearchHistory()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
howManyDeleted -> Toast.makeText(getActivity(),
R.string.search_history_deleted,
Toast.LENGTH_SHORT).show(),
throwable -> ErrorActivity.reportError(getContext(),
throwable,
SettingsActivity.class, null,
ErrorActivity.ErrorInfo.make(
UserAction.DELETE_FROM_HISTORY,
"none",
"Delete search history",
R.string.general_error)));
disposables.add(onDelete);
}))
.create()
.show();
}
return super.onPreferenceTreeClick(preference);
}
}

Wyświetl plik

@ -20,7 +20,7 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.subscription.SubscriptionService;
import org.schabi.newpipe.local.subscription.SubscriptionService;
import java.util.List;
import java.util.Vector;

Wyświetl plik

@ -33,15 +33,13 @@ import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.fragments.MainFragment;
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
import org.schabi.newpipe.fragments.list.channel.ChannelFragment;
import org.schabi.newpipe.fragments.list.feed.FeedFragment;
import org.schabi.newpipe.local.feed.FeedFragment;
import org.schabi.newpipe.fragments.list.kiosk.KioskFragment;
import org.schabi.newpipe.fragments.list.playlist.PlaylistFragment;
import org.schabi.newpipe.fragments.list.search.SearchFragment;
import org.schabi.newpipe.fragments.local.bookmark.LastPlayedFragment;
import org.schabi.newpipe.fragments.local.bookmark.LocalPlaylistFragment;
import org.schabi.newpipe.fragments.local.bookmark.MostPlayedFragment;
import org.schabi.newpipe.fragments.subscription.SubscriptionsImportFragment;
import org.schabi.newpipe.history.HistoryActivity;
import org.schabi.newpipe.local.history.StatisticsPlaylistFragment;
import org.schabi.newpipe.local.playlist.LocalPlaylistFragment;
import org.schabi.newpipe.local.subscription.SubscriptionsImportFragment;
import org.schabi.newpipe.player.BackgroundPlayer;
import org.schabi.newpipe.player.BackgroundPlayerActivity;
import org.schabi.newpipe.player.BasePlayer;
@ -50,7 +48,7 @@ import org.schabi.newpipe.player.PopupVideoPlayer;
import org.schabi.newpipe.player.PopupVideoPlayerActivity;
import org.schabi.newpipe.player.VideoPlayer;
import org.schabi.newpipe.player.old.PlayVideoActivity;
import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.settings.SettingsActivity;
import java.util.ArrayList;
@ -352,16 +350,9 @@ public class NavigationHelper {
.commit();
}
public static void openLastPlayedFragment(FragmentManager fragmentManager) {
public static void openStatisticFragment(FragmentManager fragmentManager) {
defaultTransaction(fragmentManager)
.replace(R.id.fragment_holder, new LastPlayedFragment())
.addToBackStack(null)
.commit();
}
public static void openMostPlayedFragment(FragmentManager fragmentManager) {
defaultTransaction(fragmentManager)
.replace(R.id.fragment_holder, new MostPlayedFragment())
.replace(R.id.fragment_holder, new StatisticsPlaylistFragment())
.addToBackStack(null)
.commit();
}
@ -417,11 +408,6 @@ public class NavigationHelper {
context.startActivity(intent);
}
public static void openHistory(Context context) {
Intent intent = new Intent(context, HistoryActivity.class);
context.startActivity(intent);
}
public static void openSettings(Context context) {
Intent intent = new Intent(context, SettingsActivity.class);
context.startActivity(intent);

Wyświetl plik

@ -190,4 +190,16 @@ public class ThemeHelper {
String defaultTheme = context.getResources().getString(R.string.default_theme_value);
return PreferenceManager.getDefaultSharedPreferences(context).getString(themeKey, defaultTheme);
}
/**
* This will get the R.drawable.* resource to which attr is currently pointing to.
*
* @param attr a R.attribute.* resource value
* @param context the context to use
* @return a R.drawable.* resource value
*/
public static int getIconByAttr(final int attr, final Context context) {
return context.obtainStyledAttributes(new int[] {attr})
.getResourceId(0, -1);
}
}

Wyświetl plik

@ -3,8 +3,6 @@ package us.shandian.giga.get;
import android.support.annotation.Nullable;
import android.util.Log;
import com.google.gson.Gson;
import java.io.File;
import java.io.FilenameFilter;
import java.io.RandomAccessFile;
@ -156,16 +154,8 @@ public class DownloadManagerImpl implements DownloadManager {
for (File sub : subs) {
if (sub.isFile() && sub.getName().endsWith(".giga")) {
String str = Utility.readFromFile(sub.getAbsolutePath());
if (str != null && !str.trim().equals("")) {
if (DEBUG) {
Log.d(TAG, "loading mission " + sub.getName());
Log.d(TAG, str);
}
DownloadMission mis = new Gson().fromJson(str, DownloadMission.class);
DownloadMission mis = Utility.readFromFile(sub.getAbsolutePath());
if (mis != null) {
if (mis.finished) {
if (!sub.delete()) {
Log.w(TAG, "Unable to delete .giga file: " + sub.getPath());

Wyświetl plik

@ -4,9 +4,8 @@ import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.google.gson.Gson;
import java.io.File;
import java.io.Serializable;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
@ -18,7 +17,9 @@ import us.shandian.giga.util.Utility;
import static org.schabi.newpipe.BuildConfig.DEBUG;
public class DownloadMission {
public class DownloadMission implements Serializable {
private static final long serialVersionUID = 0L;
private static final String TAG = DownloadMission.class.getSimpleName();
public interface MissionListener {
@ -79,7 +80,6 @@ public class DownloadMission {
private transient boolean mWritingToFile;
private static final int NO_IDENTIFIER = -1;
private long db_identifier = NO_IDENTIFIER;
public DownloadMission() {
}
@ -308,7 +308,7 @@ public class DownloadMission {
*/
private void doWriteThisToFile() {
synchronized (blockState) {
Utility.writeToFile(getMetaFilename(), new Gson().toJson(this));
Utility.writeToFile(getMetaFilename(), this);
}
}

Wyświetl plik

@ -5,6 +5,7 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.widget.Toast;
@ -16,6 +17,9 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@ -51,57 +55,47 @@ public class Utility {
}
}
public static void writeToFile(String fileName, String content) {
public static void writeToFile(@NonNull String fileName, @NonNull Serializable serializable) {
ObjectOutputStream objectOutputStream = null;
try {
writeToFile(fileName, content.getBytes("UTF-8"));
objectOutputStream = new ObjectOutputStream(new FileOutputStream(fileName));
objectOutputStream.writeObject(serializable);
} catch (Exception e) {
//nothing to do
}
}
public static void writeToFile(String fileName, byte[] content) {
File f = new File(fileName);
if (!f.exists()) {
if(objectOutputStream != null) {
try {
f.createNewFile();
objectOutputStream.close();
} catch (Exception e) {
//nothing to do
}
}
try {
FileOutputStream opt = new FileOutputStream(f, false);
opt.write(content, 0, content.length);
opt.close();
} catch (Exception e) {
}
}
public static String readFromFile(String file) {
@Nullable
@SuppressWarnings("unchecked")
public static <T> T readFromFile(String file) {
T object = null;
ObjectInputStream objectInputStream = null;
try {
File f = new File(file);
if (!f.exists() || !f.canRead()) {
return null;
}
BufferedInputStream ipt = new BufferedInputStream(new FileInputStream(f));
byte[] buf = new byte[512];
StringBuilder sb = new StringBuilder();
while (ipt.available() > 0) {
int len = ipt.read(buf, 0, 512);
sb.append(new String(buf, 0, len, "UTF-8"));
}
ipt.close();
return sb.toString();
objectInputStream = new ObjectInputStream(new FileInputStream(file));
object = (T) objectInputStream.readObject();
} catch (Exception e) {
return null;
//nothing to do
}
if(objectInputStream != null){
try {
objectInputStream .close();
} catch (Exception e) {
//nothing to do
}
}
return object;
}
@Nullable

Wyświetl plik

@ -1,81 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:background="?attr/selectableItemBackground">
<RelativeLayout
android:id="@+id/lastPlayed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true">
<ImageView
android:id="@+id/lastPlayedIcon"
android:layout_width="48dp"
android:layout_height="28dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:src="?attr/history"
tools:ignore="ContentDescription,RtlHardcoded"/>
<TextView
android:id="@+id/lastPlayedText"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_toRightOf="@+id/lastPlayedIcon"
android:gravity="left|center"
android:text="@string/title_last_played"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="15sp"
android:textStyle="bold"
tools:ignore="RtlHardcoded"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/mostPlayed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/lastPlayed"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true">
<ImageView
android:id="@+id/mostPlayedIcon"
android:layout_width="48dp"
android:layout_height="28dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:src="?attr/filter"
tools:ignore="ContentDescription,RtlHardcoded"/>
<TextView
android:id="@+id/mostPlayedText"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_toRightOf="@+id/mostPlayedIcon"
android:gravity="left|center"
android:text="@string/title_most_played"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="15sp"
android:textStyle="bold"
tools:ignore="RtlHardcoded"/>
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@+id/mostPlayed"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="?attr/separator_color"/>
</RelativeLayout>

Wyświetl plik

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/sortButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true">
<ImageView
android:id="@+id/sortButtonIcon"
android:layout_width="48dp"
android:layout_height="28dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:src="?attr/filter"
tools:ignore="ContentDescription,RtlHardcoded"/>
<TextView
android:id="@+id/sortButtonText"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_toRightOf="@id/sortButtonIcon"
android:gravity="left|center"
android:text="@string/title_most_played"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="15sp"
android:textStyle="bold"
tools:ignore="RtlHardcoded"/>
</RelativeLayout>
<include layout="@layout/playlist_control" />
</LinearLayout>

Wyświetl plik

@ -147,6 +147,8 @@
<string name="download_thumbnail_key" translatable="false">download_thumbnail_key</string>
<string name="metadata_cache_wipe_key" translatable="false">cache_wipe_key</string>
<string name="clear_views_history_key" translatable="false">clear_play_history</string>
<string name="clear_search_history_key" translatable="false">clear_search_history</string>
<!-- FileName Downloads -->
<string name="settings_file_charset_key" translatable="false">file_rename</string>

Wyświetl plik

@ -155,6 +155,14 @@
<string name="export_data_title">Export database</string>
<string name="import_data_summary">Will override your current history and subscriptions</string>
<string name="export_data_summary">Export history, subscriptions and playlists.</string>
<string name="clear_views_history_title">Clear watch history</string>
<string name="clear_views_history_summary">Deletes the history of played streams.</string>
<string name="delete_view_history_alert">Delete whole watch history.</string>
<string name="view_history_deleted">Watch history deleted.</string>
<string name="clear_search_history_title">Clear search history</string>
<string name="clear_search_history_summary">Deletes history of search keywords.</string>
<string name="delete_search_history_alert">Delete whole search history.</string>
<string name="search_history_deleted">Search history deleted.</string>
<!-- error strings -->
<string name="general_error">Error</string>
<string name="network_error">Network error</string>
@ -273,6 +281,7 @@
<string name="msg_copied">Copied to clipboard</string>
<string name="no_available_dir">Please select an available download folder</string>
<string name="msg_popup_permission">This permission is needed to\nopen in popup mode</string>
<string name="one_item_deleted">1 item deleted.</string>
<!-- Checksum types -->
<string name="md5" translatable="false">MD5</string>

Wyświetl plik

@ -21,4 +21,14 @@
android:summary="@string/metadata_cache_wipe_summary"
android:title="@string/metadata_cache_wipe_title"/>
<Preference
android:key="@string/clear_views_history_key"
android:title="@string/clear_views_history_title"
android:summary="@string/clear_views_history_summary"/>
<Preference
android:key="@string/clear_search_history_key"
android:title="@string/clear_search_history_title"
android:summary="@string/clear_search_history_summary"/>
</PreferenceScreen>

Wyświetl plik

@ -1,9 +1,9 @@
package org.schabi.newpipe.subscription.services;
package org.schabi.newpipe.local.subscription.services;
import org.junit.Test;
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
import org.schabi.newpipe.extractor.subscription.SubscriptionItem;
import org.schabi.newpipe.subscription.ImportExportJsonHelper;
import org.schabi.newpipe.local.subscription.ImportExportJsonHelper;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;