diff --git a/README.md b/README.md index b154fad58..a171823d5 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@

ScreenshotsDescriptionFeaturesContributionDonateLicense

WebsiteBlogPress


-WARNING: PUTTING NEWPIPE OR ANY FORK OF IT INTO GOOGLE PLAYSTORE VIOLATES THEIR TERMS OF CONDITIONS. +**WARNING: PUTTING NEWPIPE OR ANY FORK OF IT INTO GOOGLE PLAYSTORE VIOLATES THEIR TERMS OF CONDITIONS.** ## Screenshots @@ -29,6 +29,8 @@ WARNING: PUTTING NEWPIPE OR ANY FORK OF IT INTO GOOGLE PLAYSTORE VIOLATES THEIR [](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_8.png) [](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_9.png) [](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_10.png) +[](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_11.png) +[](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_12.png) ## Description @@ -61,11 +63,11 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only * Queuing videos * Local playlists * Subtitles -* Multi-service support (eg. SoundCloud in NewPipe Beta) +* Multi-service support (eg. SoundCloud \[beta\]) +* Livestream support ### Coming Features -* Livestream support * Cast to UPnP and Cast * Show comments * ... and many more diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index f436a26b8..dfce8f100 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -106,7 +106,7 @@ public class App extends Application { // https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling RxJavaPlugins.setErrorHandler(new Consumer() { @Override - public void accept(@NonNull Throwable throwable) throws Exception { + public void accept(@NonNull Throwable throwable) { Log.e(TAG, "RxJavaPlugins.ErrorHandler called with -> : " + "throwable = [" + throwable.getClass().getName() + "]"); diff --git a/app/src/main/java/org/schabi/newpipe/BaseFragment.java b/app/src/main/java/org/schabi/newpipe/BaseFragment.java index b125ab02f..4e4cdcc0d 100644 --- a/app/src/main/java/org/schabi/newpipe/BaseFragment.java +++ b/app/src/main/java/org/schabi/newpipe/BaseFragment.java @@ -12,14 +12,12 @@ import android.view.View; import com.nostra13.universalimageloader.core.ImageLoader; import com.squareup.leakcanary.RefWatcher; -import org.schabi.newpipe.report.UserAction; - import icepick.Icepick; import icepick.State; public abstract class BaseFragment extends Fragment { protected final String TAG = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()); - protected boolean DEBUG = MainActivity.DEBUG; + protected final boolean DEBUG = MainActivity.DEBUG; protected AppCompatActivity activity; public static final ImageLoader imageLoader = ImageLoader.getInstance(); diff --git a/app/src/main/java/org/schabi/newpipe/Downloader.java b/app/src/main/java/org/schabi/newpipe/Downloader.java index 17dc5859d..68f7e080f 100644 --- a/app/src/main/java/org/schabi/newpipe/Downloader.java +++ b/app/src/main/java/org/schabi/newpipe/Downloader.java @@ -43,7 +43,7 @@ public class Downloader implements org.schabi.newpipe.extractor.Downloader { private static Downloader instance; private String mCookies; - private OkHttpClient client; + private final OkHttpClient client; private Downloader(OkHttpClient.Builder builder) { this.client = builder diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index 7c77bff3d..a9f2e9622 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -23,7 +23,6 @@ package org.schabi.newpipe; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; -import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -66,8 +65,6 @@ import org.schabi.newpipe.util.ServiceHelper; import org.schabi.newpipe.util.StateSaver; import org.schabi.newpipe.util.ThemeHelper; -import static org.schabi.newpipe.extractor.InfoItem.InfoType.PLAYLIST; - public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; public static final boolean DEBUG = !BuildConfig.BUILD_TYPE.equals("release"); diff --git a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java index a4e6730da..74c818bf9 100644 --- a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java +++ b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java @@ -85,7 +85,7 @@ public class ReCaptchaActivity extends AppCompatActivity { } private class ReCaptchaWebViewClient extends WebViewClient { - private Activity context; + private final Activity context; private String mCookies; ReCaptchaWebViewClient(Activity ctx) { diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 4f1fdeab2..e22e2f474 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -1,7 +1,6 @@ package org.schabi.newpipe; import android.annotation.SuppressLint; -import android.app.FragmentManager; import android.app.IntentService; import android.content.Context; import android.content.DialogInterface; @@ -13,7 +12,6 @@ import android.preference.PreferenceManager; import android.support.annotation.DrawableRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v4.app.Fragment; import android.support.v4.app.NotificationCompat; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; @@ -38,7 +36,6 @@ 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.VideoStream; -import org.schabi.newpipe.fragments.detail.VideoDetailFragment; import org.schabi.newpipe.player.helper.PlayerHelper; import org.schabi.newpipe.player.playqueue.ChannelPlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueue; @@ -51,14 +48,12 @@ import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.PermissionHelper; import org.schabi.newpipe.util.ThemeHelper; -import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; -import java.util.Observer; import icepick.Icepick; import icepick.State; @@ -86,7 +81,7 @@ public class RouterActivity extends AppCompatActivity { protected int selectedPreviously = -1; protected String currentUrl; - protected CompositeDisposable disposables = new CompositeDisposable(); + protected final CompositeDisposable disposables = new CompositeDisposable(); private boolean selectionIsDownload = false; @@ -184,12 +179,16 @@ public class RouterActivity extends AppCompatActivity { if (selectedChoiceKey.equals(alwaysAskKey)) { final List choices = getChoicesForService(currentService, currentLinkType); - if (choices.size() == 1) { - handleChoice(choices.get(0).key); - } else if (choices.size() == 0) { - handleChoice(showInfoKey); - } else { - showDialog(choices); + switch (choices.size()) { + case 1: + handleChoice(choices.get(0).key); + break; + case 0: + handleChoice(showInfoKey); + break; + default: + showDialog(choices); + break; } } else if (selectedChoiceKey.equals(showInfoKey)) { handleChoice(showInfoKey); diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.java b/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.java index 701e18cbf..09d33bd8a 100644 --- a/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.java +++ b/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.java @@ -4,7 +4,6 @@ import android.app.Activity; import android.content.Context; import android.content.DialogInterface; import android.os.AsyncTask; -import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; import android.webkit.WebView; @@ -17,7 +16,7 @@ import java.lang.ref.WeakReference; public class LicenseFragmentHelper extends AsyncTask { - WeakReference weakReference; + final WeakReference weakReference; private License license; public LicenseFragmentHelper(@Nullable Activity activity) { @@ -78,18 +77,18 @@ public class LicenseFragmentHelper extends AsyncTask { throw new NullPointerException("license is null"); } - String licenseContent = ""; + StringBuilder licenseContent = new StringBuilder(); String webViewData; try { BufferedReader in = new BufferedReader(new InputStreamReader(context.getAssets().open(license.getFilename()), "UTF-8")); String str; while ((str = in.readLine()) != null) { - licenseContent += str; + licenseContent.append(str); } in.close(); // split the HTML file and insert the stylesheet into the HEAD of the file - String[] insert = licenseContent.split(""); + String[] insert = licenseContent.toString().split(""); webViewData = insert[0] + "" + insert[1]; diff --git a/app/src/main/java/org/schabi/newpipe/database/BasicDAO.java b/app/src/main/java/org/schabi/newpipe/database/BasicDAO.java index 425c122ca..13117145a 100644 --- a/app/src/main/java/org/schabi/newpipe/database/BasicDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/BasicDAO.java @@ -30,7 +30,7 @@ public interface BasicDAO { /* Deletes */ @Delete - int delete(final Entity entity); + void delete(final Entity entity); @Delete int delete(final Collection entities); @@ -42,5 +42,5 @@ public interface BasicDAO { int update(final Entity entity); @Update - int update(final Collection entities); + void update(final Collection entities); } diff --git a/app/src/main/java/org/schabi/newpipe/database/history/dao/SearchHistoryDAO.java b/app/src/main/java/org/schabi/newpipe/database/history/dao/SearchHistoryDAO.java index b0a3c3a3c..83e629e48 100644 --- a/app/src/main/java/org/schabi/newpipe/database/history/dao/SearchHistoryDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/history/dao/SearchHistoryDAO.java @@ -4,7 +4,6 @@ import android.arch.persistence.room.Dao; import android.arch.persistence.room.Query; import android.support.annotation.Nullable; -import org.schabi.newpipe.database.BasicDAO; import org.schabi.newpipe.database.history.model.SearchHistoryEntry; import java.util.List; diff --git a/app/src/main/java/org/schabi/newpipe/database/history/dao/StreamHistoryDAO.java b/app/src/main/java/org/schabi/newpipe/database/history/dao/StreamHistoryDAO.java index fd7a1b96f..847153e12 100644 --- a/app/src/main/java/org/schabi/newpipe/database/history/dao/StreamHistoryDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/history/dao/StreamHistoryDAO.java @@ -5,7 +5,6 @@ import android.arch.persistence.room.Dao; import android.arch.persistence.room.Query; import android.support.annotation.Nullable; -import org.schabi.newpipe.database.BasicDAO; import org.schabi.newpipe.database.history.model.StreamHistoryEntry; import org.schabi.newpipe.database.stream.StreamStatisticsEntry; import org.schabi.newpipe.database.history.model.StreamHistoryEntity; diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistDAO.java index 88d5645af..7a6282f96 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistDAO.java @@ -2,7 +2,6 @@ package org.schabi.newpipe.database.playlist.dao; import android.arch.persistence.room.Dao; import android.arch.persistence.room.Query; -import android.arch.persistence.room.Transaction; import org.schabi.newpipe.database.BasicDAO; import org.schabi.newpipe.database.playlist.model.PlaylistEntity; @@ -12,7 +11,6 @@ import java.util.List; import io.reactivex.Flowable; import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_ID; -import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_NAME; import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_TABLE; @Dao diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java index 8bf1ea696..8b6d62ca4 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java @@ -8,7 +8,6 @@ import org.schabi.newpipe.database.BasicDAO; import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry; import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity; -import org.schabi.newpipe.database.stream.model.StreamEntity; import java.util.List; diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java index a3ec1b5f2..bfda8eeec 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.java @@ -5,8 +5,6 @@ import android.arch.persistence.room.Entity; import android.arch.persistence.room.Index; import android.arch.persistence.room.PrimaryKey; -import java.util.Date; - import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_NAME; import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_TABLE; diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java index e2f2c8b08..ab917a22b 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java @@ -6,7 +6,6 @@ import android.arch.persistence.room.Ignore; import android.arch.persistence.room.Index; import android.arch.persistence.room.PrimaryKey; -import org.schabi.newpipe.database.LocalItem; import org.schabi.newpipe.database.playlist.PlaylistLocalItem; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.util.Constants; diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/dao/StreamDAO.java b/app/src/main/java/org/schabi/newpipe/database/stream/dao/StreamDAO.java index 63f9e5940..396a29fca 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/dao/StreamDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/stream/dao/StreamDAO.java @@ -10,7 +10,6 @@ import org.schabi.newpipe.database.BasicDAO; import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity; import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.database.history.model.StreamHistoryEntity; -import org.schabi.newpipe.database.stream.model.StreamStateEntity; import java.util.ArrayList; import java.util.List; @@ -23,7 +22,6 @@ import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_SERVI import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_TABLE; import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_URL; import static org.schabi.newpipe.database.history.model.StreamHistoryEntity.STREAM_HISTORY_TABLE; -import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_STATE_TABLE; @Dao public abstract class StreamDAO implements BasicDAO { diff --git a/app/src/main/java/org/schabi/newpipe/download/DeleteDownloadManager.java b/app/src/main/java/org/schabi/newpipe/download/DeleteDownloadManager.java index f2912a6fa..5a2d4a486 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DeleteDownloadManager.java +++ b/app/src/main/java/org/schabi/newpipe/download/DeleteDownloadManager.java @@ -28,11 +28,11 @@ public class DeleteDownloadManager { private static final String KEY_STATE = "delete_manager_state"; - private View mView; - private HashSet mPendingMap; - private List mDisposableList; + private final View mView; + private final HashSet mPendingMap; + private final List mDisposableList; private DownloadManager mDownloadManager; - private PublishSubject publishSubject = PublishSubject.create(); + private final PublishSubject publishSubject = PublishSubject.create(); DeleteDownloadManager(Activity activity) { mPendingMap = new HashSet<>(); diff --git a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java index 75f05cd16..9bbda6032 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java @@ -55,7 +55,7 @@ public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheck private StreamItemAdapter audioStreamsAdapter; private StreamItemAdapter videoStreamsAdapter; - private CompositeDisposable disposables = new CompositeDisposable(); + private final CompositeDisposable disposables = new CompositeDisposable(); private EditText nameEditText; private Spinner streamsSpinner; 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 589d15bd4..acee1f111 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java @@ -32,7 +32,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import icepick.State; import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.functions.Consumer; import static org.schabi.newpipe.util.AnimationUtils.animateView; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java index 4ee90f083..948e9377d 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java @@ -2,7 +2,6 @@ package org.schabi.newpipe.fragments; import android.os.Bundle; import android.support.annotation.Nullable; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/StackItem.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/StackItem.java index b8957f33c..f7f8ad702 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/StackItem.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/StackItem.java @@ -3,9 +3,9 @@ package org.schabi.newpipe.fragments.detail; import java.io.Serializable; class StackItem implements Serializable { - private int serviceId; + private final int serviceId; private String title; - private String url; + private final String url; StackItem(int serviceId, String url, String title) { this.serviceId = serviceId; 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 c726f8cee..9ab40e81c 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 @@ -33,12 +33,14 @@ import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.ViewParent; import android.widget.AdapterView; import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; +import android.widget.ScrollView; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; @@ -64,19 +66,17 @@ import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.fragments.BackPressable; import org.schabi.newpipe.fragments.BaseStateFragment; -import org.schabi.newpipe.local.history.HistoryRecordManager; -import org.schabi.newpipe.report.ErrorActivity; -import org.schabi.newpipe.util.StreamItemAdapter; -import org.schabi.newpipe.util.StreamItemAdapter.StreamSizeWrapper; -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.local.dialog.PlaylistAppendDialog; +import org.schabi.newpipe.local.history.HistoryRecordManager; 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.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.SinglePlayQueue; +import org.schabi.newpipe.report.ErrorActivity; import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.ExtractorHelper; @@ -87,6 +87,8 @@ import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.OnClickGesture; import org.schabi.newpipe.util.PermissionHelper; +import org.schabi.newpipe.util.StreamItemAdapter; +import org.schabi.newpipe.util.StreamItemAdapter.StreamSizeWrapper; import org.schabi.newpipe.util.ThemeHelper; import java.io.Serializable; @@ -154,6 +156,7 @@ public class VideoDetailFragment private View videoTitleRoot; private TextView videoTitleTextView; + @Nullable private ImageView videoTitleToggleArrow; private TextView videoCountView; @@ -415,14 +418,16 @@ public class VideoDetailFragment } private void toggleTitleAndDescription() { - if (videoDescriptionRootLayout.getVisibility() == View.VISIBLE) { - videoTitleTextView.setMaxLines(1); - videoDescriptionRootLayout.setVisibility(View.GONE); - videoTitleToggleArrow.setImageResource(R.drawable.arrow_down); - } else { - videoTitleTextView.setMaxLines(10); - videoDescriptionRootLayout.setVisibility(View.VISIBLE); - videoTitleToggleArrow.setImageResource(R.drawable.arrow_up); + if (videoTitleToggleArrow != null) { //it is null for tablets + if (videoDescriptionRootLayout.getVisibility() == View.VISIBLE) { + videoTitleTextView.setMaxLines(1); + videoDescriptionRootLayout.setVisibility(View.GONE); + videoTitleToggleArrow.setImageResource(R.drawable.arrow_down); + } else { + videoTitleTextView.setMaxLines(10); + videoDescriptionRootLayout.setVisibility(View.VISIBLE); + videoTitleToggleArrow.setImageResource(R.drawable.arrow_up); + } } } @@ -622,8 +627,11 @@ public class VideoDetailFragment relatedStreamsView.addView( infoItemBuilder.buildView(relatedStreamsView, info.getNextVideo())); relatedStreamsView.addView(getSeparatorView()); - relatedStreamRootLayout.setVisibility(View.VISIBLE); - } else nextStreamTitle.setVisibility(View.GONE); + setRelatedStreamsVisibility(View.VISIBLE); + } else { + nextStreamTitle.setVisibility(View.GONE); + setRelatedStreamsVisibility(View.GONE); + } if (info.getRelatedStreams() != null && !info.getRelatedStreams().isEmpty() && showRelatedStreams) { @@ -639,13 +647,13 @@ public class VideoDetailFragment } //if (DEBUG) Log.d(TAG, "Total time " + ((System.nanoTime() - first) / 1000000L) + "ms"); - relatedStreamRootLayout.setVisibility(View.VISIBLE); + setRelatedStreamsVisibility(View.VISIBLE); relatedStreamExpandButton.setVisibility(View.VISIBLE); relatedStreamExpandButton.setImageDrawable(ContextCompat.getDrawable( activity, ThemeHelper.resolveResourceIdFromAttr(activity, R.attr.expand))); } else { - if (info.getNextVideo() == null) relatedStreamRootLayout.setVisibility(View.GONE); + if (info.getNextVideo() == null) setRelatedStreamsVisibility(View.GONE); relatedStreamExpandButton.setVisibility(View.GONE); } } @@ -760,7 +768,7 @@ public class VideoDetailFragment * Stack that contains the "navigation history".
* The peek is the current video. */ - protected LinkedList stack = new LinkedList<>(); + protected final LinkedList stack = new LinkedList<>(); public void clearHistory() { stack.clear(); @@ -1114,8 +1122,16 @@ public class VideoDetailFragment animateView(videoTitleTextView, true, 0); videoDescriptionRootLayout.setVisibility(View.GONE); - videoTitleToggleArrow.setImageResource(R.drawable.arrow_down); - videoTitleToggleArrow.setVisibility(View.GONE); + if (videoTitleToggleArrow != null) { //phone + videoTitleToggleArrow.setImageResource(R.drawable.arrow_down); + videoTitleToggleArrow.setVisibility(View.GONE); + } else { //tablet + final View related = (View) relatedStreamRootLayout.getParent(); + //don`t need to hide it if related streams are disabled + if (related.getVisibility() == View.VISIBLE) { + related.setVisibility(View.INVISIBLE); + } + } videoTitleRoot.setClickable(false); imageLoader.cancelDisplayTask(thumbnailImageView); @@ -1190,11 +1206,15 @@ public class VideoDetailFragment detailDurationView.setVisibility(View.GONE); } - videoTitleRoot.setClickable(true); - videoTitleToggleArrow.setVisibility(View.VISIBLE); - videoTitleToggleArrow.setImageResource(R.drawable.arrow_down); videoDescriptionView.setVisibility(View.GONE); - videoDescriptionRootLayout.setVisibility(View.GONE); + if (videoTitleToggleArrow != null) { + videoTitleRoot.setClickable(true); + videoTitleToggleArrow.setVisibility(View.VISIBLE); + videoTitleToggleArrow.setImageResource(R.drawable.arrow_down); + videoDescriptionRootLayout.setVisibility(View.GONE); + } else { + videoDescriptionRootLayout.setVisibility(View.VISIBLE); + } if (!TextUtils.isEmpty(info.getUploadDate())) { videoUploadDateView.setText(Localization.localizeDate(activity, info.getUploadDate())); } @@ -1242,6 +1262,11 @@ public class VideoDetailFragment // Only auto play in the first open autoPlayEnabled = false; } + + final ViewParent related = relatedStreamRootLayout.getParent(); + if (related instanceof ScrollView) { + ((ScrollView) related).scrollTo(0, 0); + } } @@ -1299,4 +1324,13 @@ public class VideoDetailFragment showError(getString(R.string.blocked_by_gema), false, R.drawable.gruese_die_gema); } + + private void setRelatedStreamsVisibility(int visibility) { + final ViewParent parent = relatedStreamRootLayout.getParent(); + if (parent instanceof ScrollView) { + ((ScrollView) parent).setVisibility(visibility); + } else { + relatedStreamRootLayout.setVisibility(visibility); + } + } } \ No newline at end of file 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 c70ea2b19..0816334ea 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 @@ -3,10 +3,15 @@ package org.schabi.newpipe.fragments.list; import android.app.Activity; import android.content.Context; import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.content.res.Resources; import android.os.Bundle; +import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; @@ -21,9 +26,9 @@ 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.local.dialog.PlaylistAppendDialog; import org.schabi.newpipe.info_list.InfoItemDialog; import org.schabi.newpipe.info_list.InfoListAdapter; +import org.schabi.newpipe.local.dialog.PlaylistAppendDialog; import org.schabi.newpipe.player.playqueue.SinglePlayQueue; import org.schabi.newpipe.report.ErrorActivity; import org.schabi.newpipe.util.NavigationHelper; @@ -36,7 +41,7 @@ import java.util.Queue; import static org.schabi.newpipe.util.AnimationUtils.animateView; -public abstract class BaseListFragment extends BaseStateFragment implements ListViewContract, StateSaver.WriteRead { +public abstract class BaseListFragment extends BaseStateFragment implements ListViewContract, StateSaver.WriteRead, SharedPreferences.OnSharedPreferenceChangeListener { /*////////////////////////////////////////////////////////////////////////// // Views @@ -44,6 +49,9 @@ public abstract class BaseListFragment extends BaseStateFragment implem protected InfoListAdapter infoListAdapter; protected RecyclerView itemsList; + private int updateFlags = 0; + + private static final int LIST_MODE_UPDATE_FLAG = 0x32; /*////////////////////////////////////////////////////////////////////////// // LifeCycle @@ -59,12 +67,31 @@ public abstract class BaseListFragment extends BaseStateFragment implem public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); + PreferenceManager.getDefaultSharedPreferences(activity) + .registerOnSharedPreferenceChangeListener(this); } @Override public void onDestroy() { super.onDestroy(); StateSaver.onDestroy(savedState); + PreferenceManager.getDefaultSharedPreferences(activity) + .unregisterOnSharedPreferenceChangeListener(this); + } + + @Override + public void onResume() { + super.onResume(); + + if (updateFlags != 0) { + if ((updateFlags & LIST_MODE_UPDATE_FLAG) != 0) { + final boolean useGrid = isGridLayout(); + itemsList.setLayoutManager(useGrid ? getGridLayoutManager() : getListLayoutManager()); + infoListAdapter.setGridItemVariants(useGrid); + infoListAdapter.notifyDataSetChanged(); + } + updateFlags = 0; + } } /*////////////////////////////////////////////////////////////////////////// @@ -119,13 +146,25 @@ public abstract class BaseListFragment extends BaseStateFragment implem return new LinearLayoutManager(activity); } + protected RecyclerView.LayoutManager getGridLayoutManager() { + final Resources resources = activity.getResources(); + int width = resources.getDimensionPixelSize(R.dimen.video_item_grid_thumbnail_image_width); + width += (24 * resources.getDisplayMetrics().density); + final int spanCount = (int) Math.floor(resources.getDisplayMetrics().widthPixels / (double)width); + final GridLayoutManager lm = new GridLayoutManager(activity, spanCount); + lm.setSpanSizeLookup(infoListAdapter.getSpanSizeLookup(spanCount)); + return lm; + } + @Override protected void initViews(View rootView, Bundle savedInstanceState) { super.initViews(rootView, savedInstanceState); + final boolean useGrid = isGridLayout(); itemsList = rootView.findViewById(R.id.items_list); - itemsList.setLayoutManager(getListLayoutManager()); + itemsList.setLayoutManager(useGrid ? getGridLayoutManager() : getListLayoutManager()); + infoListAdapter.setGridItemVariants(useGrid); infoListAdapter.setFooter(getListFooter()); infoListAdapter.setHeader(getListHeader()); @@ -308,4 +347,22 @@ public abstract class BaseListFragment extends BaseStateFragment implem public void handleNextItems(N result) { isLoading.set(false); } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (key.equals(getString(R.string.list_view_mode_key))) { + updateFlags |= LIST_MODE_UPDATE_FLAG; + } + } + + protected boolean isGridLayout() { + final String list_mode = PreferenceManager.getDefaultSharedPreferences(activity).getString(getString(R.string.list_view_mode_key), getString(R.string.list_view_mode_value)); + if ("auto".equals(list_mode)) { + final Configuration configuration = getResources().getConfiguration(); + return configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + && configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE); + } else { + return "grid".equals(list_mode); + } + } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java index e702c602f..5d042c949 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java @@ -8,9 +8,6 @@ import android.view.View; import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.ListInfo; -import org.schabi.newpipe.extractor.NewPipe; -import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; -import org.schabi.newpipe.extractor.linkhandler.LinkHandler; import org.schabi.newpipe.util.Constants; import java.util.Queue; @@ -19,7 +16,6 @@ import icepick.State; import io.reactivex.Single; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; -import io.reactivex.functions.Consumer; import io.reactivex.schedulers.Schedulers; public abstract class BaseListInfoFragment 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 9a52b8d12..6a3b3eb50 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 @@ -68,7 +68,7 @@ import static org.schabi.newpipe.util.AnimationUtils.animateView; public class ChannelFragment extends BaseListInfoFragment { - private CompositeDisposable disposables = new CompositeDisposable(); + private final CompositeDisposable disposables = new CompositeDisposable(); private Disposable subscribeButtonMonitor; private SubscriptionService subscriptionService; @@ -90,8 +90,6 @@ public class ChannelFragment extends BaseListInfoFragment { private MenuItem menuRssButton; - private boolean mIsVisibleToUser = false; - public static ChannelFragment getInstance(int serviceId, String url, String name) { ChannelFragment instance = new ChannelFragment(); instance.setInitialData(serviceId, url, name); @@ -105,7 +103,6 @@ public class ChannelFragment extends BaseListInfoFragment { @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); - mIsVisibleToUser = isVisibleToUser; if(activity != null && useAsFrontPage && isVisibleToUser) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java index 833d0f55e..92138f7db 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java @@ -5,7 +5,6 @@ import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.app.ActionBar; -import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -19,8 +18,6 @@ import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.kiosk.KioskInfo; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory; -import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; -import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory; import org.schabi.newpipe.fragments.list.BaseListInfoFragment; import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.util.ExtractorHelper; 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 b7a42791c..0019a3819 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 @@ -20,7 +20,6 @@ import android.widget.TextView; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; -import org.schabi.newpipe.App; import org.schabi.newpipe.NewPipeDatabase; import org.schabi.newpipe.R; import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity; @@ -30,7 +29,6 @@ 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.StreamInfoItem; -import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.fragments.list.BaseListInfoFragment; import org.schabi.newpipe.info_list.InfoItemDialog; import org.schabi.newpipe.local.playlist.RemotePlaylistManager; 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 a699e28bc..19c7d463e 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 @@ -122,12 +122,11 @@ public class SearchFragment private String nextPageUrl; private String contentCountry; private boolean isSuggestionsEnabled = true; - private boolean isSearchHistoryEnabled = true; - private PublishSubject suggestionPublisher = PublishSubject.create(); + private final PublishSubject suggestionPublisher = PublishSubject.create(); private Disposable searchDisposable; private Disposable suggestionDisposable; - private CompositeDisposable disposables = new CompositeDisposable(); + private final CompositeDisposable disposables = new CompositeDisposable(); private SuggestionListAdapter suggestionListAdapter; private HistoryRecordManager historyRecordManager; @@ -173,7 +172,7 @@ public class SearchFragment suggestionListAdapter = new SuggestionListAdapter(activity); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); - isSearchHistoryEnabled = preferences.getBoolean(getString(R.string.enable_search_history_key), true); + boolean isSearchHistoryEnabled = preferences.getBoolean(getString(R.string.enable_search_history_key), true); suggestionListAdapter.setShowSuggestionHistory(isSearchHistoryEnabled); historyRecordManager = new HistoryRecordManager(context); diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java index 78867c81f..f473e5d08 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java @@ -45,7 +45,7 @@ public class InfoItemBuilder { private static final String TAG = InfoItemBuilder.class.toString(); private final Context context; - private ImageLoader imageLoader = ImageLoader.getInstance(); + private final ImageLoader imageLoader = ImageLoader.getInstance(); private OnClickGesture onStreamSelectedListener; private OnClickGesture onChannelSelectedListener; diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java index 88aa76887..fd0e9f528 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java @@ -5,7 +5,6 @@ import android.app.AlertDialog; import android.content.DialogInterface; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java index cf12deb6f..15fdcad05 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java @@ -1,6 +1,7 @@ package org.schabi.newpipe.info_list; import android.app.Activity; +import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.View; @@ -12,9 +13,12 @@ import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.info_list.holder.ChannelInfoItemHolder; import org.schabi.newpipe.info_list.holder.ChannelMiniInfoItemHolder; +import org.schabi.newpipe.info_list.holder.ChannelGridInfoItemHolder; import org.schabi.newpipe.info_list.holder.InfoItemHolder; +import org.schabi.newpipe.info_list.holder.PlaylistGridInfoItemHolder; import org.schabi.newpipe.info_list.holder.PlaylistInfoItemHolder; import org.schabi.newpipe.info_list.holder.PlaylistMiniInfoItemHolder; +import org.schabi.newpipe.info_list.holder.StreamGridInfoItemHolder; import org.schabi.newpipe.info_list.holder.StreamInfoItemHolder; import org.schabi.newpipe.info_list.holder.StreamMiniInfoItemHolder; import org.schabi.newpipe.util.FallbackViewHolder; @@ -52,14 +56,18 @@ public class InfoListAdapter extends RecyclerView.Adapter infoItemList; private boolean useMiniVariant = false; + private boolean useGridVariant = false; private boolean showFooter = false; private View header = null; private View footer = null; @@ -94,6 +102,10 @@ public class InfoListAdapter extends RecyclerView.Adapter data) { if (data != null) { if (DEBUG) { @@ -206,11 +218,11 @@ public class InfoListAdapter extends RecyclerView.Adapter { + if (itemBuilder.getOnChannelSelectedListener() != null) { + itemBuilder.getOnChannelSelectedListener().held(item); + } + return true; + }); } protected String getDetailLine(final ChannelInfoItem item) { diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistGridInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistGridInfoItemHolder.java new file mode 100644 index 000000000..96b9c90a7 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistGridInfoItemHolder.java @@ -0,0 +1,13 @@ +package org.schabi.newpipe.info_list.holder; + +import android.view.ViewGroup; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.info_list.InfoItemBuilder; + +public class PlaylistGridInfoItemHolder extends PlaylistMiniInfoItemHolder { + + public PlaylistGridInfoItemHolder(InfoItemBuilder infoItemBuilder, ViewGroup parent) { + super(infoItemBuilder, R.layout.list_playlist_grid_item, parent); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamGridInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamGridInfoItemHolder.java new file mode 100644 index 000000000..a2e585857 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamGridInfoItemHolder.java @@ -0,0 +1,13 @@ +package org.schabi.newpipe.info_list.holder; + +import android.view.ViewGroup; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.info_list.InfoItemBuilder; + +public class StreamGridInfoItemHolder extends StreamMiniInfoItemHolder { + + public StreamGridInfoItemHolder(InfoItemBuilder infoItemBuilder, ViewGroup parent) { + super(infoItemBuilder, R.layout.list_stream_grid_item, parent); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java b/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java index 5192aa2ab..abdf82353 100644 --- a/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java @@ -1,8 +1,13 @@ package org.schabi.newpipe.local; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.content.res.Resources; import android.os.Bundle; +import android.preference.PreferenceManager; import android.support.v4.app.Fragment; import android.support.v7.app.ActionBar; +import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; @@ -25,7 +30,7 @@ import static org.schabi.newpipe.util.AnimationUtils.animateView; * called and is memory efficient when in backstack. * */ public abstract class BaseLocalListFragment extends BaseStateFragment - implements ListViewContract { + implements ListViewContract, SharedPreferences.OnSharedPreferenceChangeListener { /*////////////////////////////////////////////////////////////////////////// // Views @@ -36,6 +41,9 @@ public abstract class BaseLocalListFragment extends BaseStateFragment protected LocalItemListAdapter itemListAdapter; protected RecyclerView itemsList; + private int updateFlags = 0; + + private static final int LIST_MODE_UPDATE_FLAG = 0x32; /*////////////////////////////////////////////////////////////////////////// // Lifecycle - Creation @@ -45,6 +53,29 @@ public abstract class BaseLocalListFragment extends BaseStateFragment public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); + PreferenceManager.getDefaultSharedPreferences(activity) + .registerOnSharedPreferenceChangeListener(this); + } + + @Override + public void onDestroy() { + super.onDestroy(); + PreferenceManager.getDefaultSharedPreferences(activity) + .unregisterOnSharedPreferenceChangeListener(this); + } + + @Override + public void onResume() { + super.onResume(); + if (updateFlags != 0) { + if ((updateFlags & LIST_MODE_UPDATE_FLAG) != 0) { + final boolean useGrid = isGridLayout(); + itemsList.setLayoutManager(useGrid ? getGridLayoutManager() : getListLayoutManager()); + itemListAdapter.setGridItemVariants(useGrid); + itemListAdapter.notifyDataSetChanged(); + } + updateFlags = 0; + } } /*////////////////////////////////////////////////////////////////////////// @@ -59,6 +90,16 @@ public abstract class BaseLocalListFragment extends BaseStateFragment return activity.getLayoutInflater().inflate(R.layout.pignate_footer, itemsList, false); } + protected RecyclerView.LayoutManager getGridLayoutManager() { + final Resources resources = activity.getResources(); + int width = resources.getDimensionPixelSize(R.dimen.video_item_grid_thumbnail_image_width); + width += (24 * resources.getDisplayMetrics().density); + final int spanCount = (int) Math.floor(resources.getDisplayMetrics().widthPixels / (double)width); + final GridLayoutManager lm = new GridLayoutManager(activity, spanCount); + lm.setSpanSizeLookup(itemListAdapter.getSpanSizeLookup(spanCount)); + return lm; + } + protected RecyclerView.LayoutManager getListLayoutManager() { return new LinearLayoutManager(activity); } @@ -67,10 +108,13 @@ public abstract class BaseLocalListFragment extends BaseStateFragment protected void initViews(View rootView, Bundle savedInstanceState) { super.initViews(rootView, savedInstanceState); - itemsList = rootView.findViewById(R.id.items_list); - itemsList.setLayoutManager(getListLayoutManager()); - itemListAdapter = new LocalItemListAdapter(activity); + + final boolean useGrid = isGridLayout(); + itemsList = rootView.findViewById(R.id.items_list); + itemsList.setLayoutManager(useGrid ? getGridLayoutManager() : getListLayoutManager()); + + itemListAdapter.setGridItemVariants(useGrid); itemListAdapter.setHeader(headerRootView = getListHeader()); itemListAdapter.setFooter(footerRootView = getListFooter()); @@ -174,4 +218,22 @@ public abstract class BaseLocalListFragment extends BaseStateFragment resetFragment(); return super.onError(exception); } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (key.equals(getString(R.string.list_view_mode_key))) { + updateFlags |= LIST_MODE_UPDATE_FLAG; + } + } + + protected boolean isGridLayout() { + final String list_mode = PreferenceManager.getDefaultSharedPreferences(activity).getString(getString(R.string.list_view_mode_key), getString(R.string.list_view_mode_value)); + if ("auto".equals(list_mode)) { + final Configuration configuration = getResources().getConfiguration(); + return configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + && configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE); + } else { + return "grid".equals(list_mode); + } + } } diff --git a/app/src/main/java/org/schabi/newpipe/local/LocalItemBuilder.java b/app/src/main/java/org/schabi/newpipe/local/LocalItemBuilder.java index 148f93075..0fbab0398 100644 --- a/app/src/main/java/org/schabi/newpipe/local/LocalItemBuilder.java +++ b/app/src/main/java/org/schabi/newpipe/local/LocalItemBuilder.java @@ -33,7 +33,7 @@ public class LocalItemBuilder { private static final String TAG = LocalItemBuilder.class.toString(); private final Context context; - private ImageLoader imageLoader = ImageLoader.getInstance(); + private final ImageLoader imageLoader = ImageLoader.getInstance(); private OnClickGesture onSelectedListener; diff --git a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java index 99937b58c..e298dedd3 100644 --- a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java @@ -1,18 +1,21 @@ package org.schabi.newpipe.local; import android.app.Activity; +import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.View; import android.view.ViewGroup; import org.schabi.newpipe.database.LocalItem; -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.LocalPlaylistGridItemHolder; import org.schabi.newpipe.local.holder.LocalPlaylistItemHolder; +import org.schabi.newpipe.local.holder.LocalPlaylistStreamGridItemHolder; import org.schabi.newpipe.local.holder.LocalPlaylistStreamItemHolder; +import org.schabi.newpipe.local.holder.LocalStatisticStreamGridItemHolder; import org.schabi.newpipe.local.holder.LocalStatisticStreamItemHolder; +import org.schabi.newpipe.local.holder.RemotePlaylistGridItemHolder; import org.schabi.newpipe.local.holder.RemotePlaylistItemHolder; import org.schabi.newpipe.util.FallbackViewHolder; import org.schabi.newpipe.util.Localization; @@ -52,14 +55,19 @@ public class LocalItemListAdapter extends RecyclerView.Adapter localItems; private final DateFormat dateFormat; private boolean showFooter = false; + private boolean useGridVariant = false; private View header = null; private View footer = null; @@ -134,6 +142,10 @@ public class LocalItemListAdapter extends RecyclerView.Adapter savedObjects) throws Exception { + public void readFrom(@NonNull Queue savedObjects) { streamEntities = (List) savedObjects.poll(); } diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.java b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.java index 634bea62b..f1bb01734 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.java @@ -36,8 +36,6 @@ import io.reactivex.MaybeObserver; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; -import io.reactivex.functions.Consumer; -import io.reactivex.functions.Predicate; public class FeedFragment extends BaseListFragment, Void> { diff --git a/app/src/main/java/org/schabi/newpipe/local/history/HistoryEntryAdapter.java b/app/src/main/java/org/schabi/newpipe/local/history/HistoryEntryAdapter.java index 2cb1add5d..09549346b 100644 --- a/app/src/main/java/org/schabi/newpipe/local/history/HistoryEntryAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/local/history/HistoryEntryAdapter.java @@ -1,7 +1,6 @@ package org.schabi.newpipe.local.history; import android.content.Context; -import android.content.res.Resources; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; diff --git a/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java b/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java index d3d824103..56453773a 100644 --- a/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java @@ -45,7 +45,6 @@ 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; diff --git a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java index 95aeb09d7..32083fd42 100644 --- a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java @@ -21,7 +21,6 @@ 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.fragments.list.BaseListFragment; import org.schabi.newpipe.local.BaseLocalListFragment; import org.schabi.newpipe.info_list.InfoItemDialog; import org.schabi.newpipe.player.playqueue.PlayQueue; @@ -57,7 +56,7 @@ public class StatisticsPlaylistFragment /* Used for independent events */ private Subscription databaseSubscription; private HistoryRecordManager recordManager; - private CompositeDisposable disposables = new CompositeDisposable(); + private final CompositeDisposable disposables = new CompositeDisposable(); private enum StatisticSortMode { LAST_PLAYED, diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistGridItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistGridItemHolder.java new file mode 100644 index 000000000..4276cf721 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistGridItemHolder.java @@ -0,0 +1,13 @@ +package org.schabi.newpipe.local.holder; + +import android.view.ViewGroup; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.local.LocalItemBuilder; + +public class LocalPlaylistGridItemHolder extends LocalPlaylistItemHolder { + + public LocalPlaylistGridItemHolder(LocalItemBuilder infoItemBuilder, ViewGroup parent) { + super(infoItemBuilder, R.layout.list_playlist_grid_item, parent); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java index 1a5ec63bf..8743684ee 100644 --- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistItemHolder.java @@ -16,6 +16,10 @@ public class LocalPlaylistItemHolder extends PlaylistItemHolder { super(infoItemBuilder, parent); } + LocalPlaylistItemHolder(LocalItemBuilder infoItemBuilder, int layoutId, ViewGroup parent) { + super(infoItemBuilder, layoutId, parent); + } + @Override public void updateFromItem(final LocalItem localItem, final DateFormat dateFormat) { if (!(localItem instanceof PlaylistMetadataEntry)) return; diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamGridItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamGridItemHolder.java new file mode 100644 index 000000000..6986713bb --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalPlaylistStreamGridItemHolder.java @@ -0,0 +1,13 @@ +package org.schabi.newpipe.local.holder; + +import android.view.ViewGroup; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.local.LocalItemBuilder; + +public class LocalPlaylistStreamGridItemHolder extends LocalPlaylistStreamItemHolder { + + public LocalPlaylistStreamGridItemHolder(LocalItemBuilder infoItemBuilder, ViewGroup parent) { + super(infoItemBuilder, R.layout.list_stream_playlist_grid_item, parent); //TODO + } +} diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamGridItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamGridItemHolder.java new file mode 100644 index 000000000..792ad92f0 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamGridItemHolder.java @@ -0,0 +1,13 @@ +package org.schabi.newpipe.local.holder; + +import android.view.ViewGroup; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.local.LocalItemBuilder; + +public class LocalStatisticStreamGridItemHolder extends LocalStatisticStreamItemHolder { + + public LocalStatisticStreamGridItemHolder(LocalItemBuilder infoItemBuilder, ViewGroup parent) { + super(infoItemBuilder, R.layout.list_stream_grid_item, parent); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java index b2a04ca9c..57a5794e3 100644 --- a/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.local.holder; +import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.view.View; import android.view.ViewGroup; @@ -42,10 +43,15 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder { public final TextView itemVideoTitleView; public final TextView itemUploaderView; public final TextView itemDurationView; + @Nullable public final TextView itemAdditionalDetails; - public LocalStatisticStreamItemHolder(LocalItemBuilder infoItemBuilder, ViewGroup parent) { - super(infoItemBuilder, R.layout.list_stream_item, parent); + public LocalStatisticStreamItemHolder(LocalItemBuilder itemBuilder, ViewGroup parent) { + this(itemBuilder, R.layout.list_stream_item, parent); + } + + LocalStatisticStreamItemHolder(LocalItemBuilder infoItemBuilder, int layoutId, ViewGroup parent) { + super(infoItemBuilder, layoutId, parent); itemThumbnailView = itemView.findViewById(R.id.itemThumbnailView); itemVideoTitleView = itemView.findViewById(R.id.itemVideoTitleView); @@ -80,7 +86,9 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder { itemDurationView.setVisibility(View.GONE); } - itemAdditionalDetails.setText(getStreamInfoDetailLine(item, dateFormat)); + if (itemAdditionalDetails != null) { + itemAdditionalDetails.setText(getStreamInfoDetailLine(item, dateFormat)); + } // Default thumbnail is shown on error, while loading and if the url is empty itemBuilder.displayImage(item.thumbnailUrl, itemThumbnailView, diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistGridItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistGridItemHolder.java new file mode 100644 index 000000000..5ac18fccb --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistGridItemHolder.java @@ -0,0 +1,13 @@ +package org.schabi.newpipe.local.holder; + +import android.view.ViewGroup; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.local.LocalItemBuilder; + +public class RemotePlaylistGridItemHolder extends RemotePlaylistItemHolder { + + public RemotePlaylistGridItemHolder(LocalItemBuilder infoItemBuilder, ViewGroup parent) { + super(infoItemBuilder, R.layout.list_playlist_grid_item, parent); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java index 12d3063b0..5b2a88d38 100644 --- a/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/local/holder/RemotePlaylistItemHolder.java @@ -16,6 +16,10 @@ public class RemotePlaylistItemHolder extends PlaylistItemHolder { super(infoItemBuilder, parent); } + RemotePlaylistItemHolder(LocalItemBuilder infoItemBuilder, int layoutId, ViewGroup parent) { + super(infoItemBuilder, layoutId, parent); + } + @Override public void updateFromItem(final LocalItem localItem, final DateFormat dateFormat) { if (!(localItem instanceof PlaylistRemoteEntity)) return; diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 35a1530c9..f400061e1 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -459,7 +459,11 @@ public class LocalPlaylistFragment extends BaseLocalListFragment> { +public class SubscriptionFragment extends BaseStateFragment> implements SharedPreferences.OnSharedPreferenceChangeListener { private static final int REQUEST_EXPORT_CODE = 666; private static final int REQUEST_IMPORT_CODE = 667; @@ -80,8 +89,10 @@ public class SubscriptionFragment extends BaseStateFragment() { - @Override + public void selected(ChannelInfoItem selectedItem) { final FragmentManager fragmentManager = getFM(); NavigationHelper.openChannelFragment(fragmentManager, @@ -328,6 +369,11 @@ public class SubscriptionFragment extends BaseStateFragment importExportOptions.switchState()); } + private void showLongTapDialog(ChannelInfoItem selectedItem) { + final Context context = getContext(); + final Activity activity = getActivity(); + if (context == null || context.getResources() == null || getActivity() == null) return; + + final String[] commands = new String[]{ + context.getResources().getString(R.string.share), + context.getResources().getString(R.string.unsubscribe) + }; + + final DialogInterface.OnClickListener actions = (dialogInterface, i) -> { + switch (i) { + case 0: + shareChannel(selectedItem); + break; + case 1: + deleteChannel(selectedItem); + break; + default: + break; + } + }; + + final View bannerView = View.inflate(activity, R.layout.dialog_title, null); + bannerView.setSelected(true); + + TextView titleView = bannerView.findViewById(R.id.itemTitleView); + titleView.setText(selectedItem.getName()); + + TextView detailsView = bannerView.findViewById(R.id.itemAdditionalDetails); + detailsView.setVisibility(View.GONE); + + new AlertDialog.Builder(activity) + .setCustomTitle(bannerView) + .setItems(commands, actions) + .create() + .show(); + + } + + private void shareChannel (ChannelInfoItem selectedItem) { + shareUrl(selectedItem.getName(), selectedItem.getUrl()); + } + + @SuppressLint("CheckResult") + private void deleteChannel (ChannelInfoItem selectedItem) { + subscriptionService.subscriptionTable() + .getSubscription(selectedItem.getServiceId(), selectedItem.getUrl()) + .toObservable() + .observeOn(Schedulers.io()) + .subscribe(getDeleteObserver()); + + Toast.makeText(activity, getString(R.string.channel_unsubscribed), Toast.LENGTH_SHORT).show(); + } + + + + private Observer> getDeleteObserver(){ + return new Observer>() { + @Override + public void onSubscribe(Disposable d) { + disposables.add(d); + } + + @Override + public void onNext(List subscriptionEntities) { + subscriptionService.subscriptionTable().delete(subscriptionEntities); + } + + @Override + public void onError(Throwable exception) { + SubscriptionFragment.this.onError(exception); + } + + @Override + public void onComplete() { } + }; + } + private void resetFragment() { if (disposables != null) disposables.clear(); if (infoListAdapter != null) infoListAdapter.clearStreamItemList(); @@ -447,4 +572,22 @@ public class SubscriptionFragment extends BaseStateFragment> subscription; + private final AppDatabase db; + private final Flowable> subscription; - private Scheduler subscriptionScheduler; + private final Scheduler subscriptionScheduler; private SubscriptionService(Context context) { db = NewPipeDatabase.getInstance(context.getApplicationContext()); @@ -116,7 +116,7 @@ public class SubscriptionService { public Completable updateChannelInfo(final ChannelInfo info) { final Function, CompletableSource> update = new Function, CompletableSource>() { @Override - public CompletableSource apply(@NonNull List subscriptionEntities) throws Exception { + public CompletableSource apply(@NonNull List subscriptionEntities) { if (DEBUG) Log.d(TAG, "updateChannelInfo() called with: subscriptionEntities = [" + subscriptionEntities + "]"); if (subscriptionEntities.size() == 1) { SubscriptionEntity subscription = subscriptionEntities.get(0); diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/services/BaseImportExportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/BaseImportExportService.java index 9d055b82a..e3db6e12c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/services/BaseImportExportService.java +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/BaseImportExportService.java @@ -58,8 +58,8 @@ public abstract class BaseImportExportService extends Service { protected NotificationCompat.Builder notificationBuilder; protected SubscriptionService subscriptionService; - protected CompositeDisposable disposables = new CompositeDisposable(); - protected PublishProcessor notificationUpdater = PublishProcessor.create(); + protected final CompositeDisposable disposables = new CompositeDisposable(); + protected final PublishProcessor notificationUpdater = PublishProcessor.create(); @Nullable @Override @@ -90,9 +90,9 @@ public abstract class BaseImportExportService extends Service { private static final int NOTIFICATION_SAMPLING_PERIOD = 2500; - protected AtomicInteger currentProgress = new AtomicInteger(-1); - protected AtomicInteger maxProgress = new AtomicInteger(-1); - protected ImportExportEventListener eventListener = new ImportExportEventListener() { + protected final AtomicInteger currentProgress = new AtomicInteger(-1); + protected final AtomicInteger maxProgress = new AtomicInteger(-1); + protected final ImportExportEventListener eventListener = new ImportExportEventListener() { @Override public void onSizeReceived(int size) { maxProgress.set(size); @@ -187,13 +187,13 @@ public abstract class BaseImportExportService extends Service { protected Toast toast; protected void showToast(@StringRes int message) { - showToast(getString(message), Toast.LENGTH_SHORT); + showToast(getString(message)); } - protected void showToast(String message, int duration) { + protected void showToast(String message) { if (toast != null) toast.cancel(); - toast = Toast.makeText(this, message, duration); + toast = Toast.makeText(this, message, Toast.LENGTH_SHORT); toast.show(); } diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java index 3fdc91358..48410205a 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java @@ -144,12 +144,16 @@ public class SubscriptionsImportService extends BaseImportExportService { showToast(R.string.import_ongoing); Flowable> flowable = null; - if (currentMode == CHANNEL_URL_MODE) { - flowable = importFromChannelUrl(); - } else if (currentMode == INPUT_STREAM_MODE) { - flowable = importFromInputStream(); - } else if (currentMode == PREVIOUS_EXPORT_MODE) { - flowable = importFromPreviousExport(); + switch (currentMode) { + case CHANNEL_URL_MODE: + flowable = importFromChannelUrl(); + break; + case INPUT_STREAM_MODE: + flowable = importFromInputStream(); + break; + case PREVIOUS_EXPORT_MODE: + flowable = importFromPreviousExport(); + break; } if (flowable == null) { 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 01a0614fa..f5f843caa 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java @@ -230,7 +230,8 @@ public abstract class BasePlayer implements int sizeBeforeAppend = playQueue.size(); playQueue.append(queue.getStreams()); - if (intent.getBooleanExtra(SELECT_ON_APPEND, false) && + if ((intent.getBooleanExtra(SELECT_ON_APPEND, false) || + getCurrentState() == STATE_COMPLETED) && queue.getStreams().size() > 0) { playQueue.setIndex(sizeBeforeAppend); } 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 de7960a0d..71b724228 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java @@ -175,6 +175,10 @@ public final class MainVideoPlayer extends AppCompatActivity setLandscape(lastOrientationWasLandscape); } + final int lastResizeMode = defaultPreferences.getInt( + getString(R.string.last_resize_mode), AspectRatioFrameLayout.RESIZE_MODE_FIT); + playerImpl.setResizeMode(lastResizeMode); + // Upon going in or out of multiwindow mode, isInMultiWindow will always be false, // since the first onResume needs to restore the player. // Subsequent onResume calls while multiwindow mode remains the same and the player is @@ -705,14 +709,27 @@ public final class MainVideoPlayer extends AppCompatActivity @Override protected int nextResizeMode(int currentResizeMode) { + final int newResizeMode; switch (currentResizeMode) { case AspectRatioFrameLayout.RESIZE_MODE_FIT: - return AspectRatioFrameLayout.RESIZE_MODE_FILL; + newResizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL; + break; case AspectRatioFrameLayout.RESIZE_MODE_FILL: - return AspectRatioFrameLayout.RESIZE_MODE_ZOOM; + newResizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM; + break; default: - return AspectRatioFrameLayout.RESIZE_MODE_FIT; + newResizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT; + break; } + + storeResizeMode(newResizeMode); + return newResizeMode; + } + + private void storeResizeMode(@AspectRatioFrameLayout.ResizeMode int resizeMode) { + defaultPreferences.edit() + .putInt(getString(R.string.last_resize_mode), resizeMode) + .apply(); } @Override 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 0e7328020..a36a0576c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -114,7 +114,6 @@ public final class PopupVideoPlayer extends Service { private View closeOverlayView; private FloatingActionButton closeOverlayButton; - private WindowManager.LayoutParams closeOverlayLayoutParams; private int tossFlingVelocity; @@ -248,7 +247,7 @@ public final class PopupVideoPlayer extends Service { final int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; - closeOverlayLayoutParams = new WindowManager.LayoutParams( + WindowManager.LayoutParams closeOverlayLayoutParams = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, layoutParamType, flags, 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 679fc6645..d30d9b8be 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java @@ -137,16 +137,16 @@ public abstract class VideoPlayer extends BasePlayer private TextView captionTextView; private ValueAnimator controlViewAnimator; - private Handler controlsVisibilityHandler = new Handler(); + private final Handler controlsVisibilityHandler = new Handler(); boolean isSomePopupMenuVisible = false; - private int qualityPopupMenuGroupId = 69; + private final int qualityPopupMenuGroupId = 69; private PopupMenu qualityPopupMenu; - private int playbackSpeedPopupMenuGroupId = 79; + private final int playbackSpeedPopupMenuGroupId = 79; private PopupMenu playbackSpeedPopupMenu; - private int captionPopupMenuGroupId = 89; + private final int captionPopupMenuGroupId = 89; private PopupMenu captionPopupMenu; /////////////////////////////////////////////////////////////////////////// @@ -683,12 +683,17 @@ public abstract class VideoPlayer extends BasePlayer if (getAspectRatioFrameLayout() != null) { final int currentResizeMode = getAspectRatioFrameLayout().getResizeMode(); final int newResizeMode = nextResizeMode(currentResizeMode); - getAspectRatioFrameLayout().setResizeMode(newResizeMode); - getResizeView().setText(PlayerHelper.resizeTypeOf(context, newResizeMode)); + setResizeMode(newResizeMode); } } + protected void setResizeMode(@AspectRatioFrameLayout.ResizeMode final int resizeMode) { + getAspectRatioFrameLayout().setResizeMode(resizeMode); + getResizeView().setText(PlayerHelper.resizeTypeOf(context, resizeMode)); + } + protected abstract int nextResizeMode(@AspectRatioFrameLayout.ResizeMode final int resizeMode); + /*////////////////////////////////////////////////////////////////////////// // SeekBar Listener //////////////////////////////////////////////////////////////////////////*/ diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java b/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java index 5b9cce947..46d20c7e1 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java @@ -116,7 +116,7 @@ public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, private void onAudioFocusGain() { Log.d(TAG, "onAudioFocusGain() called"); player.setVolume(DUCK_AUDIO_TO); - animateAudio(DUCK_AUDIO_TO, 1f, DUCK_DURATION); + animateAudio(DUCK_AUDIO_TO, 1f); if (PlayerHelper.isResumeAfterAudioFocusGain(context)) { player.setPlayWhenReady(true); @@ -131,13 +131,13 @@ public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, private void onAudioFocusLossCanDuck() { Log.d(TAG, "onAudioFocusLossCanDuck() called"); // Set the volume to 1/10 on ducking - animateAudio(player.getVolume(), DUCK_AUDIO_TO, DUCK_DURATION); + animateAudio(player.getVolume(), DUCK_AUDIO_TO); } - private void animateAudio(final float from, final float to, int duration) { + private void animateAudio(final float from, final float to) { ValueAnimator valueAnimator = new ValueAnimator(); valueAnimator.setFloatValues(from, to); - valueAnimator.setDuration(duration); + valueAnimator.setDuration(AudioReactor.DUCK_DURATION); valueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/CacheFactory.java b/app/src/main/java/org/schabi/newpipe/player/helper/CacheFactory.java index ec7813056..b8d8dc12f 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/CacheFactory.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/CacheFactory.java @@ -4,12 +4,9 @@ import android.content.Context; import android.support.annotation.NonNull; import android.util.Log; -import com.google.android.exoplayer2.upstream.BandwidthMeter; import com.google.android.exoplayer2.upstream.DataSource; -import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; import com.google.android.exoplayer2.upstream.DefaultDataSource; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; -import com.google.android.exoplayer2.upstream.DefaultHttpDataSource; import com.google.android.exoplayer2.upstream.FileDataSource; import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.upstream.cache.CacheDataSink; @@ -17,8 +14,6 @@ import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor; import com.google.android.exoplayer2.upstream.cache.SimpleCache; -import org.schabi.newpipe.Downloader; - import java.io.File; /* package-private */ class CacheFactory implements DataSource.Factory { diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlaybackParameterDialog.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlaybackParameterDialog.java index d6453f579..f49ca3330 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlaybackParameterDialog.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlaybackParameterDialog.java @@ -66,25 +66,15 @@ public class PlaybackParameterDialog extends DialogFragment { private double stepSize = DEFAULT_STEP; @Nullable private SeekBar tempoSlider; - @Nullable private TextView tempoMinimumText; - @Nullable private TextView tempoMaximumText; @Nullable private TextView tempoCurrentText; @Nullable private TextView tempoStepDownText; @Nullable private TextView tempoStepUpText; @Nullable private SeekBar pitchSlider; - @Nullable private TextView pitchMinimumText; - @Nullable private TextView pitchMaximumText; @Nullable private TextView pitchCurrentText; @Nullable private TextView pitchStepDownText; @Nullable private TextView pitchStepUpText; - @Nullable private TextView stepSizeOnePercentText; - @Nullable private TextView stepSizeFivePercentText; - @Nullable private TextView stepSizeTenPercentText; - @Nullable private TextView stepSizeTwentyFivePercentText; - @Nullable private TextView stepSizeOneHundredPercentText; - @Nullable private CheckBox unhookingCheckbox; @Nullable private CheckBox skipSilenceCheckbox; @@ -181,8 +171,8 @@ public class PlaybackParameterDialog extends DialogFragment { private void setupTempoControl(@NonNull View rootView) { tempoSlider = rootView.findViewById(R.id.tempoSeekbar); - tempoMinimumText = rootView.findViewById(R.id.tempoMinimumText); - tempoMaximumText = rootView.findViewById(R.id.tempoMaximumText); + TextView tempoMinimumText = rootView.findViewById(R.id.tempoMinimumText); + TextView tempoMaximumText = rootView.findViewById(R.id.tempoMaximumText); tempoCurrentText = rootView.findViewById(R.id.tempoCurrentText); tempoStepUpText = rootView.findViewById(R.id.tempoStepUp); tempoStepDownText = rootView.findViewById(R.id.tempoStepDown); @@ -203,8 +193,8 @@ public class PlaybackParameterDialog extends DialogFragment { private void setupPitchControl(@NonNull View rootView) { pitchSlider = rootView.findViewById(R.id.pitchSeekbar); - pitchMinimumText = rootView.findViewById(R.id.pitchMinimumText); - pitchMaximumText = rootView.findViewById(R.id.pitchMaximumText); + TextView pitchMinimumText = rootView.findViewById(R.id.pitchMinimumText); + TextView pitchMaximumText = rootView.findViewById(R.id.pitchMaximumText); pitchCurrentText = rootView.findViewById(R.id.pitchCurrentText); pitchStepDownText = rootView.findViewById(R.id.pitchStepDown); pitchStepUpText = rootView.findViewById(R.id.pitchStepUp); @@ -247,11 +237,11 @@ public class PlaybackParameterDialog extends DialogFragment { } private void setupStepSizeSelector(@NonNull final View rootView) { - stepSizeOnePercentText = rootView.findViewById(R.id.stepSizeOnePercent); - stepSizeFivePercentText = rootView.findViewById(R.id.stepSizeFivePercent); - stepSizeTenPercentText = rootView.findViewById(R.id.stepSizeTenPercent); - stepSizeTwentyFivePercentText = rootView.findViewById(R.id.stepSizeTwentyFivePercent); - stepSizeOneHundredPercentText = rootView.findViewById(R.id.stepSizeOneHundredPercent); + TextView stepSizeOnePercentText = rootView.findViewById(R.id.stepSizeOnePercent); + TextView stepSizeFivePercentText = rootView.findViewById(R.id.stepSizeFivePercent); + TextView stepSizeTenPercentText = rootView.findViewById(R.id.stepSizeTenPercent); + TextView stepSizeTwentyFivePercentText = rootView.findViewById(R.id.stepSizeTwentyFivePercent); + TextView stepSizeOneHundredPercentText = rootView.findViewById(R.id.stepSizeOneHundredPercent); if (stepSizeOnePercentText != null) { stepSizeOnePercentText.setText(getPercentString(STEP_ONE_PERCENT_VALUE)); 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 52e268b24..16dffc3de 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 @@ -207,7 +207,7 @@ public class PlayerHelper { @NonNull public static SeekParameters getSeekParameters(@NonNull final Context context) { - return isUsingInexactSeek(context, false) ? + return isUsingInexactSeek(context) ? SeekParameters.CLOSEST_SYNC : SeekParameters.EXACT; } @@ -326,8 +326,8 @@ public class PlayerHelper { return getPreferences(context).getBoolean(context.getString(R.string.popup_remember_size_pos_key), b); } - private static boolean isUsingInexactSeek(@NonNull final Context context, final boolean b) { - return getPreferences(context).getBoolean(context.getString(R.string.use_inexact_seek_key), b); + private static boolean isUsingInexactSeek(@NonNull final Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.use_inexact_seek_key), false); } private static boolean isAutoQueueEnabled(@NonNull final Context context, final boolean b) { diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java index 429c26fd9..3d1fd171f 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/PlayQueueNavigator.java @@ -79,7 +79,7 @@ public class PlayQueueNavigator implements MediaSessionConnector.QueueNavigator private void publishFloatingQueueWindow() { if (callback.getQueueSize() == 0) { - mediaSession.setQueue(Collections.emptyList()); + mediaSession.setQueue(Collections.emptyList()); activeQueueItemId = MediaSessionCompat.QueueItem.UNKNOWN_ID; return; } 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 3365828d1..00604b236 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 @@ -8,7 +8,7 @@ import org.schabi.newpipe.player.mediasession.MediaSessionCallback; import org.schabi.newpipe.player.playqueue.PlayQueueItem; public class BasePlayerMediaSession implements MediaSessionCallback { - private BasePlayer player; + private final BasePlayer player; public BasePlayerMediaSession(final BasePlayer player) { this.player = player; diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/CustomTrackSelector.java b/app/src/main/java/org/schabi/newpipe/player/playback/CustomTrackSelector.java index d80ea5bae..efe6f3a58 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playback/CustomTrackSelector.java +++ b/app/src/main/java/org/schabi/newpipe/player/playback/CustomTrackSelector.java @@ -4,7 +4,6 @@ import android.support.annotation.NonNull; import android.text.TextUtils; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroupArray; @@ -12,7 +11,6 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.FixedTrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.util.Assertions; -import com.google.android.exoplayer2.util.Util; /** * This class allows irregular text language labels for use when selecting text captions and @@ -55,7 +53,7 @@ public class CustomTrackSelector extends DefaultTrackSelector { /** @see DefaultTrackSelector#selectTextTrack(TrackGroupArray, int[][], Parameters) */ @Override protected TrackSelection selectTextTrack(TrackGroupArray groups, int[][] formatSupport, - Parameters params) throws ExoPlaybackException { + Parameters params) { TrackGroup selectedGroup = null; int selectedTrackIndex = 0; int selectedTrackScore = 0; 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 b27dc3dd6..3c5642d51 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 @@ -335,7 +335,7 @@ public class MediaSourceManager { private void loadImmediate() { if (DEBUG) Log.d(TAG, "MediaSource - loadImmediate() called"); - final ItemsToLoad itemsToLoad = getItemsToLoad(playQueue, WINDOW_SIZE); + final ItemsToLoad itemsToLoad = getItemsToLoad(playQueue); if (itemsToLoad == null) return; // Evict the previous items being loaded to free up memory, before start loading new ones @@ -472,8 +472,7 @@ public class MediaSourceManager { // Manager Helpers //////////////////////////////////////////////////////////////////////////*/ @Nullable - private static ItemsToLoad getItemsToLoad(@NonNull final PlayQueue playQueue, - final int windowSize) { + private static ItemsToLoad getItemsToLoad(@NonNull final PlayQueue playQueue) { // The current item has higher priority final int currentIndex = playQueue.getIndex(); final PlayQueueItem currentItem = playQueue.getItem(currentIndex); @@ -482,8 +481,8 @@ public class MediaSourceManager { // The rest are just for seamless playback // Although timeline is not updated prior to the current index, these sources are still // loaded into the cache for faster retrieval at a potentially later time. - final int leftBound = Math.max(0, currentIndex - windowSize); - final int rightLimit = currentIndex + windowSize + 1; + final int leftBound = Math.max(0, currentIndex - MediaSourceManager.WINDOW_SIZE); + final int rightLimit = currentIndex + MediaSourceManager.WINDOW_SIZE + 1; final int rightBound = Math.min(playQueue.size(), rightLimit); final Set neighbors = new ArraySet<>( playQueue.getStreams().subList(leftBound,rightBound)); 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 238bdfcd0..4e79c6d75 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 @@ -8,8 +8,6 @@ import com.google.android.exoplayer2.source.MediaSource; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.player.playqueue.PlayQueueItem; -import java.util.List; - public interface PlaybackListener { /** diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java index 2c08f4f92..676c0ca72 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java @@ -19,14 +19,14 @@ abstract class AbstractInfoPlayQueue ext boolean isInitial; boolean isComplete; - int serviceId; - String baseUrl; + final int serviceId; + final String baseUrl; String nextUrl; transient Disposable fetchReactor; AbstractInfoPlayQueue(final U item) { - this(item.getServiceId(), item.getUrl(), null, Collections.emptyList(), 0); + this(item.getServiceId(), item.getUrl(), null, Collections.emptyList(), 0); } AbstractInfoPlayQueue(final int serviceId, diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java index 996d3ace3..c24eff81a 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemBuilder.java @@ -5,10 +5,8 @@ import android.text.TextUtils; import android.view.MotionEvent; import android.view.View; -import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; -import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.util.ImageDisplayConstants; import org.schabi.newpipe.util.Localization; diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemHolder.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemHolder.java index 2483e4473..effb9aae9 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemHolder.java @@ -6,8 +6,6 @@ import android.widget.ImageView; import android.widget.TextView; import org.schabi.newpipe.R; -import org.schabi.newpipe.extractor.InfoItem; -import org.schabi.newpipe.info_list.holder.InfoItemHolder; /** * Created by Christian Schabesberger on 01.08.16. diff --git a/app/src/main/java/org/schabi/newpipe/report/AcraReportSender.java b/app/src/main/java/org/schabi/newpipe/report/AcraReportSender.java index 2d3226ab6..a6a81474f 100644 --- a/app/src/main/java/org/schabi/newpipe/report/AcraReportSender.java +++ b/app/src/main/java/org/schabi/newpipe/report/AcraReportSender.java @@ -5,7 +5,6 @@ import android.support.annotation.NonNull; import org.acra.collector.CrashReportData; import org.acra.sender.ReportSender; -import org.acra.sender.ReportSenderException; import org.schabi.newpipe.R; /* @@ -31,7 +30,7 @@ import org.schabi.newpipe.R; public class AcraReportSender implements ReportSender { @Override - public void send(@NonNull Context context, @NonNull CrashReportData report) throws ReportSenderException { + public void send(@NonNull Context context, @NonNull CrashReportData report) { ErrorActivity.reportError(context, report, ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR,"none", "App crash, UI failure", R.string.app_ui_crash)); diff --git a/app/src/main/java/org/schabi/newpipe/report/ErrorActivity.java b/app/src/main/java/org/schabi/newpipe/report/ErrorActivity.java index 3ad08c3ec..f852e0134 100644 --- a/app/src/main/java/org/schabi/newpipe/report/ErrorActivity.java +++ b/app/src/main/java/org/schabi/newpipe/report/ErrorActivity.java @@ -3,7 +3,6 @@ package org.schabi.newpipe.report; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; import android.net.Uri; @@ -46,7 +45,6 @@ import java.util.Date; import java.util.List; import java.util.TimeZone; import java.util.Vector; -import java.util.concurrent.atomic.AtomicBoolean; /* * Created by Christian Schabesberger on 24.10.15. @@ -81,12 +79,7 @@ public class ErrorActivity extends AppCompatActivity { private ErrorInfo errorInfo; private Class returnActivity; private String currentTimeStamp; - // views - private TextView errorView; private EditText userCommentBox; - private Button reportButton; - private TextView infoView; - private TextView errorMessageView; public static void reportUiError(final AppCompatActivity activity, final Throwable el) { reportError(activity, el, activity.getClass(), null, @@ -194,11 +187,11 @@ public class ErrorActivity extends AppCompatActivity { actionBar.setDisplayShowTitleEnabled(true); } - reportButton = findViewById(R.id.errorReportButton); + Button reportButton = findViewById(R.id.errorReportButton); userCommentBox = findViewById(R.id.errorCommentBox); - errorView = findViewById(R.id.errorView); - infoView = findViewById(R.id.errorInfosView); - errorMessageView = findViewById(R.id.errorMessageView); + TextView errorView = findViewById(R.id.errorView); + TextView infoView = findViewById(R.id.errorInfosView); + TextView errorMessageView = findViewById(R.id.errorMessageView); ActivityCommunicator ac = ActivityCommunicator.getCommunicator(); returnActivity = ac.returnActivity; @@ -281,15 +274,14 @@ public class ErrorActivity extends AppCompatActivity { } private String formErrorText(String[] el) { - String text = ""; + StringBuilder text = new StringBuilder(); if (el != null) { for (String e : el) { - text += "-------------------------------------\n" - + e; + text.append("-------------------------------------\n").append(e); } } - text += "-------------------------------------"; - return text; + text.append("-------------------------------------"); + return text.toString(); } /** diff --git a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java index 806b30a5b..821636ee5 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java @@ -6,7 +6,6 @@ import android.os.Bundle; import android.provider.Settings; import android.support.annotation.Nullable; import android.support.v7.preference.Preference; -import android.util.Log; import org.schabi.newpipe.R; import org.schabi.newpipe.util.Constants; @@ -49,7 +48,7 @@ public class AppearanceSettingsFragment extends BasePreferenceFragment { return super.onPreferenceTreeClick(preference); } - private Preference.OnPreferenceChangeListener themePreferenceChange = new Preference.OnPreferenceChangeListener() { + private final Preference.OnPreferenceChangeListener themePreferenceChange = new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { defaultPreferences.edit().putBoolean(Constants.KEY_THEME_CHANGE, true).apply(); diff --git a/app/src/main/java/org/schabi/newpipe/settings/BasePreferenceFragment.java b/app/src/main/java/org/schabi/newpipe/settings/BasePreferenceFragment.java index e3c52cdad..e4fae3e1f 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/BasePreferenceFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/BasePreferenceFragment.java @@ -13,7 +13,7 @@ import org.schabi.newpipe.MainActivity; public abstract class BasePreferenceFragment extends PreferenceFragmentCompat { protected final String TAG = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()); - protected boolean DEBUG = MainActivity.DEBUG; + protected final boolean DEBUG = MainActivity.DEBUG; protected SharedPreferences defaultPreferences; diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index 0ca78b34a..5c54fa735 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -9,8 +9,6 @@ import android.os.Bundle; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v4.app.Fragment; -import android.support.v7.preference.ListPreference; import android.support.v7.preference.Preference; import android.util.Log; import android.widget.Toast; @@ -19,12 +17,9 @@ import com.nononsenseapps.filepicker.Utils; import com.nostra13.universalimageloader.core.ImageLoader; import org.schabi.newpipe.R; -import org.schabi.newpipe.extractor.NewPipe; -import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.report.ErrorActivity; import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.util.FilePickerActivityHelper; -import org.schabi.newpipe.util.KioskTranslator; import org.schabi.newpipe.util.ZipHelper; import java.io.BufferedOutputStream; @@ -47,7 +42,6 @@ public class ContentSettingsFragment extends BasePreferenceFragment { private static final int REQUEST_IMPORT_PATH = 8945; private static final int REQUEST_EXPORT_PATH = 30945; - private String homeDir; private File databasesDir; private File newpipe_db; private File newpipe_db_journal; @@ -81,7 +75,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment { @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - homeDir = getActivity().getApplicationInfo().dataDir; + String homeDir = getActivity().getApplicationInfo().dataDir; databasesDir = new File(homeDir + "/databases"); newpipe_db = new File(homeDir + "/databases/newpipe.db"); newpipe_db_journal = new File(homeDir + "/databases/newpipe.db-journal"); @@ -193,7 +187,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment { } finally { try { zipFile.close(); - } catch (Exception e){} + } catch (Exception ignored){} } try { @@ -254,17 +248,17 @@ public class ContentSettingsFragment extends BasePreferenceFragment { String key = entry.getKey(); if (v instanceof Boolean) - prefEdit.putBoolean(key, ((Boolean) v).booleanValue()); + prefEdit.putBoolean(key, (Boolean) v); else if (v instanceof Float) - prefEdit.putFloat(key, ((Float) v).floatValue()); + prefEdit.putFloat(key, (Float) v); else if (v instanceof Integer) - prefEdit.putInt(key, ((Integer) v).intValue()); + prefEdit.putInt(key, (Integer) v); else if (v instanceof Long) - prefEdit.putLong(key, ((Long) v).longValue()); + prefEdit.putLong(key, (Long) v); else if (v instanceof String) prefEdit.putString(key, ((String) v)); } - prefEdit.commit(); + prefEdit.apply(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { @@ -286,13 +280,12 @@ public class ContentSettingsFragment extends BasePreferenceFragment { // Error //////////////////////////////////////////////////////////////////////////*/ - protected boolean onError(Throwable e) { + protected void onError(Throwable e) { final Activity activity = getActivity(); ErrorActivity.reportError(activity, e, activity.getClass(), null, ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR, "none", "", R.string.app_ui_crash)); - return true; } } 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 cc1f408b7..d28c3179c 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java @@ -1,29 +1,20 @@ 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; 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 0ebdbefe0..61bd4077e 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java @@ -51,9 +51,7 @@ import io.reactivex.schedulers.Schedulers; */ public class SelectChannelFragment extends DialogFragment { - private SelectChannelAdapter channelAdapter; - private SubscriptionService subscriptionService; - private ImageLoader imageLoader = ImageLoader.getInstance(); + private final ImageLoader imageLoader = ImageLoader.getInstance(); private ProgressBar progressBar; private TextView emptyView; @@ -89,9 +87,9 @@ public class SelectChannelFragment extends DialogFragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.select_channel_fragment, container, false); - recyclerView = (RecyclerView) v.findViewById(R.id.items_list); + recyclerView = v.findViewById(R.id.items_list); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - channelAdapter = new SelectChannelAdapter(); + SelectChannelAdapter channelAdapter = new SelectChannelAdapter(); recyclerView.setAdapter(channelAdapter); progressBar = v.findViewById(R.id.progressBar); @@ -101,7 +99,7 @@ public class SelectChannelFragment extends DialogFragment { emptyView.setVisibility(View.GONE); - subscriptionService = SubscriptionService.getInstance(getContext()); + SubscriptionService subscriptionService = SubscriptionService.getInstance(getContext()); subscriptionService.getSubscription().toObservable() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -203,9 +201,9 @@ public class SelectChannelFragment extends DialogFragment { thumbnailView = v.findViewById(R.id.itemThumbnailView); titleView = v.findViewById(R.id.itemTitleView); } - public View view; - public CircleImageView thumbnailView; - public TextView titleView; + public final View view; + public final CircleImageView thumbnailView; + public final TextView titleView; } } @@ -213,14 +211,13 @@ public class SelectChannelFragment extends DialogFragment { // Error //////////////////////////////////////////////////////////////////////////*/ - protected boolean onError(Throwable e) { + protected void onError(Throwable e) { final Activity activity = getActivity(); ErrorActivity.reportError(activity, e, activity.getClass(), null, ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR, "none", "", R.string.app_ui_crash)); - return true; } diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectKioskFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectKioskFragment.java index 44cb16682..8c3bd56e7 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SelectKioskFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SelectKioskFragment.java @@ -75,7 +75,7 @@ public class SelectKioskFragment extends DialogFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.select_kiosk_fragment, container, false); - recyclerView = (RecyclerView) v.findViewById(R.id.items_list); + recyclerView = v.findViewById(R.id.items_list); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); try { selectKioskAdapter = new SelectKioskAdapter(); @@ -112,13 +112,13 @@ public class SelectKioskFragment extends DialogFragment { public Entry (int i, int si, String ki, String kn){ icon = i; serviceId=si; kioskId=ki; kioskName = kn; } - int icon; - int serviceId; - String kioskId; - String kioskName; + final int icon; + final int serviceId; + final String kioskId; + final String kioskName; } - private List kioskList = new Vector<>(); + private final List kioskList = new Vector<>(); public SelectKioskAdapter() throws Exception { @@ -157,9 +157,9 @@ public class SelectKioskFragment extends DialogFragment { thumbnailView = v.findViewById(R.id.itemThumbnailView); titleView = v.findViewById(R.id.itemTitleView); } - public View view; - public ImageView thumbnailView; - public TextView titleView; + public final View view; + public final ImageView thumbnailView; + public final TextView titleView; } public void onBindViewHolder(SelectKioskItemHolder holder, final int position) { @@ -179,13 +179,12 @@ public class SelectKioskFragment extends DialogFragment { // Error //////////////////////////////////////////////////////////////////////////*/ - protected boolean onError(Throwable e) { + protected void onError(Throwable e) { final Activity activity = getActivity(); ErrorActivity.reportError(activity, e, activity.getClass(), null, ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR, "none", "", R.string.app_ui_crash)); - return true; } } diff --git a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java index e445233c3..31ab1a845 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java @@ -32,6 +32,7 @@ import org.schabi.newpipe.extractor.Info; import org.schabi.newpipe.extractor.ListExtractor.InfoItemsPage; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.channel.ChannelInfo; +import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ReCaptchaException; @@ -183,7 +184,7 @@ public final class ExtractorHelper { cache.removeInfo(serviceId, url); load = loadFromNetwork; } else { - load = Maybe.concat(ExtractorHelper.loadFromCache(serviceId, url), + load = Maybe.concat(ExtractorHelper.loadFromCache(serviceId, url), loadFromNetwork.toMaybe()) .firstElement() //Take the first valid .toSingle(); diff --git a/app/src/main/java/org/schabi/newpipe/util/InfoCache.java b/app/src/main/java/org/schabi/newpipe/util/InfoCache.java index ecc66bb40..318db37a1 100644 --- a/app/src/main/java/org/schabi/newpipe/util/InfoCache.java +++ b/app/src/main/java/org/schabi/newpipe/util/InfoCache.java @@ -28,9 +28,6 @@ import org.schabi.newpipe.MainActivity; import org.schabi.newpipe.extractor.Info; import java.util.Map; -import java.util.concurrent.TimeUnit; - -import static org.schabi.newpipe.extractor.ServiceList.SoundCloud; public final class InfoCache { @@ -58,7 +55,7 @@ public final class InfoCache { public Info getFromKey(int serviceId, @NonNull String url) { if (DEBUG) Log.d(TAG, "getFromKey() called with: serviceId = [" + serviceId + "], url = [" + url + "]"); synchronized (lruCache) { - return getInfo(lruCache, keyOf(serviceId, url)); + return getInfo(keyOf(serviceId, url)); } } @@ -89,7 +86,7 @@ public final class InfoCache { public void trimCache() { if (DEBUG) Log.d(TAG, "trimCache() called"); synchronized (lruCache) { - removeStaleCache(lruCache); + removeStaleCache(); lruCache.trimToSize(TRIM_CACHE_TO); } } @@ -105,23 +102,22 @@ public final class InfoCache { return serviceId + url; } - private static void removeStaleCache(@NonNull final LruCache cache) { - for (Map.Entry entry : cache.snapshot().entrySet()) { + private static void removeStaleCache() { + for (Map.Entry entry : InfoCache.lruCache.snapshot().entrySet()) { final CacheData data = entry.getValue(); if (data != null && data.isExpired()) { - cache.remove(entry.getKey()); + InfoCache.lruCache.remove(entry.getKey()); } } } @Nullable - private static Info getInfo(@NonNull final LruCache cache, - @NonNull final String key) { - final CacheData data = cache.get(key); + private static Info getInfo(@NonNull final String key) { + final CacheData data = InfoCache.lruCache.get(key); if (data == null) return null; if (data.isExpired()) { - cache.remove(key); + InfoCache.lruCache.remove(key); return null; } diff --git a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java index 1a5bf14f7..871d0578f 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java @@ -204,7 +204,7 @@ public final class ListHelper { */ private static void sortStreamList(List videoStreams, final boolean ascendingOrder) { Collections.sort(videoStreams, (o1, o2) -> { - int result = compareVideoStreamResolution(o1, o2, VIDEO_FORMAT_QUALITY_RANKING); + int result = compareVideoStreamResolution(o1, o2); return result == 0 ? 0 : (ascendingOrder ? result : -result); }); } @@ -399,8 +399,7 @@ public final class ListHelper { } // Compares the quality of two video streams. - private static int compareVideoStreamResolution(VideoStream streamA, VideoStream streamB, - List formatRanking) { + private static int compareVideoStreamResolution(VideoStream streamA, VideoStream streamB) { if (streamA == null) { return -1; } @@ -414,7 +413,7 @@ public final class ListHelper { } // Same bitrate and format - return formatRanking.indexOf(streamA.getFormat()) - formatRanking.indexOf(streamB.getFormat()); + return ListHelper.VIDEO_FORMAT_QUALITY_RANKING.indexOf(streamA.getFormat()) - ListHelper.VIDEO_FORMAT_QUALITY_RANKING.indexOf(streamB.getFormat()); } 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 13767125d..5b953697d 100644 --- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java @@ -26,7 +26,6 @@ import org.schabi.newpipe.download.DownloadActivity; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.exceptions.ExtractionException; -import org.schabi.newpipe.extractor.search.SearchExtractor; import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.Stream; import org.schabi.newpipe.extractor.stream.StreamInfo; diff --git a/app/src/main/java/org/schabi/newpipe/util/StateSaver.java b/app/src/main/java/org/schabi/newpipe/util/StateSaver.java index 51dceddf3..3115862e0 100644 --- a/app/src/main/java/org/schabi/newpipe/util/StateSaver.java +++ b/app/src/main/java/org/schabi/newpipe/util/StateSaver.java @@ -21,7 +21,6 @@ package org.schabi.newpipe.util; import android.content.Context; -import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; diff --git a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java index e3fe4a679..e100a447b 100644 --- a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java @@ -31,7 +31,7 @@ import us.shandian.giga.util.Utility; public class StreamItemAdapter extends BaseAdapter { private final Context context; - private StreamSizeWrapper streamsWrapper; + private final StreamSizeWrapper streamsWrapper; private final boolean showIconNoAudio; public StreamItemAdapter(Context context, StreamSizeWrapper streamsWrapper, boolean showIconNoAudio) { @@ -124,7 +124,7 @@ public class StreamItemAdapter extends BaseAdapter { public static class StreamSizeWrapper implements Serializable { private static final StreamSizeWrapper EMPTY = new StreamSizeWrapper<>(Collections.emptyList()); private final List streamsList; - private long[] streamSizes; + private final long[] streamSizes; public StreamSizeWrapper(List streamsList) { this.streamsList = streamsList; diff --git a/app/src/main/java/org/schabi/newpipe/util/ZipHelper.java b/app/src/main/java/org/schabi/newpipe/util/ZipHelper.java index 3578f34ac..3142ad8dc 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ZipHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ZipHelper.java @@ -56,7 +56,6 @@ public class ZipHelper { /** * This will extract data from Zipfiles. * Caution this will override the original file. - * @param inZip The ZipOutputStream where the data is stored in * @param file The path of the file on the disk where the data should be extracted to. * @param name The path of the file inside the zip. * @return will return true if the file was found within the zip file diff --git a/app/src/main/java/org/schabi/newpipe/views/CollapsibleView.java b/app/src/main/java/org/schabi/newpipe/views/CollapsibleView.java index adef7e76f..88d525625 100644 --- a/app/src/main/java/org/schabi/newpipe/views/CollapsibleView.java +++ b/app/src/main/java/org/schabi/newpipe/views/CollapsibleView.java @@ -81,7 +81,7 @@ public class CollapsibleView extends LinearLayout { private int targetHeight = -1; private ValueAnimator currentAnimator; - private List listeners = new ArrayList<>(); + private final List listeners = new ArrayList<>(); /** * This method recalculates the height of this view so it must be called when 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 3294f5164..a377d861c 100755 --- a/app/src/main/java/us/shandian/giga/get/DownloadManagerImpl.java +++ b/app/src/main/java/us/shandian/giga/get/DownloadManagerImpl.java @@ -123,7 +123,7 @@ public class DownloadManagerImpl implements DownloadManager { Collections.sort(missions, new Comparator() { @Override public int compare(DownloadMission o1, DownloadMission o2) { - return Long.valueOf(o1.timestamp).compareTo(o2.timestamp); + return Long.compare(o1.timestamp, o2.timestamp); } }); } 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 f02eaae28..79c4baf05 100644 --- a/app/src/main/java/us/shandian/giga/get/DownloadMission.java +++ b/app/src/main/java/us/shandian/giga/get/DownloadMission.java @@ -67,8 +67,8 @@ public class DownloadMission implements Serializable { public long done; public int threadCount = 3; public int finishCount; - private List threadPositions = new ArrayList(); - public final Map blockState = new HashMap(); + private final List threadPositions = new ArrayList<>(); + public final Map blockState = new HashMap<>(); public boolean running; public boolean finished; public boolean fallback; @@ -77,7 +77,7 @@ public class DownloadMission implements Serializable { public transient boolean recovered; - private transient ArrayList> mListeners = new ArrayList>(); + private transient ArrayList> mListeners = new ArrayList<>(); private transient boolean mWritingToFile; private static final int NO_IDENTIFIER = -1; @@ -232,7 +232,7 @@ public class DownloadMission implements Serializable { public synchronized void addListener(MissionListener listener) { Handler handler = new Handler(Looper.getMainLooper()); MissionListener.handlerStore.put(listener, handler); - mListeners.add(new WeakReference(listener)); + mListeners.add(new WeakReference<>(listener)); } public synchronized void removeListener(MissionListener listener) { diff --git a/app/src/main/java/us/shandian/giga/get/DownloadRunnable.java b/app/src/main/java/us/shandian/giga/get/DownloadRunnable.java index b53f8aea9..6ad8626c3 100644 --- a/app/src/main/java/us/shandian/giga/get/DownloadRunnable.java +++ b/app/src/main/java/us/shandian/giga/get/DownloadRunnable.java @@ -92,7 +92,7 @@ public class DownloadRunnable implements Runnable { // A server may be ignoring the range request if (conn.getResponseCode() != 206) { mMission.errCode = DownloadMission.ERROR_SERVER_UNSUPPORTED; - notifyError(DownloadMission.ERROR_SERVER_UNSUPPORTED); + notifyError(); if (DEBUG) { Log.e(TAG, mId + ":Unsupported " + conn.getResponseCode()); @@ -161,9 +161,9 @@ public class DownloadRunnable implements Runnable { } } - private void notifyError(final int err) { + private void notifyError() { synchronized (mMission) { - mMission.notifyError(err); + mMission.notifyError(DownloadMission.ERROR_SERVER_UNSUPPORTED); mMission.pause(); } } diff --git a/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java b/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java index 59f5e2225..ff410a79a 100755 --- a/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java +++ b/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java @@ -56,7 +56,7 @@ public class DownloadManagerService extends Service { private DownloadDataSource mDataSource; - private MissionListener missionListener = new MissionListener(); + private final MissionListener missionListener = new MissionListener(); private void notifyMediaScanner(DownloadMission mission) { diff --git a/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java b/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java index 8127c3467..d5555c2be 100644 --- a/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java +++ b/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java @@ -306,12 +306,12 @@ public class MissionAdapter extends RecyclerView.Adapter { ProgressDialog prog; - WeakReference weakReference; + final WeakReference weakReference; ChecksumTask(@NonNull Activity activity) { weakReference = new WeakReference<>(activity); diff --git a/app/src/main/java/us/shandian/giga/ui/common/ProgressDrawable.java b/app/src/main/java/us/shandian/giga/ui/common/ProgressDrawable.java index 6a0e35cff..955ce4c65 100644 --- a/app/src/main/java/us/shandian/giga/ui/common/ProgressDrawable.java +++ b/app/src/main/java/us/shandian/giga/ui/common/ProgressDrawable.java @@ -12,7 +12,8 @@ import android.support.v4.content.ContextCompat; public class ProgressDrawable extends Drawable { private float mProgress; - private int mBackgroundColor, mForegroundColor; + private final int mBackgroundColor; + private final int mForegroundColor; public ProgressDrawable(Context context, @ColorRes int background, @ColorRes int foreground) { this(ContextCompat.getColor(context, background), ContextCompat.getColor(context, foreground)); diff --git a/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java b/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java index 14439f6c8..5241415b2 100644 --- a/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java +++ b/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java @@ -16,6 +16,8 @@ import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -44,7 +46,7 @@ public abstract class MissionsFragment extends Fragment { private DeleteDownloadManager mDeleteDownloadManager; private Disposable mDeleteDisposable; - private ServiceConnection mConnection = new ServiceConnection() { + private final ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder binder) { @@ -144,17 +146,21 @@ public abstract class MissionsFragment extends Fragment { } @Override - public boolean onOptionsItemSelected(MenuItem item) { - return super.onOptionsItemSelected(item); + public void onPrepareOptionsMenu(Menu menu) { + mSwitch = menu.findItem(R.id.switch_mode); + super.onPrepareOptionsMenu(menu); + } - /*switch (item.getItemId()) { + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { case R.id.switch_mode: mLinear = !mLinear; updateList(); return true; default: return super.onOptionsItemSelected(item); - }*/ + } } public void notifyChange() { 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 de9a16a1b..163ac2b14 100644 --- a/app/src/main/java/us/shandian/giga/util/Utility.java +++ b/app/src/main/java/us/shandian/giga/util/Utility.java @@ -11,9 +11,7 @@ import android.widget.Toast; import org.schabi.newpipe.R; -import java.io.BufferedInputStream; import java.io.BufferedOutputStream; -import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -198,7 +196,7 @@ public class Utility { while ((len = i.read(buf)) != -1) { md.update(buf, 0, len); } - } catch (IOException e) { + } catch (IOException ignored) { } diff --git a/app/src/main/res/layout-large-land/activity_main_player.xml b/app/src/main/res/layout-large-land/activity_main_player.xml new file mode 100644 index 000000000..7d7e1230e --- /dev/null +++ b/app/src/main/res/layout-large-land/activity_main_player.xml @@ -0,0 +1,581 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-large-land/fragment_video_detail.xml b/app/src/main/res/layout-large-land/fragment_video_detail.xml new file mode 100644 index 000000000..73939d60a --- /dev/null +++ b/app/src/main/res/layout-large-land/fragment_video_detail.xml @@ -0,0 +1,491 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-v21/drawer_header.xml b/app/src/main/res/layout-v21/drawer_header.xml index 4cdc2b30e..4474ee4ed 100644 --- a/app/src/main/res/layout-v21/drawer_header.xml +++ b/app/src/main/res/layout-v21/drawer_header.xml @@ -16,7 +16,8 @@ android:layout_height="match_parent" android:background="?attr/colorPrimary" android:scaleType="centerCrop" - android:src="@drawable/background_header" /> + android:src="@drawable/background_header" + android:contentDescription="TODO" /> + android:src="@drawable/np_logo_nude_shadow" + android:contentDescription="TODO" /> @@ -50,7 +52,7 @@ android:layout_alignStart="@id/drawer_header_np_text_view" android:layout_below="@id/drawer_header_np_text_view" android:text="YouTube" - android:textSize="18dp" + android:textSize="18sp" android:textColor="@color/drawer_header_font_color" android:textStyle="italic" /> @@ -66,6 +68,7 @@ android:paddingBottom="20dp" android:paddingEnd="20dp" android:paddingRight="20dp" - android:src="@drawable/ic_arrow_down_white" /> + android:src="@drawable/ic_arrow_down_white" + android:contentDescription="TODO" /> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_error.xml b/app/src/main/res/layout/activity_error.xml index 7752dc7cb..c47077c73 100644 --- a/app/src/main/res/layout/activity_error.xml +++ b/app/src/main/res/layout/activity_error.xml @@ -114,7 +114,8 @@ + android:layout_height="wrap_content" + android:inputType="" />