diff --git a/app/build.gradle b/app/build.gradle
index 47a424250..67c001535 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -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'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 1e55270be..33e0651e5 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -80,8 +80,8 @@
android:name=".history.HistoryActivity"
android:label="@string/title_activity_history"/>
-
-
+
+
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);
diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java
index 2ddf6b122..a862384cf 100644
--- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java
index a64ed7ff4..962ec8a36 100644
--- a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java
@@ -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),
diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.java b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.java
index 0a9a0bb66..d6cab1090 100644
--- a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.java
+++ b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java
index cb9ce8947..5707716bf 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java
@@ -239,7 +239,8 @@ public abstract class BaseStateFragment 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));
}
/*//////////////////////////////////////////////////////////////////////////
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java
index 20607b3a0..31092d3e6 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
index e1fee28bb..68c0a11ff 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java
index 580e16825..14ec50775 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java
@@ -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 extends BaseStateFragment implem
infoListAdapter.setOnStreamSelectedListener(new OnClickGesture() {
@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 extends BaseStateFragment 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 extends BaseStateFragment implem
new InfoItemDialog(getActivity(), item, commands, actions).show();
}
+
/*//////////////////////////////////////////////////////////////////////////
// Menu
//////////////////////////////////////////////////////////////////////////*/
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
index 683286764..dc8d764f3 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
index 3bcf9d322..0498c95c5 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java
index f7831e02d..d07ff6448 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java
@@ -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);
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionListAdapter.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionListAdapter.java
index 2fed3f8fb..7b5f72c53 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionListAdapter.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionListAdapter.java
@@ -63,24 +63,15 @@ public class SuggestionListAdapter extends RecyclerView.Adapter {
+ 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);
});
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/LastPlayedFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/LastPlayedFragment.java
deleted file mode 100644
index a5b62c63e..000000000
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/LastPlayedFragment.java
+++ /dev/null
@@ -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 processResult(List results) {
- Collections.sort(results, (left, right) ->
- right.latestAccessDate.compareTo(left.latestAccessDate));
- return results;
- }
-}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/MostPlayedFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/MostPlayedFragment.java
deleted file mode 100644
index cba9e9c64..000000000
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/MostPlayedFragment.java
+++ /dev/null
@@ -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 processResult(List results) {
- Collections.sort(results, (left, right) ->
- ((Long) right.watchCount).compareTo(left.watchCount));
- return results;
- }
-
-}
diff --git a/app/src/main/java/org/schabi/newpipe/history/HistoryActivity.java b/app/src/main/java/org/schabi/newpipe/history/HistoryActivity.java
deleted file mode 100644
index 267d07065..000000000
--- a/app/src/main/java/org/schabi/newpipe/history/HistoryActivity.java
+++ /dev/null
@@ -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;
- }
- }
-}
diff --git a/app/src/main/java/org/schabi/newpipe/history/HistoryFragment.java b/app/src/main/java/org/schabi/newpipe/history/HistoryFragment.java
deleted file mode 100644
index 14bd93c57..000000000
--- a/app/src/main/java/org/schabi/newpipe/history/HistoryFragment.java
+++ /dev/null
@@ -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 extends BaseFragment
- implements HistoryEntryAdapter.OnHistoryItemClickListener {
-
- 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 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 createAdapter();
-
- protected abstract Single> insert(final Collection entries);
-
- protected abstract Single delete(final Collection entries);
-
- @NonNull
- protected abstract Flowable> 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> getHistorySubscriber() {
- return new Subscriber>() {
- @Override
- public void onSubscribe(Subscription s) {
- if (historySubscription != null) historySubscription.cancel();
-
- historySubscription = s;
- historySubscription.request(1);
- }
-
- @Override
- public void onNext(List 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 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);
- }
- }
- }
- }
-}
diff --git a/app/src/main/java/org/schabi/newpipe/history/SearchHistoryFragment.java b/app/src/main/java/org/schabi/newpipe/history/SearchHistoryFragment.java
deleted file mode 100644
index 25098fac8..000000000
--- a/app/src/main/java/org/schabi/newpipe/history/SearchHistoryFragment.java
+++ /dev/null
@@ -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 {
-
- @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> insert(Collection entries) {
- return historyRecordManager.insertSearches(entries);
- }
-
- @Override
- protected Single delete(Collection entries) {
- return historyRecordManager.deleteSearches(entries);
- }
-
- @NonNull
- @Override
- protected Flowable> 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 {
-
- 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);
- }
- }
-}
diff --git a/app/src/main/java/org/schabi/newpipe/history/WatchHistoryFragment.java b/app/src/main/java/org/schabi/newpipe/history/WatchHistoryFragment.java
deleted file mode 100644
index 4fe2b701d..000000000
--- a/app/src/main/java/org/schabi/newpipe/history/WatchHistoryFragment.java
+++ /dev/null
@@ -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 {
-
- @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> insert(Collection entries) {
- return historyRecordManager.insertStreamHistory(entries);
- }
-
- @Override
- protected Single delete(Collection entries) {
- return historyRecordManager.deleteStreamHistory(entries);
- }
-
- @NonNull
- @Override
- protected Flowable> 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 {
-
- 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);
- }
- }
-}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/BaseLocalListFragment.java b/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java
similarity index 98%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/BaseLocalListFragment.java
rename to app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java
index eb366d97f..5192aa2ab 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/BaseLocalListFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/HeaderFooterHolder.java b/app/src/main/java/org/schabi/newpipe/local/HeaderFooterHolder.java
similarity index 84%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/HeaderFooterHolder.java
rename to app/src/main/java/org/schabi/newpipe/local/HeaderFooterHolder.java
index 3c0830751..49a552b3e 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/HeaderFooterHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/HeaderFooterHolder.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/LocalItemBuilder.java b/app/src/main/java/org/schabi/newpipe/local/LocalItemBuilder.java
similarity index 97%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/LocalItemBuilder.java
rename to app/src/main/java/org/schabi/newpipe/local/LocalItemBuilder.java
index 5dc6c17a4..148f93075 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/LocalItemBuilder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/LocalItemBuilder.java
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.fragments.local;
+package org.schabi.newpipe.local;
import android.content.Context;
import android.widget.ImageView;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/LocalItemListAdapter.java b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java
similarity index 95%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/LocalItemListAdapter.java
rename to app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java
index d36f56733..d05ef3488 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/LocalItemListAdapter.java
+++ b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java
similarity index 89%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/BookmarkFragment.java
rename to app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java
index e1f724b6e..f3f390c4d 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/BookmarkFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java
@@ -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, 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();
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java
similarity index 96%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/dialog/PlaylistAppendDialog.java
rename to app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java
index da31ca3f8..e422b332a 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/dialog/PlaylistAppendDialog.java
+++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/dialog/PlaylistCreationDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java
similarity index 95%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/dialog/PlaylistCreationDialog.java
rename to app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java
index f721e7701..ddbe65399 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/dialog/PlaylistCreationDialog.java
+++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/dialog/PlaylistDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistDialog.java
similarity index 97%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/dialog/PlaylistDialog.java
rename to app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistDialog.java
index a632988c4..4b8e391c7 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/dialog/PlaylistDialog.java
+++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistDialog.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/feed/FeedFragment.java b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.java
similarity index 99%
rename from app/src/main/java/org/schabi/newpipe/fragments/list/feed/FeedFragment.java
rename to app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.java
index dabfd9e1b..4937bb094 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/feed/FeedFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/history/HistoryEntryAdapter.java b/app/src/main/java/org/schabi/newpipe/local/history/HistoryEntryAdapter.java
similarity index 98%
rename from app/src/main/java/org/schabi/newpipe/history/HistoryEntryAdapter.java
rename to app/src/main/java/org/schabi/newpipe/local/history/HistoryEntryAdapter.java
index 4170a1139..2cb1add5d 100644
--- a/app/src/main/java/org/schabi/newpipe/history/HistoryEntryAdapter.java
+++ b/app/src/main/java/org/schabi/newpipe/local/history/HistoryEntryAdapter.java
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.history;
+package org.schabi.newpipe.local.history;
import android.content.Context;
import android.content.res.Resources;
diff --git a/app/src/main/java/org/schabi/newpipe/history/HistoryListener.java b/app/src/main/java/org/schabi/newpipe/local/history/HistoryListener.java
similarity index 96%
rename from app/src/main/java/org/schabi/newpipe/history/HistoryListener.java
rename to app/src/main/java/org/schabi/newpipe/local/history/HistoryListener.java
index 5c729b022..6e4b85713 100644
--- a/app/src/main/java/org/schabi/newpipe/history/HistoryListener.java
+++ b/app/src/main/java/org/schabi/newpipe/local/history/HistoryListener.java
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.history;
+package org.schabi.newpipe.local.history;
import android.support.annotation.Nullable;
diff --git a/app/src/main/java/org/schabi/newpipe/history/HistoryRecordManager.java b/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java
similarity index 88%
rename from app/src/main/java/org/schabi/newpipe/history/HistoryRecordManager.java
rename to app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java
index 9d3ffaffe..d3d824103 100644
--- a/app/src/main/java/org/schabi/newpipe/history/HistoryRecordManager.java
+++ b/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java
@@ -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 .
+ */
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 deleteWholeStreamHistory() {
+ return Single.fromCallable(() -> streamHistoryTable.deleteAll())
+ .subscribeOn(Schedulers.io());
+ }
+
public Flowable> getStreamHistory() {
return streamHistoryTable.getHistory().subscribeOn(Schedulers.io());
}
@@ -114,20 +138,6 @@ public class HistoryRecordManager {
// Search History
///////////////////////////////////////////////////////
- public Single> insertSearches(final Collection entries) {
- return Single.fromCallable(() -> searchHistoryTable.insertAll(entries))
- .subscribeOn(Schedulers.io());
- }
-
- public Single deleteSearches(final Collection entries) {
- return Single.fromCallable(() -> searchHistoryTable.delete(entries))
- .subscribeOn(Schedulers.io());
- }
-
- public Flowable> getSearchHistory() {
- return searchHistoryTable.getAll();
- }
-
public Maybe onSearched(final int serviceId, final String search) {
if (!isSearchHistoryEnabled()) return Maybe.empty();
@@ -150,6 +160,11 @@ public class HistoryRecordManager {
.subscribeOn(Schedulers.io());
}
+ public Single deleteWholeSearchHistory() {
+ return Single.fromCallable(() -> searchHistoryTable.deleteAll())
+ .subscribeOn(Schedulers.io());
+ }
+
public Flowable> getRelatedSearches(final String query,
final int similarQueryLimit,
final int uniqueQueryLimit) {
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/StatisticsPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java
similarity index 71%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/StatisticsPlaylistFragment.java
rename to app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java
index d9bbc68c8..eac1873a4 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/StatisticsPlaylistFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java
@@ -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, 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 processResult(final List results);
+ protected List processResult(final List 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);
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalItemHolder.java
similarity index 93%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalItemHolder.java
rename to app/src/main/java/org/schabi/newpipe/local/holder/LocalItemHolder.java
index 2dffdbfdb..889751afa 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalItemHolder.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalPlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java
similarity index 90%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalPlaylistItemHolder.java
rename to app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java
index d9eb7caa5..1a5ec63bf 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalPlaylistItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalPlaylistStreamItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java
similarity index 97%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalPlaylistStreamItemHolder.java
rename to app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java
index 5f9555d9f..e591b73e5 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalPlaylistStreamItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamItemHolder.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalStatisticStreamItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java
similarity index 97%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalStatisticStreamItemHolder.java
rename to app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java
index 199158672..b2a04ca9c 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalStatisticStreamItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/PlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/PlaylistItemHolder.java
similarity index 93%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/holder/PlaylistItemHolder.java
rename to app/src/main/java/org/schabi/newpipe/local/holder/PlaylistItemHolder.java
index 57bc2a3cb..5d6f192e1 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/PlaylistItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/holder/PlaylistItemHolder.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/RemotePlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java
similarity index 91%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/holder/RemotePlaylistItemHolder.java
rename to app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java
index 871138464..12d3063b0 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/RemotePlaylistItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java
similarity index 98%
rename from app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/LocalPlaylistFragment.java
rename to app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java
index 20eee38fc..e51fa50a4 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/local/bookmark/LocalPlaylistFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java
@@ -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
.
*/
-package org.schabi.newpipe.subscription;
+package org.schabi.newpipe.local.subscription;
import android.support.annotation.Nullable;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/subscription/SubscriptionFragment.java b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.java
similarity index 96%
rename from app/src/main/java/org/schabi/newpipe/fragments/subscription/SubscriptionFragment.java
rename to app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.java
index 610c74a01..5f6ea42ee 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/subscription/SubscriptionFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/subscription/SubscriptionService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionService.java
similarity index 99%
rename from app/src/main/java/org/schabi/newpipe/subscription/SubscriptionService.java
rename to app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionService.java
index 3220643b3..fc4230711 100644
--- a/app/src/main/java/org/schabi/newpipe/subscription/SubscriptionService.java
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionService.java
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.subscription;
+package org.schabi.newpipe.local.subscription;
import android.content.Context;
import android.support.annotation.NonNull;
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/subscription/SubscriptionsImportFragment.java b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionsImportFragment.java
similarity index 93%
rename from app/src/main/java/org/schabi/newpipe/fragments/subscription/SubscriptionsImportFragment.java
rename to app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionsImportFragment.java
index 775777c81..ed694c70e 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/subscription/SubscriptionsImportFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionsImportFragment.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/subscription/services/BaseImportExportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/BaseImportExportService.java
similarity index 97%
rename from app/src/main/java/org/schabi/newpipe/subscription/services/BaseImportExportService.java
rename to app/src/main/java/org/schabi/newpipe/local/subscription/services/BaseImportExportService.java
index a26b7a6d1..9d055b82a 100644
--- a/app/src/main/java/org/schabi/newpipe/subscription/services/BaseImportExportService.java
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/BaseImportExportService.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-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;
diff --git a/app/src/main/java/org/schabi/newpipe/subscription/services/SubscriptionsExportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java
similarity index 96%
rename from app/src/main/java/org/schabi/newpipe/subscription/services/SubscriptionsExportService.java
rename to app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java
index 069195c65..35da7dd4f 100644
--- a/app/src/main/java/org/schabi/newpipe/subscription/services/SubscriptionsExportService.java
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-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;
diff --git a/app/src/main/java/org/schabi/newpipe/subscription/services/SubscriptionsImportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java
similarity index 97%
rename from app/src/main/java/org/schabi/newpipe/subscription/services/SubscriptionsImportService.java
rename to app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java
index 259b1c2bd..3fdc91358 100644
--- a/app/src/main/java/org/schabi/newpipe/subscription/services/SubscriptionsImportService.java
+++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-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;
diff --git a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java
index 2d990e43e..f25c20bb2 100644
--- a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java
+++ b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java
index 5e5518ee9..94e0654e2 100644
--- a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java
+++ b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java
index aedcdb791..bc4a3f71d 100644
--- a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java
+++ b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerState.java b/app/src/main/java/org/schabi/newpipe/player/PlayerState.java
index 6f38ce835..8ffcb6b29 100644
--- a/app/src/main/java/org/schabi/newpipe/player/PlayerState.java
+++ b/app/src/main/java/org/schabi/newpipe/player/PlayerState.java
@@ -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
//////////////////////////////////////////////////////////////////////////*/
diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java
index 9528bf2bc..6e4f09ace 100644
--- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java
+++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java b/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java
index ccaa6f225..8b96b651e 100644
--- a/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java
index 6cf2076eb..f81318880 100644
--- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java
+++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java
index 7d3550c91..4ae8eec2a 100644
--- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasource/FailedMediaSource.java b/app/src/main/java/org/schabi/newpipe/player/mediasource/FailedMediaSource.java
index 878d7c711..8d498a9bf 100644
--- a/app/src/main/java/org/schabi/newpipe/player/mediasource/FailedMediaSource.java
+++ b/app/src/main/java/org/schabi/newpipe/player/mediasource/FailedMediaSource.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasource/LoadedMediaSource.java b/app/src/main/java/org/schabi/newpipe/player/mediasource/LoadedMediaSource.java
index fe7508ecc..1a9cfeb4d 100644
--- a/app/src/main/java/org/schabi/newpipe/player/mediasource/LoadedMediaSource.java
+++ b/app/src/main/java/org/schabi/newpipe/player/mediasource/LoadedMediaSource.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasource/ManagedMediaSource.java b/app/src/main/java/org/schabi/newpipe/player/mediasource/ManagedMediaSource.java
index 46fd149bb..8837e7529 100644
--- a/app/src/main/java/org/schabi/newpipe/player/mediasource/ManagedMediaSource.java
+++ b/app/src/main/java/org/schabi/newpipe/player/mediasource/ManagedMediaSource.java
@@ -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 {
/**
diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasource/PlaceholderMediaSource.java b/app/src/main/java/org/schabi/newpipe/player/mediasource/PlaceholderMediaSource.java
index 2c57f2f9c..318f9a316 100644
--- a/app/src/main/java/org/schabi/newpipe/player/mediasource/PlaceholderMediaSource.java
+++ b/app/src/main/java/org/schabi/newpipe/player/mediasource/PlaceholderMediaSource.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/BasePlayerMediaSession.java b/app/src/main/java/org/schabi/newpipe/player/playback/BasePlayerMediaSession.java
index 616879917..6cce4a764 100644
--- a/app/src/main/java/org/schabi/newpipe/player/playback/BasePlayerMediaSession.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playback/BasePlayerMediaSession.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java
index b4236d3c5..8ab3cba98 100644
--- a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java
@@ -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();
diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/PlaybackListener.java b/app/src/main/java/org/schabi/newpipe/player/playback/PlaybackListener.java
index daf58d5dd..4dcb30aa3 100644
--- a/app/src/main/java/org/schabi/newpipe/player/playback/PlaybackListener.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playback/PlaybackListener.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/AbstractInfoPlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java
similarity index 98%
rename from app/src/main/java/org/schabi/newpipe/playlist/AbstractInfoPlayQueue.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java
index 2b31cd340..2c08f4f92 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/AbstractInfoPlayQueue.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.playlist;
+package org.schabi.newpipe.player.playqueue;
import android.util.Log;
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/ChannelPlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelPlayQueue.java
similarity index 95%
rename from app/src/main/java/org/schabi/newpipe/playlist/ChannelPlayQueue.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelPlayQueue.java
index d37b84072..5a2e34d31 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/ChannelPlayQueue.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelPlayQueue.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java
similarity index 95%
rename from app/src/main/java/org/schabi/newpipe/playlist/PlayQueue.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java
index 19e6dc63d..a21560abd 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueue.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueAdapter.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueAdapter.java
similarity index 94%
rename from app/src/main/java/org/schabi/newpipe/playlist/PlayQueueAdapter.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueAdapter.java
index dd320c2bc..7aedc22a7 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueAdapter.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueAdapter.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItem.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java
similarity index 98%
rename from app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItem.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java
index 2d543fb4e..8cbc3ed1c 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItem.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItemBuilder.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java
similarity index 98%
rename from app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItemBuilder.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java
index 7042bea89..996d3ace3 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItemBuilder.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.playlist;
+package org.schabi.newpipe.player.playqueue;
import android.content.Context;
import android.text.TextUtils;
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItemHolder.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemHolder.java
similarity index 97%
rename from app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItemHolder.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemHolder.java
index 3837c4046..2483e4473 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItemHolder.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemHolder.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItemTouchCallback.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemTouchCallback.java
similarity index 97%
rename from app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItemTouchCallback.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemTouchCallback.java
index 405dba11e..6edeff670 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItemTouchCallback.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemTouchCallback.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/PlaylistPlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlaylistPlayQueue.java
similarity index 95%
rename from app/src/main/java/org/schabi/newpipe/playlist/PlaylistPlayQueue.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/PlaylistPlayQueue.java
index d9e1d2d2b..fcb7080c5 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/PlaylistPlayQueue.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlaylistPlayQueue.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/SinglePlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/SinglePlayQueue.java
similarity index 96%
rename from app/src/main/java/org/schabi/newpipe/playlist/SinglePlayQueue.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/SinglePlayQueue.java
index 9c4d2fb39..5993481e2 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/SinglePlayQueue.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/SinglePlayQueue.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/AppendEvent.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/AppendEvent.java
similarity index 86%
rename from app/src/main/java/org/schabi/newpipe/playlist/events/AppendEvent.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/events/AppendEvent.java
index b3ba8835a..6ccd85f82 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/events/AppendEvent.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/AppendEvent.java
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.playlist.events;
+package org.schabi.newpipe.player.playqueue.events;
public class AppendEvent implements PlayQueueEvent {
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/ErrorEvent.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/ErrorEvent.java
similarity index 92%
rename from app/src/main/java/org/schabi/newpipe/playlist/events/ErrorEvent.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/events/ErrorEvent.java
index 45629feb6..570a8e337 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/events/ErrorEvent.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/ErrorEvent.java
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.playlist.events;
+package org.schabi.newpipe.player.playqueue.events;
public class ErrorEvent implements PlayQueueEvent {
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/InitEvent.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/InitEvent.java
similarity index 74%
rename from app/src/main/java/org/schabi/newpipe/playlist/events/InitEvent.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/events/InitEvent.java
index 1c1d01508..559975b35 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/events/InitEvent.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/InitEvent.java
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.playlist.events;
+package org.schabi.newpipe.player.playqueue.events;
public class InitEvent implements PlayQueueEvent {
@Override
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/MoveEvent.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/MoveEvent.java
similarity index 90%
rename from app/src/main/java/org/schabi/newpipe/playlist/events/MoveEvent.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/events/MoveEvent.java
index 4370fe328..69468be31 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/events/MoveEvent.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/MoveEvent.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/PlayQueueEvent.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/PlayQueueEvent.java
similarity index 69%
rename from app/src/main/java/org/schabi/newpipe/playlist/events/PlayQueueEvent.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/events/PlayQueueEvent.java
index c56c3fbc0..431053e7b 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/events/PlayQueueEvent.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/PlayQueueEvent.java
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.playlist.events;
+package org.schabi.newpipe.player.playqueue.events;
import java.io.Serializable;
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/PlayQueueEventType.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/PlayQueueEventType.java
similarity index 90%
rename from app/src/main/java/org/schabi/newpipe/playlist/events/PlayQueueEventType.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/events/PlayQueueEventType.java
index 0fc40c098..1cc710c7b 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/events/PlayQueueEventType.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/PlayQueueEventType.java
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.playlist.events;
+package org.schabi.newpipe.player.playqueue.events;
public enum PlayQueueEventType {
INIT,
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/RecoveryEvent.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/RecoveryEvent.java
similarity index 90%
rename from app/src/main/java/org/schabi/newpipe/playlist/events/RecoveryEvent.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/events/RecoveryEvent.java
index 715cf88c4..58d3fadfc 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/events/RecoveryEvent.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/RecoveryEvent.java
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.playlist.events;
+package org.schabi.newpipe.player.playqueue.events;
public class RecoveryEvent implements PlayQueueEvent {
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/RemoveEvent.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/RemoveEvent.java
similarity index 90%
rename from app/src/main/java/org/schabi/newpipe/playlist/events/RemoveEvent.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/events/RemoveEvent.java
index 464dbfa49..bb42ef109 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/events/RemoveEvent.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/RemoveEvent.java
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.playlist.events;
+package org.schabi.newpipe.player.playqueue.events;
public class RemoveEvent implements PlayQueueEvent {
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/ReorderEvent.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/ReorderEvent.java
similarity index 91%
rename from app/src/main/java/org/schabi/newpipe/playlist/events/ReorderEvent.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/events/ReorderEvent.java
index 19bb632d8..738a89fcf 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/events/ReorderEvent.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/ReorderEvent.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/playlist/events/SelectEvent.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/SelectEvent.java
similarity index 90%
rename from app/src/main/java/org/schabi/newpipe/playlist/events/SelectEvent.java
rename to app/src/main/java/org/schabi/newpipe/player/playqueue/events/SelectEvent.java
index d1d0b1137..7dcc88794 100644
--- a/app/src/main/java/org/schabi/newpipe/playlist/events/SelectEvent.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/events/SelectEvent.java
@@ -1,4 +1,4 @@
-package org.schabi.newpipe.playlist.events;
+package org.schabi.newpipe.player.playqueue.events;
public class SelectEvent implements PlayQueueEvent {
diff --git a/app/src/main/java/org/schabi/newpipe/report/UserAction.java b/app/src/main/java/org/schabi/newpipe/report/UserAction.java
index c06c65a81..93a3ce16c 100644
--- a/app/src/main/java/org/schabi/newpipe/report/UserAction.java
+++ b/app/src/main/java/org/schabi/newpipe/report/UserAction.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java
index 53e8d6fc4..cc1f408b7 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java
@@ -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);
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java
index c0eadfaa8..107f8b7f0 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java
@@ -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;
diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
index 7454aaf57..ebbeb06f8 100644
--- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
@@ -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);
diff --git a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java
index 1edc4dfec..1d1b66bf9 100644
--- a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java
@@ -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);
+ }
}
diff --git a/app/src/main/java/us/shandian/giga/get/DownloadManagerImpl.java b/app/src/main/java/us/shandian/giga/get/DownloadManagerImpl.java
index acbd41680..ecd3ce562 100755
--- a/app/src/main/java/us/shandian/giga/get/DownloadManagerImpl.java
+++ b/app/src/main/java/us/shandian/giga/get/DownloadManagerImpl.java
@@ -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());
diff --git a/app/src/main/java/us/shandian/giga/get/DownloadMission.java b/app/src/main/java/us/shandian/giga/get/DownloadMission.java
index 9938d2d86..c48e5ffbc 100644
--- a/app/src/main/java/us/shandian/giga/get/DownloadMission.java
+++ b/app/src/main/java/us/shandian/giga/get/DownloadMission.java
@@ -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);
}
}
diff --git a/app/src/main/java/us/shandian/giga/util/Utility.java b/app/src/main/java/us/shandian/giga/util/Utility.java
index 1d7b629e4..2d44e8c15 100644
--- a/app/src/main/java/us/shandian/giga/util/Utility.java
+++ b/app/src/main/java/us/shandian/giga/util/Utility.java
@@ -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 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
diff --git a/app/src/main/res/layout/bookmark_header.xml b/app/src/main/res/layout/bookmark_header.xml
deleted file mode 100644
index 8ca5c1228..000000000
--- a/app/src/main/res/layout/bookmark_header.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/statistic_playlist_control.xml b/app/src/main/res/layout/statistic_playlist_control.xml
new file mode 100644
index 000000000..8dc4e8c08
--- /dev/null
+++ b/app/src/main/res/layout/statistic_playlist_control.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml
index dcbea2eb8..20a6ab68f 100644
--- a/app/src/main/res/values/settings_keys.xml
+++ b/app/src/main/res/values/settings_keys.xml
@@ -147,6 +147,8 @@
download_thumbnail_key
cache_wipe_key
+ clear_play_history
+ clear_search_history
file_rename
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 939e0df13..3edbd4e9b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -155,6 +155,14 @@
Export database
Will override your current history and subscriptions
Export history, subscriptions and playlists.
+ Clear watch history
+ Deletes the history of played streams.
+ Delete whole watch history.
+ Watch history deleted.
+ Clear search history
+ Deletes history of search keywords.
+ Delete whole search history.
+ Search history deleted.
Error
Network error
@@ -273,6 +281,7 @@
Copied to clipboard
Please select an available download folder
This permission is needed to\nopen in popup mode
+ 1 item deleted.
MD5
diff --git a/app/src/main/res/xml/history_settings.xml b/app/src/main/res/xml/history_settings.xml
index 2e19517b9..2be1e5341 100644
--- a/app/src/main/res/xml/history_settings.xml
+++ b/app/src/main/res/xml/history_settings.xml
@@ -21,4 +21,14 @@
android:summary="@string/metadata_cache_wipe_summary"
android:title="@string/metadata_cache_wipe_title"/>
+
+
+
+
diff --git a/app/src/test/java/org/schabi/newpipe/subscription/services/ImportExportJsonHelperTest.java b/app/src/test/java/org/schabi/newpipe/local/subscription/services/ImportExportJsonHelperTest.java
similarity index 97%
rename from app/src/test/java/org/schabi/newpipe/subscription/services/ImportExportJsonHelperTest.java
rename to app/src/test/java/org/schabi/newpipe/local/subscription/services/ImportExportJsonHelperTest.java
index a5e6b659f..4a8b3d8c8 100644
--- a/app/src/test/java/org/schabi/newpipe/subscription/services/ImportExportJsonHelperTest.java
+++ b/app/src/test/java/org/schabi/newpipe/local/subscription/services/ImportExportJsonHelperTest.java
@@ -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;