mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 07:13:00 +00:00 
			
		
		
		
	Merge branch 'dev' into pr3178
This commit is contained in:
		| @@ -84,7 +84,7 @@ ext { | |||||||
|     checkstyleVersion = '8.32' |     checkstyleVersion = '8.32' | ||||||
|     stethoVersion = '1.5.1' |     stethoVersion = '1.5.1' | ||||||
|     leakCanaryVersion = '2.2' |     leakCanaryVersion = '2.2' | ||||||
|     exoPlayerVersion = '2.11.6' |     exoPlayerVersion = '2.11.8' | ||||||
|     androidxLifecycleVersion = '2.2.0' |     androidxLifecycleVersion = '2.2.0' | ||||||
|     androidxRoomVersion = '2.2.5' |     androidxRoomVersion = '2.2.5' | ||||||
|     groupieVersion = '2.8.0' |     groupieVersion = '2.8.0' | ||||||
| @@ -139,7 +139,7 @@ afterEvaluate { | |||||||
| } | } | ||||||
|  |  | ||||||
| dependencies { | dependencies { | ||||||
|     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" |     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" | ||||||
|  |  | ||||||
|     implementation "frankiesardo:icepick:${icepickVersion}" |     implementation "frankiesardo:icepick:${icepickVersion}" | ||||||
|     kapt "frankiesardo:icepick-processor:${icepickVersion}" |     kapt "frankiesardo:icepick-processor:${icepickVersion}" | ||||||
| @@ -169,7 +169,7 @@ dependencies { | |||||||
|     implementation "com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751" |     implementation "com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751" | ||||||
|     implementation "org.jsoup:jsoup:1.13.1" |     implementation "org.jsoup:jsoup:1.13.1" | ||||||
|  |  | ||||||
|     implementation "com.squareup.okhttp3:okhttp:3.12.11" |     implementation "com.squareup.okhttp3:okhttp:3.12.12" | ||||||
|  |  | ||||||
|     implementation "com.google.android.exoplayer:exoplayer:${exoPlayerVersion}" |     implementation "com.google.android.exoplayer:exoplayer:${exoPlayerVersion}" | ||||||
|     implementation "com.google.android.exoplayer:extension-mediasession:${exoPlayerVersion}" |     implementation "com.google.android.exoplayer:extension-mediasession:${exoPlayerVersion}" | ||||||
| @@ -187,7 +187,6 @@ dependencies { | |||||||
|  |  | ||||||
|     implementation "androidx.lifecycle:lifecycle-livedata:${androidxLifecycleVersion}" |     implementation "androidx.lifecycle:lifecycle-livedata:${androidxLifecycleVersion}" | ||||||
|     implementation "androidx.lifecycle:lifecycle-viewmodel:${androidxLifecycleVersion}" |     implementation "androidx.lifecycle:lifecycle-viewmodel:${androidxLifecycleVersion}" | ||||||
|     implementation "androidx.lifecycle:lifecycle-extensions:${androidxLifecycleVersion}" |  | ||||||
|  |  | ||||||
|     implementation "androidx.room:room-runtime:${androidxRoomVersion}" |     implementation "androidx.room:room-runtime:${androidxRoomVersion}" | ||||||
|     implementation "androidx.room:room-rxjava2:${androidxRoomVersion}" |     implementation "androidx.room:room-rxjava2:${androidxRoomVersion}" | ||||||
|   | |||||||
| @@ -2,9 +2,9 @@ package org.schabi.newpipe.report; | |||||||
|  |  | ||||||
| import android.os.Parcel; | import android.os.Parcel; | ||||||
|  |  | ||||||
|  | import androidx.test.ext.junit.runners.AndroidJUnit4; | ||||||
| import androidx.test.filters.LargeTest; | import androidx.test.filters.LargeTest; | ||||||
|  |  | ||||||
| import androidx.test.runner.AndroidJUnit4; |  | ||||||
| import org.junit.Test; | import org.junit.Test; | ||||||
| import org.junit.runner.RunWith; | import org.junit.runner.RunWith; | ||||||
| import org.schabi.newpipe.R; | import org.schabi.newpipe.R; | ||||||
|   | |||||||
| @@ -300,8 +300,8 @@ public abstract class FragmentStatePagerAdapterMenuWorkaround extends PagerAdapt | |||||||
|             mSavedState.clear(); |             mSavedState.clear(); | ||||||
|             mFragments.clear(); |             mFragments.clear(); | ||||||
|             if (fss != null) { |             if (fss != null) { | ||||||
|                 for (int i = 0; i < fss.length; i++) { |                 for (final Parcelable parcelable : fss) { | ||||||
|                     mSavedState.add((Fragment.SavedState) fss[i]); |                     mSavedState.add((Fragment.SavedState) parcelable); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             final Iterable<String> keys = bundle.keySet(); |             final Iterable<String> keys = bundle.keySet(); | ||||||
|   | |||||||
| @@ -220,7 +220,7 @@ public class App extends Application { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void initNotificationChannel() { |     public void initNotificationChannel() { | ||||||
|         if (Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) { |         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ import android.content.pm.Signature; | |||||||
| import android.net.ConnectivityManager; | import android.net.ConnectivityManager; | ||||||
| import android.net.Uri; | import android.net.Uri; | ||||||
| import android.os.AsyncTask; | import android.os.AsyncTask; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
|  |  | ||||||
| import androidx.core.app.NotificationCompat; | import androidx.core.app.NotificationCompat; | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ package org.schabi.newpipe; | |||||||
|  |  | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.os.Build; | import android.os.Build; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
|  |  | ||||||
| import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||||
| import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||||
| @@ -114,8 +114,8 @@ public final class DownloaderImpl extends Downloader { | |||||||
|             // Necessary because some servers (e.g. Framatube.org) |             // Necessary because some servers (e.g. Framatube.org) | ||||||
|             // don't support the old cipher suites. |             // don't support the old cipher suites. | ||||||
|             // https://github.com/square/okhttp/issues/4053#issuecomment-402579554 |             // https://github.com/square/okhttp/issues/4053#issuecomment-402579554 | ||||||
|             final List<CipherSuite> cipherSuites = new ArrayList<>(); |             final List<CipherSuite> cipherSuites = | ||||||
|             cipherSuites.addAll(ConnectionSpec.MODERN_TLS.cipherSuites()); |                     new ArrayList<>(ConnectionSpec.MODERN_TLS.cipherSuites()); | ||||||
|             cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA); |             cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA); | ||||||
|             cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA); |             cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA); | ||||||
|             final ConnectionSpec legacyTLS = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) |             final ConnectionSpec legacyTLS = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ public class ExitActivity extends Activity { | |||||||
|     protected void onCreate(final Bundle savedInstanceState) { |     protected void onCreate(final Bundle savedInstanceState) { | ||||||
|         super.onCreate(savedInstanceState); |         super.onCreate(savedInstanceState); | ||||||
|  |  | ||||||
|         if (Build.VERSION.SDK_INT >= 21) { |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||||
|             finishAndRemoveTask(); |             finishAndRemoveTask(); | ||||||
|         } else { |         } else { | ||||||
|             finish(); |             finish(); | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ import android.annotation.SuppressLint; | |||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.content.res.Resources; | import android.content.res.Resources; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
|  |  | ||||||
| import com.nostra13.universalimageloader.core.download.BaseImageDownloader; | import com.nostra13.universalimageloader.core.download.BaseImageDownloader; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ import android.os.Build; | |||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.os.Handler; | import android.os.Handler; | ||||||
| import android.os.Looper; | import android.os.Looper; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
|  |  | ||||||
| import android.view.KeyEvent; | import android.view.KeyEvent; | ||||||
|   | |||||||
| @@ -40,7 +40,7 @@ public class PanicResponderActivity extends Activity { | |||||||
|             ExitActivity.exitAndRemoveFromRecentApps(this); |             ExitActivity.exitAndRemoveFromRecentApps(this); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (Build.VERSION.SDK_INT >= 21) { |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||||
|             finishAndRemoveTask(); |             finishAndRemoveTask(); | ||||||
|         } else { |         } else { | ||||||
|             finish(); |             finish(); | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ import android.content.Intent; | |||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.content.pm.PackageManager; | import android.content.pm.PackageManager; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.text.TextUtils; | import android.text.TextUtils; | ||||||
| import android.view.ContextThemeWrapper; | import android.view.ContextThemeWrapper; | ||||||
| import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||||
| @@ -492,12 +492,8 @@ public class RouterActivity extends AppCompatActivity { | |||||||
|                     downloadDialog.setSelectedVideoStream(selectedVideoStreamIndex); |                     downloadDialog.setSelectedVideoStream(selectedVideoStreamIndex); | ||||||
|                     downloadDialog.show(fm, "downloadDialog"); |                     downloadDialog.show(fm, "downloadDialog"); | ||||||
|                     fm.executePendingTransactions(); |                     fm.executePendingTransactions(); | ||||||
|                     downloadDialog.getDialog().setOnDismissListener(dialog -> { |                     downloadDialog.getDialog().setOnDismissListener(dialog -> finish()); | ||||||
|                         finish(); |                 }, (@NonNull Throwable throwable) -> onError()); | ||||||
|                     }); |  | ||||||
|                 }, (@NonNull Throwable throwable) -> { |  | ||||||
|                     onError(); |  | ||||||
|                 }); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @@ -572,7 +568,7 @@ public class RouterActivity extends AppCompatActivity { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         return result.toArray(new String[result.size()]); |         return result.toArray(new String[0]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static class AdapterChoiceItem { |     private static class AdapterChoiceItem { | ||||||
|   | |||||||
| @@ -167,7 +167,7 @@ public class AboutActivity extends AppCompatActivity { | |||||||
|      */ |      */ | ||||||
|     public class SectionsPagerAdapter extends FragmentPagerAdapter { |     public class SectionsPagerAdapter extends FragmentPagerAdapter { | ||||||
|         public SectionsPagerAdapter(final FragmentManager fm) { |         public SectionsPagerAdapter(final FragmentManager fm) { | ||||||
|             super(fm); |             super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         @Override |         @Override | ||||||
|   | |||||||
| @@ -14,13 +14,13 @@ import io.reactivex.Flowable; | |||||||
| @Dao | @Dao | ||||||
| public interface BasicDAO<Entity> { | public interface BasicDAO<Entity> { | ||||||
|     /* Inserts */ |     /* Inserts */ | ||||||
|     @Insert(onConflict = OnConflictStrategy.FAIL) |     @Insert(onConflict = OnConflictStrategy.ABORT) | ||||||
|     long insert(Entity entity); |     long insert(Entity entity); | ||||||
|  |  | ||||||
|     @Insert(onConflict = OnConflictStrategy.FAIL) |     @Insert(onConflict = OnConflictStrategy.ABORT) | ||||||
|     List<Long> insertAll(Entity... entities); |     List<Long> insertAll(Entity... entities); | ||||||
|  |  | ||||||
|     @Insert(onConflict = OnConflictStrategy.FAIL) |     @Insert(onConflict = OnConflictStrategy.ABORT) | ||||||
|     List<Long> insertAll(Collection<Entity> entities); |     List<Long> insertAll(Collection<Entity> entities); | ||||||
|  |  | ||||||
|     /* Searches */ |     /* Searches */ | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| package org.schabi.newpipe.download; | package org.schabi.newpipe.download; | ||||||
|  |  | ||||||
| import android.app.FragmentTransaction; |  | ||||||
| import android.content.Intent; | import android.content.Intent; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.view.Menu; | import android.view.Menu; | ||||||
| @@ -11,6 +10,7 @@ import android.view.ViewTreeObserver; | |||||||
| import androidx.appcompat.app.ActionBar; | import androidx.appcompat.app.ActionBar; | ||||||
| import androidx.appcompat.app.AppCompatActivity; | import androidx.appcompat.app.AppCompatActivity; | ||||||
| import androidx.appcompat.widget.Toolbar; | import androidx.appcompat.widget.Toolbar; | ||||||
|  | import androidx.fragment.app.FragmentTransaction; | ||||||
|  |  | ||||||
| import org.schabi.newpipe.R; | import org.schabi.newpipe.R; | ||||||
| import org.schabi.newpipe.util.DeviceUtils; | import org.schabi.newpipe.util.DeviceUtils; | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ import android.net.Uri; | |||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.os.Environment; | import android.os.Environment; | ||||||
| import android.os.IBinder; | import android.os.IBinder; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| import android.util.SparseArray; | import android.util.SparseArray; | ||||||
| import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||||
| @@ -295,7 +295,7 @@ public class DownloadDialog extends DialogFragment | |||||||
|         initToolbar(view.findViewById(R.id.toolbar)); |         initToolbar(view.findViewById(R.id.toolbar)); | ||||||
|         setupDownloadOptions(); |         setupDownloadOptions(); | ||||||
|  |  | ||||||
|         prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); |         prefs = PreferenceManager.getDefaultSharedPreferences(requireContext()); | ||||||
|  |  | ||||||
|         final int threads = prefs.getInt(getString(R.string.default_download_threads), 3); |         final int threads = prefs.getInt(getString(R.string.default_download_threads), 3); | ||||||
|         threadsCountTextView.setText(String.valueOf(threads)); |         threadsCountTextView.setText(String.valueOf(threads)); | ||||||
| @@ -516,7 +516,23 @@ public class DownloadDialog extends DialogFragment | |||||||
|         videoButton.setVisibility(isVideoStreamsAvailable ? View.VISIBLE : View.GONE); |         videoButton.setVisibility(isVideoStreamsAvailable ? View.VISIBLE : View.GONE); | ||||||
|         subtitleButton.setVisibility(isSubtitleStreamsAvailable ? View.VISIBLE : View.GONE); |         subtitleButton.setVisibility(isSubtitleStreamsAvailable ? View.VISIBLE : View.GONE); | ||||||
|  |  | ||||||
|         if (isVideoStreamsAvailable) { |         prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); | ||||||
|  |         final String defaultMedia = prefs.getString(getString(R.string.last_used_download_type), | ||||||
|  |                     getString(R.string.last_download_type_video_key)); | ||||||
|  |  | ||||||
|  |         if (isVideoStreamsAvailable | ||||||
|  |                 && (defaultMedia.equals(getString(R.string.last_download_type_video_key)))) { | ||||||
|  |             videoButton.setChecked(true); | ||||||
|  |             setupVideoSpinner(); | ||||||
|  |         } else if (isAudioStreamsAvailable | ||||||
|  |                 && (defaultMedia.equals(getString(R.string.last_download_type_audio_key)))) { | ||||||
|  |             audioButton.setChecked(true); | ||||||
|  |             setupAudioSpinner(); | ||||||
|  |         } else if (isSubtitleStreamsAvailable | ||||||
|  |                 && (defaultMedia.equals(getString(R.string.last_download_type_subtitle_key)))) { | ||||||
|  |             subtitleButton.setChecked(true); | ||||||
|  |             setupSubtitleSpinner(); | ||||||
|  |         } else if (isVideoStreamsAvailable) { | ||||||
|             videoButton.setChecked(true); |             videoButton.setChecked(true); | ||||||
|             setupVideoSpinner(); |             setupVideoSpinner(); | ||||||
|         } else if (isAudioStreamsAvailable) { |         } else if (isAudioStreamsAvailable) { | ||||||
| @@ -595,6 +611,7 @@ public class DownloadDialog extends DialogFragment | |||||||
|         final StoredDirectoryHelper mainStorage; |         final StoredDirectoryHelper mainStorage; | ||||||
|         final MediaFormat format; |         final MediaFormat format; | ||||||
|         final String mime; |         final String mime; | ||||||
|  |         final String selectedMediaType; | ||||||
|  |  | ||||||
|         // first, build the filename and get the output folder (if possible) |         // first, build the filename and get the output folder (if possible) | ||||||
|         // later, run a very very very large file checking logic |         // later, run a very very very large file checking logic | ||||||
| @@ -603,6 +620,7 @@ public class DownloadDialog extends DialogFragment | |||||||
|  |  | ||||||
|         switch (radioStreamsGroup.getCheckedRadioButtonId()) { |         switch (radioStreamsGroup.getCheckedRadioButtonId()) { | ||||||
|             case R.id.audio_button: |             case R.id.audio_button: | ||||||
|  |                 selectedMediaType = getString(R.string.last_download_type_audio_key); | ||||||
|                 mainStorage = mainStorageAudio; |                 mainStorage = mainStorageAudio; | ||||||
|                 format = audioStreamsAdapter.getItem(selectedAudioIndex).getFormat(); |                 format = audioStreamsAdapter.getItem(selectedAudioIndex).getFormat(); | ||||||
|                 switch (format) { |                 switch (format) { | ||||||
| @@ -617,12 +635,14 @@ public class DownloadDialog extends DialogFragment | |||||||
|                 } |                 } | ||||||
|                 break; |                 break; | ||||||
|             case R.id.video_button: |             case R.id.video_button: | ||||||
|  |                 selectedMediaType = getString(R.string.last_download_type_video_key); | ||||||
|                 mainStorage = mainStorageVideo; |                 mainStorage = mainStorageVideo; | ||||||
|                 format = videoStreamsAdapter.getItem(selectedVideoIndex).getFormat(); |                 format = videoStreamsAdapter.getItem(selectedVideoIndex).getFormat(); | ||||||
|                 mime = format.mimeType; |                 mime = format.mimeType; | ||||||
|                 filename += format.suffix; |                 filename += format.suffix; | ||||||
|                 break; |                 break; | ||||||
|             case R.id.subtitle_button: |             case R.id.subtitle_button: | ||||||
|  |                 selectedMediaType = getString(R.string.last_download_type_subtitle_key); | ||||||
|                 mainStorage = mainStorageVideo; // subtitle & video files go together |                 mainStorage = mainStorageVideo; // subtitle & video files go together | ||||||
|                 format = subtitleStreamsAdapter.getItem(selectedSubtitleIndex).getFormat(); |                 format = subtitleStreamsAdapter.getItem(selectedSubtitleIndex).getFormat(); | ||||||
|                 mime = format.mimeType; |                 mime = format.mimeType; | ||||||
| @@ -664,6 +684,11 @@ public class DownloadDialog extends DialogFragment | |||||||
|  |  | ||||||
|         // check for existing file with the same name |         // check for existing file with the same name | ||||||
|         checkSelectedDownload(mainStorage, mainStorage.findFile(filename), filename, mime); |         checkSelectedDownload(mainStorage, mainStorage.findFile(filename), filename, mime); | ||||||
|  |  | ||||||
|  |         // remember the last media type downloaded by the user | ||||||
|  |         prefs.edit() | ||||||
|  |                 .putString(getString(R.string.last_used_download_type), selectedMediaType) | ||||||
|  |                 .apply(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void checkSelectedDownload(final StoredDirectoryHelper mainStorage, |     private void checkSelectedDownload(final StoredDirectoryHelper mainStorage, | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ package org.schabi.newpipe.fragments; | |||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.res.ColorStateList; | import android.content.res.ColorStateList; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||||
| import android.view.Menu; | import android.view.Menu; | ||||||
| @@ -74,7 +74,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte | |||||||
|  |  | ||||||
|         youtubeRestrictedModeEnabledKey = getString(R.string.youtube_restricted_mode_enabled); |         youtubeRestrictedModeEnabledKey = getString(R.string.youtube_restricted_mode_enabled); | ||||||
|         previousYoutubeRestrictedModeEnabled = |         previousYoutubeRestrictedModeEnabled = | ||||||
|                 PreferenceManager.getDefaultSharedPreferences(getContext()) |                 PreferenceManager.getDefaultSharedPreferences(requireContext()) | ||||||
|                         .getBoolean(youtubeRestrictedModeEnabledKey, false); |                         .getBoolean(youtubeRestrictedModeEnabledKey, false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -105,7 +105,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte | |||||||
|         super.onResume(); |         super.onResume(); | ||||||
|  |  | ||||||
|         final boolean youtubeRestrictedModeEnabled = |         final boolean youtubeRestrictedModeEnabled = | ||||||
|                 PreferenceManager.getDefaultSharedPreferences(getContext()) |                 PreferenceManager.getDefaultSharedPreferences(requireContext()) | ||||||
|                         .getBoolean(youtubeRestrictedModeEnabledKey, false); |                         .getBoolean(youtubeRestrictedModeEnabledKey, false); | ||||||
|         if (previousYoutubeRestrictedModeEnabled != youtubeRestrictedModeEnabled) { |         if (previousYoutubeRestrictedModeEnabled != youtubeRestrictedModeEnabled) { | ||||||
|             previousYoutubeRestrictedModeEnabled = youtubeRestrictedModeEnabled; |             previousYoutubeRestrictedModeEnabled = youtubeRestrictedModeEnabled; | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ package org.schabi.newpipe.fragments.detail; | |||||||
| 
 | 
 | ||||||
| import android.view.ViewGroup; | import android.view.ViewGroup; | ||||||
| 
 | 
 | ||||||
|  | import androidx.annotation.NonNull; | ||||||
| import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||||
| import androidx.fragment.app.Fragment; | import androidx.fragment.app.Fragment; | ||||||
| import androidx.fragment.app.FragmentManager; | import androidx.fragment.app.FragmentManager; | ||||||
| @@ -10,16 +11,20 @@ import androidx.fragment.app.FragmentPagerAdapter; | |||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
| public class TabAdaptor extends FragmentPagerAdapter { | public class TabAdapter extends FragmentPagerAdapter { | ||||||
|     private final List<Fragment> mFragmentList = new ArrayList<>(); |     private final List<Fragment> mFragmentList = new ArrayList<>(); | ||||||
|     private final List<String> mFragmentTitleList = new ArrayList<>(); |     private final List<String> mFragmentTitleList = new ArrayList<>(); | ||||||
|     private final FragmentManager fragmentManager; |     private final FragmentManager fragmentManager; | ||||||
| 
 | 
 | ||||||
|     public TabAdaptor(final FragmentManager fm) { |     public TabAdapter(final FragmentManager fm) { | ||||||
|         super(fm); |         // if changed to BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT => crash if enqueueing stream in | ||||||
|  |         // the background and then clicking on it to open VideoDetailFragment: | ||||||
|  |         // "Cannot setMaxLifecycle for Fragment not attached to FragmentManager" | ||||||
|  |         super(fm, BEHAVIOR_SET_USER_VISIBLE_HINT); | ||||||
|         this.fragmentManager = fm; |         this.fragmentManager = fm; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @NonNull | ||||||
|     @Override |     @Override | ||||||
|     public Fragment getItem(final int position) { |     public Fragment getItem(final int position) { | ||||||
|         return mFragmentList.get(position); |         return mFragmentList.get(position); | ||||||
| @@ -57,7 +62,7 @@ public class TabAdaptor extends FragmentPagerAdapter { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public int getItemPosition(final Object object) { |     public int getItemPosition(@NonNull final Object object) { | ||||||
|         if (mFragmentList.contains(object)) { |         if (mFragmentList.contains(object)) { | ||||||
|             return mFragmentList.indexOf(object); |             return mFragmentList.indexOf(object); | ||||||
|         } else { |         } else { | ||||||
| @@ -82,7 +87,9 @@ public class TabAdaptor extends FragmentPagerAdapter { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void destroyItem(final ViewGroup container, final int position, final Object object) { |     public void destroyItem(@NonNull final ViewGroup container, | ||||||
|  |                             final int position, | ||||||
|  |                             @NonNull final Object object) { | ||||||
|         fragmentManager.beginTransaction().remove((Fragment) object).commitNowAllowingStateLoss(); |         fragmentManager.beginTransaction().remove((Fragment) object).commitNowAllowingStateLoss(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @@ -16,9 +16,9 @@ import android.os.Build; | |||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.os.Handler; | import android.os.Handler; | ||||||
| import android.os.IBinder; | import android.os.IBinder; | ||||||
| import android.preference.PreferenceManager; | import androidx.core.text.HtmlCompat; | ||||||
|  | import androidx.preference.PreferenceManager; | ||||||
| import android.provider.Settings; | import android.provider.Settings; | ||||||
| import android.text.Html; |  | ||||||
| import android.text.Spanned; | import android.text.Spanned; | ||||||
| import android.text.TextUtils; | import android.text.TextUtils; | ||||||
| import android.text.util.Linkify; | import android.text.util.Linkify; | ||||||
| @@ -244,7 +244,7 @@ public class VideoDetailFragment | |||||||
|  |  | ||||||
|     private AppBarLayout appBarLayout; |     private AppBarLayout appBarLayout; | ||||||
|     private ViewPager viewPager; |     private ViewPager viewPager; | ||||||
|     private TabAdaptor pageAdapter; |     private TabAdapter pageAdapter; | ||||||
|     private TabLayout tabLayout; |     private TabLayout tabLayout; | ||||||
|     private FrameLayout relatedStreamsLayout; |     private FrameLayout relatedStreamsLayout; | ||||||
|  |  | ||||||
| @@ -337,6 +337,7 @@ public class VideoDetailFragment | |||||||
|             stopPlayerListener(); |             stopPlayerListener(); | ||||||
|             playerService = null; |             playerService = null; | ||||||
|             player = null; |             player = null; | ||||||
|  |             saveCurrentAndRestoreDefaultBrightness(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -425,8 +426,8 @@ public class VideoDetailFragment | |||||||
|         if (currentWorker != null) { |         if (currentWorker != null) { | ||||||
|             currentWorker.dispose(); |             currentWorker.dispose(); | ||||||
|         } |         } | ||||||
|         setupBrightness(true); |         saveCurrentAndRestoreDefaultBrightness(); | ||||||
|         PreferenceManager.getDefaultSharedPreferences(getContext()) |         PreferenceManager.getDefaultSharedPreferences(requireContext()) | ||||||
|                 .edit() |                 .edit() | ||||||
|                 .putString(getString(R.string.stream_info_selected_tab_key), |                 .putString(getString(R.string.stream_info_selected_tab_key), | ||||||
|                         pageAdapter.getItemTitle(viewPager.getCurrentItem())) |                         pageAdapter.getItemTitle(viewPager.getCurrentItem())) | ||||||
| @@ -439,7 +440,7 @@ public class VideoDetailFragment | |||||||
|  |  | ||||||
|         activity.sendBroadcast(new Intent(ACTION_VIDEO_FRAGMENT_RESUMED)); |         activity.sendBroadcast(new Intent(ACTION_VIDEO_FRAGMENT_RESUMED)); | ||||||
|  |  | ||||||
|         setupBrightness(false); |         setupBrightness(); | ||||||
|  |  | ||||||
|         if (updateFlags != 0) { |         if (updateFlags != 0) { | ||||||
|             if (!isLoading.get() && currentInfo != null) { |             if (!isLoading.get() && currentInfo != null) { | ||||||
| @@ -552,7 +553,6 @@ public class VideoDetailFragment | |||||||
|  |  | ||||||
|         Serializable serializable = savedState.getSerializable(INFO_KEY); |         Serializable serializable = savedState.getSerializable(INFO_KEY); | ||||||
|         if (serializable instanceof StreamInfo) { |         if (serializable instanceof StreamInfo) { | ||||||
|             //noinspection unchecked |  | ||||||
|             currentInfo = (StreamInfo) serializable; |             currentInfo = (StreamInfo) serializable; | ||||||
|             InfoCache.getInstance().putInfo(serviceId, url, currentInfo, InfoItem.InfoType.STREAM); |             InfoCache.getInstance().putInfo(serviceId, url, currentInfo, InfoItem.InfoType.STREAM); | ||||||
|         } |         } | ||||||
| @@ -672,7 +672,8 @@ public class VideoDetailFragment | |||||||
|                 } |                 } | ||||||
|                 break; |                 break; | ||||||
|             case R.id.detail_title_root_layout: |             case R.id.detail_title_root_layout: | ||||||
|                 ShareUtils.copyToClipboard(getContext(), videoTitleTextView.getText().toString()); |                 ShareUtils.copyToClipboard(requireContext(), | ||||||
|  |                         videoTitleTextView.getText().toString()); | ||||||
|                 break; |                 break; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -751,7 +752,7 @@ public class VideoDetailFragment | |||||||
|  |  | ||||||
|         appBarLayout = rootView.findViewById(R.id.appbarlayout); |         appBarLayout = rootView.findViewById(R.id.appbarlayout); | ||||||
|         viewPager = rootView.findViewById(R.id.viewpager); |         viewPager = rootView.findViewById(R.id.viewpager); | ||||||
|         pageAdapter = new TabAdaptor(getChildFragmentManager()); |         pageAdapter = new TabAdapter(getChildFragmentManager()); | ||||||
|         viewPager.setAdapter(pageAdapter); |         viewPager.setAdapter(pageAdapter); | ||||||
|         tabLayout = rootView.findViewById(R.id.tablayout); |         tabLayout = rootView.findViewById(R.id.tablayout); | ||||||
|         tabLayout.setupWithViewPager(viewPager); |         tabLayout.setupWithViewPager(viewPager); | ||||||
| @@ -1105,7 +1106,7 @@ public class VideoDetailFragment | |||||||
|             player.toggleFullscreen(); |             player.toggleFullscreen(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!useExternalAudioPlayer && android.os.Build.VERSION.SDK_INT >= 16) { |         if (!useExternalAudioPlayer) { | ||||||
|             openNormalBackgroundPlayer(append); |             openNormalBackgroundPlayer(append); | ||||||
|         } else { |         } else { | ||||||
|             startOnExternalPlayer(activity, currentInfo, audioStream); |             startOnExternalPlayer(activity, currentInfo, audioStream); | ||||||
| @@ -1302,24 +1303,17 @@ public class VideoDetailFragment | |||||||
|  |  | ||||||
|         if (description.getType() == Description.HTML) { |         if (description.getType() == Description.HTML) { | ||||||
|             disposables.add(Single.just(description.getContent()) |             disposables.add(Single.just(description.getContent()) | ||||||
|                     .map((@NonNull String descriptionText) -> { |                     .map((@NonNull final String descriptionText) -> | ||||||
|                         final Spanned parsedDescription; |                             HtmlCompat.fromHtml(descriptionText, | ||||||
|                         if (Build.VERSION.SDK_INT >= 24) { |                                     HtmlCompat.FROM_HTML_MODE_LEGACY)) | ||||||
|                             parsedDescription = Html.fromHtml(descriptionText, 0); |  | ||||||
|                         } else { |  | ||||||
|                             //noinspection deprecation |  | ||||||
|                             parsedDescription = Html.fromHtml(descriptionText); |  | ||||||
|                         } |  | ||||||
|                         return parsedDescription; |  | ||||||
|                     }) |  | ||||||
|                     .subscribeOn(Schedulers.computation()) |                     .subscribeOn(Schedulers.computation()) | ||||||
|                     .observeOn(AndroidSchedulers.mainThread()) |                     .observeOn(AndroidSchedulers.mainThread()) | ||||||
|                     .subscribe((@NonNull Spanned spanned) -> { |                     .subscribe((@NonNull final Spanned spanned) -> { | ||||||
|                         videoDescriptionView.setText(spanned); |                         videoDescriptionView.setText(spanned); | ||||||
|                         videoDescriptionView.setVisibility(View.VISIBLE); |                         videoDescriptionView.setVisibility(View.VISIBLE); | ||||||
|                     })); |                     })); | ||||||
|         } else if (description.getType() == Description.MARKDOWN) { |         } else if (description.getType() == Description.MARKDOWN) { | ||||||
|             final Markwon markwon = Markwon.builder(getContext()) |             final Markwon markwon = Markwon.builder(requireContext()) | ||||||
|                     .usePlugin(LinkifyPlugin.create()) |                     .usePlugin(LinkifyPlugin.create()) | ||||||
|                     .build(); |                     .build(); | ||||||
|             markwon.setMarkdown(videoDescriptionView, description.getContent()); |             markwon.setMarkdown(videoDescriptionView, description.getContent()); | ||||||
| @@ -1908,6 +1902,7 @@ public class VideoDetailFragment | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void onFullscreenStateChanged(final boolean fullscreen) { |     public void onFullscreenStateChanged(final boolean fullscreen) { | ||||||
|  |         setupBrightness(); | ||||||
|         if (playerService.getView() == null || player.getParentActivity() == null) { |         if (playerService.getView() == null || player.getParentActivity() == null) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| @@ -1982,6 +1977,11 @@ public class VideoDetailFragment | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         // Prevent jumping of the player on devices with cutout | ||||||
|  |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { | ||||||
|  |             activity.getWindow().getAttributes().layoutInDisplayCutoutMode = | ||||||
|  |                     WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT; | ||||||
|  |         } | ||||||
|         activity.getWindow().getDecorView().setSystemUiVisibility(0); |         activity.getWindow().getDecorView().setSystemUiVisibility(0); | ||||||
|         activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); |         activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); | ||||||
|     } |     } | ||||||
| @@ -1995,6 +1995,11 @@ public class VideoDetailFragment | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         // Prevent jumping of the player on devices with cutout | ||||||
|  |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { | ||||||
|  |             activity.getWindow().getAttributes().layoutInDisplayCutoutMode = | ||||||
|  |                     WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER; | ||||||
|  |         } | ||||||
|         final int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE |         final int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | ||||||
|                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | ||||||
|                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | ||||||
| @@ -2022,30 +2027,42 @@ public class VideoDetailFragment | |||||||
|                 && player.getPlayer().getPlaybackState() != Player.STATE_IDLE; |                 && player.getPlayer().getPlaybackState() != Player.STATE_IDLE; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void setupBrightness(final boolean save) { |     private void saveCurrentAndRestoreDefaultBrightness() { | ||||||
|  |         final WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); | ||||||
|  |         if (lp.screenBrightness == -1) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         // Save current brightness level | ||||||
|  |         PlayerHelper.setScreenBrightness(activity, lp.screenBrightness); | ||||||
|  |  | ||||||
|  |         // Restore the old  brightness when fragment.onPause() called or | ||||||
|  |         // when a player is in portrait | ||||||
|  |         lp.screenBrightness = -1; | ||||||
|  |         activity.getWindow().setAttributes(lp); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void setupBrightness() { | ||||||
|         if (activity == null) { |         if (activity == null) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         final WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); |         final WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); | ||||||
|         if (save) { |         if (player == null | ||||||
|             // Save current brightness level |                 || !player.videoPlayerSelected() | ||||||
|             PlayerHelper.setScreenBrightness(activity, lp.screenBrightness); |                 || !player.isFullscreen() | ||||||
|  |                 || bottomSheetState != BottomSheetBehavior.STATE_EXPANDED) { | ||||||
|             // Restore the old  brightness when fragment.onPause() called. |             // Apply system brightness when the player is not in fullscreen | ||||||
|             // It means when user leaves this fragment brightness will be set to system brightness |             saveCurrentAndRestoreDefaultBrightness(); | ||||||
|             lp.screenBrightness = -1; |  | ||||||
|         } else { |         } else { | ||||||
|             // Restore already saved brightness level |             // Restore already saved brightness level | ||||||
|             final float brightnessLevel = PlayerHelper.getScreenBrightness(activity); |             final float brightnessLevel = PlayerHelper.getScreenBrightness(activity); | ||||||
|             if (brightnessLevel <= 0.0f && brightnessLevel > 1.0f) { |             if (brightnessLevel == lp.screenBrightness) { | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             lp.screenBrightness = brightnessLevel; |             lp.screenBrightness = brightnessLevel; | ||||||
|         } |  | ||||||
|             activity.getWindow().setAttributes(lp); |             activity.getWindow().setAttributes(lp); | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private void checkLandscape() { |     private void checkLandscape() { | ||||||
|         if ((!player.isPlaying() && player.getPlayQueue() != playQueue) |         if ((!player.isPlaying() && player.getPlayQueue() != playQueue) | ||||||
| @@ -2167,6 +2184,7 @@ public class VideoDetailFragment | |||||||
|      * @param toMain if true than the main fragment will be focused or the player otherwise |      * @param toMain if true than the main fragment will be focused or the player otherwise | ||||||
|      */ |      */ | ||||||
|     private void moveFocusToMainFragment(final boolean toMain) { |     private void moveFocusToMainFragment(final boolean toMain) { | ||||||
|  |         setupBrightness(); | ||||||
|         final ViewGroup mainFragment = requireActivity().findViewById(R.id.fragment_holder); |         final ViewGroup mainFragment = requireActivity().findViewById(R.id.fragment_holder); | ||||||
|         // Hamburger button steels a focus even under bottomSheet |         // Hamburger button steels a focus even under bottomSheet | ||||||
|         final Toolbar toolbar = requireActivity().findViewById(R.id.toolbar); |         final Toolbar toolbar = requireActivity().findViewById(R.id.toolbar); | ||||||
| @@ -2190,7 +2208,7 @@ public class VideoDetailFragment | |||||||
|      * Bottom padding should be equal to the mini player's height in this case |      * Bottom padding should be equal to the mini player's height in this case | ||||||
|      * |      * | ||||||
|      * @param showMore whether main fragment should be expanded or not |      * @param showMore whether main fragment should be expanded or not | ||||||
|      * */ |      */ | ||||||
|     private void manageSpaceAtTheBottom(final boolean showMore) { |     private void manageSpaceAtTheBottom(final boolean showMore) { | ||||||
|         final int peekHeight = getResources().getDimensionPixelSize(R.dimen.mini_player_height); |         final int peekHeight = getResources().getDimensionPixelSize(R.dimen.mini_player_height); | ||||||
|         final ViewGroup holder = requireActivity().findViewById(R.id.fragment_holder); |         final ViewGroup holder = requireActivity().findViewById(R.id.fragment_holder); | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ import android.content.SharedPreferences; | |||||||
| import android.content.res.Configuration; | import android.content.res.Configuration; | ||||||
| import android.content.res.Resources; | import android.content.res.Resources; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| import android.view.Menu; | import android.view.Menu; | ||||||
| import android.view.MenuInflater; | import android.view.MenuInflater; | ||||||
|   | |||||||
| @@ -133,7 +133,7 @@ public abstract class BaseListInfoFragment<I extends ListInfo> | |||||||
|                     currentInfo = result; |                     currentInfo = result; | ||||||
|                     currentNextPage = result.getNextPage(); |                     currentNextPage = result.getNextPage(); | ||||||
|                     handleResult(result); |                     handleResult(result); | ||||||
|                 }, (@NonNull Throwable throwable) -> onError(throwable)); |                 }, this::onError); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -26,8 +26,6 @@ import io.reactivex.disposables.CompositeDisposable; | |||||||
| public class CommentsFragment extends BaseListInfoFragment<CommentsInfo> { | public class CommentsFragment extends BaseListInfoFragment<CommentsInfo> { | ||||||
|     private CompositeDisposable disposables = new CompositeDisposable(); |     private CompositeDisposable disposables = new CompositeDisposable(); | ||||||
|  |  | ||||||
|     private boolean mIsVisibleToUser = false; |  | ||||||
|  |  | ||||||
|     public static CommentsFragment getInstance(final int serviceId, final  String url, |     public static CommentsFragment getInstance(final int serviceId, final  String url, | ||||||
|                                                final String name) { |                                                final String name) { | ||||||
|         final CommentsFragment instance = new CommentsFragment(); |         final CommentsFragment instance = new CommentsFragment(); | ||||||
| @@ -39,12 +37,6 @@ public class CommentsFragment extends BaseListInfoFragment<CommentsInfo> { | |||||||
|     // LifeCycle |     // LifeCycle | ||||||
|     //////////////////////////////////////////////////////////////////////////*/ |     //////////////////////////////////////////////////////////////////////////*/ | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void setUserVisibleHint(final boolean isVisibleToUser) { |  | ||||||
|         super.setUserVisibleHint(isVisibleToUser); |  | ||||||
|         mIsVisibleToUser = isVisibleToUser; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void onAttach(final Context context) { |     public void onAttach(final Context context) { | ||||||
|         super.onAttach(context); |         super.onAttach(context); | ||||||
| @@ -92,7 +84,7 @@ public class CommentsFragment extends BaseListInfoFragment<CommentsInfo> { | |||||||
|     public void handleResult(@NonNull final CommentsInfo result) { |     public void handleResult(@NonNull final CommentsInfo result) { | ||||||
|         super.handleResult(result); |         super.handleResult(result); | ||||||
|  |  | ||||||
|         AnimationUtils.slideUp(getView(), 120, 150, 0.06f); |         AnimationUtils.slideUp(requireView(), 120, 150, 0.06f); | ||||||
|  |  | ||||||
|         if (!result.getErrors().isEmpty()) { |         if (!result.getErrors().isEmpty()) { | ||||||
|             showSnackBarError(result.getErrors(), UserAction.REQUESTED_COMMENTS, |             showSnackBarError(result.getErrors(), UserAction.REQUESTED_COMMENTS, | ||||||
|   | |||||||
| @@ -5,7 +5,8 @@ import android.content.Context; | |||||||
| import android.content.Intent; | import android.content.Intent; | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.preference.PreferenceManager; | import androidx.core.text.HtmlCompat; | ||||||
|  | import androidx.preference.PreferenceManager; | ||||||
| import android.text.Editable; | import android.text.Editable; | ||||||
| import android.text.Html; | import android.text.Html; | ||||||
| import android.text.TextUtils; | import android.text.TextUtils; | ||||||
| @@ -73,7 +74,6 @@ import io.reactivex.disposables.Disposable; | |||||||
| import io.reactivex.schedulers.Schedulers; | import io.reactivex.schedulers.Schedulers; | ||||||
| import io.reactivex.subjects.PublishSubject; | import io.reactivex.subjects.PublishSubject; | ||||||
|  |  | ||||||
| import static android.text.Html.escapeHtml; |  | ||||||
| import static androidx.recyclerview.widget.ItemTouchHelper.Callback.makeMovementFlags; | import static androidx.recyclerview.widget.ItemTouchHelper.Callback.makeMovementFlags; | ||||||
| import static java.util.Arrays.asList; | import static java.util.Arrays.asList; | ||||||
| import static org.schabi.newpipe.util.AnimationUtils.animateView; | import static org.schabi.newpipe.util.AnimationUtils.animateView; | ||||||
| @@ -1005,10 +1005,9 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I | |||||||
|                     : R.string.did_you_mean); |                     : R.string.did_you_mean); | ||||||
|  |  | ||||||
|             final String highlightedSearchSuggestion = |             final String highlightedSearchSuggestion = | ||||||
|                     "<b><i>" + escapeHtml(searchSuggestion) + "</i></b>"; |                     "<b><i>" + Html.escapeHtml(searchSuggestion) + "</i></b>"; | ||||||
|             correctSuggestion.setText( |             final String text = String.format(helperText, highlightedSearchSuggestion); | ||||||
|                     Html.fromHtml(String.format(helperText, highlightedSearchSuggestion))); |             correctSuggestion.setText(HtmlCompat.fromHtml(text, HtmlCompat.FROM_HTML_MODE_LEGACY)); | ||||||
|  |  | ||||||
|  |  | ||||||
|             correctSuggestion.setOnClickListener(v -> { |             correctSuggestion.setOnClickListener(v -> { | ||||||
|                 correctSuggestion.setVisibility(View.GONE); |                 correctSuggestion.setVisibility(View.GONE); | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ package org.schabi.newpipe.fragments.list.videos; | |||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||||
| import android.view.Menu; | import android.view.Menu; | ||||||
| import android.view.MenuInflater; | import android.view.MenuInflater; | ||||||
| @@ -78,11 +78,11 @@ public class RelatedVideosFragment extends BaseListInfoFragment<RelatedStreamInf | |||||||
|             autoplaySwitch = headerRootLayout.findViewById(R.id.autoplay_switch); |             autoplaySwitch = headerRootLayout.findViewById(R.id.autoplay_switch); | ||||||
|  |  | ||||||
|             final SharedPreferences pref = PreferenceManager |             final SharedPreferences pref = PreferenceManager | ||||||
|                     .getDefaultSharedPreferences(getContext()); |                     .getDefaultSharedPreferences(requireContext()); | ||||||
|             final boolean autoplay = pref.getBoolean(getString(R.string.auto_queue_key), false); |             final boolean autoplay = pref.getBoolean(getString(R.string.auto_queue_key), false); | ||||||
|             autoplaySwitch.setChecked(autoplay); |             autoplaySwitch.setChecked(autoplay); | ||||||
|             autoplaySwitch.setOnCheckedChangeListener((compoundButton, b) -> |             autoplaySwitch.setOnCheckedChangeListener((compoundButton, b) -> | ||||||
|                     PreferenceManager.getDefaultSharedPreferences(getContext()).edit() |                     PreferenceManager.getDefaultSharedPreferences(requireContext()).edit() | ||||||
|                             .putBoolean(getString(R.string.auto_queue_key), b).apply()); |                             .putBoolean(getString(R.string.auto_queue_key), b).apply()); | ||||||
|             return headerRootLayout; |             return headerRootLayout; | ||||||
|         } else { |         } else { | ||||||
| @@ -166,12 +166,10 @@ public class RelatedVideosFragment extends BaseListInfoFragment<RelatedStreamInf | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void setTitle(final String title) { |     public void setTitle(final String title) { | ||||||
|         return; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { |     public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { | ||||||
|         return; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void setInitialData(final StreamInfo info) { |     private void setInitialData(final StreamInfo info) { | ||||||
| @@ -201,7 +199,8 @@ public class RelatedVideosFragment extends BaseListInfoFragment<RelatedStreamInf | |||||||
|     @Override |     @Override | ||||||
|     public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, |     public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, | ||||||
|                                           final String s) { |                                           final String s) { | ||||||
|         final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getContext()); |         final SharedPreferences pref = | ||||||
|  |                 PreferenceManager.getDefaultSharedPreferences(requireContext()); | ||||||
|         final boolean autoplay = pref.getBoolean(getString(R.string.auto_queue_key), false); |         final boolean autoplay = pref.getBoolean(getString(R.string.auto_queue_key), false); | ||||||
|         if (autoplaySwitch != null) { |         if (autoplaySwitch != null) { | ||||||
|             autoplaySwitch.setChecked(autoplay); |             autoplaySwitch.setChecked(autoplay); | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| package org.schabi.newpipe.info_list.holder; | package org.schabi.newpipe.info_list.holder; | ||||||
|  |  | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.text.TextUtils; | import android.text.TextUtils; | ||||||
| import android.view.ViewGroup; | import android.view.ViewGroup; | ||||||
| import android.widget.TextView; | import android.widget.TextView; | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ import android.content.SharedPreferences; | |||||||
| import android.content.res.Configuration; | import android.content.res.Configuration; | ||||||
| import android.content.res.Resources; | import android.content.res.Resources; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| import android.view.Menu; | import android.view.Menu; | ||||||
| import android.view.MenuInflater; | import android.view.MenuInflater; | ||||||
|   | |||||||
| @@ -271,9 +271,8 @@ public final class BookmarkFragment extends BaseLocalListFragment<List<PlaylistL | |||||||
|  |  | ||||||
|         final Builder builder = new AlertDialog.Builder(activity); |         final Builder builder = new AlertDialog.Builder(activity); | ||||||
|         builder.setView(dialogView) |         builder.setView(dialogView) | ||||||
|                 .setPositiveButton(R.string.rename_playlist, (dialog, which) -> { |                 .setPositiveButton(R.string.rename_playlist, (dialog, which) -> | ||||||
|                     changeLocalPlaylistName(selectedItem.uid, editText.getText().toString()); |                         changeLocalPlaylistName(selectedItem.uid, editText.getText().toString())) | ||||||
|                 }) |  | ||||||
|                 .setNegativeButton(R.string.cancel, null) |                 .setNegativeButton(R.string.cancel, null) | ||||||
|                 .setNeutralButton(R.string.delete, (dialog, which) -> { |                 .setNeutralButton(R.string.delete, (dialog, which) -> { | ||||||
|                     showDeleteDialog(selectedItem.name, |                     showDeleteDialog(selectedItem.name, | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ import android.view.View | |||||||
| import android.view.ViewGroup | import android.view.ViewGroup | ||||||
| import androidx.appcompat.app.AlertDialog | import androidx.appcompat.app.AlertDialog | ||||||
| import androidx.lifecycle.Observer | import androidx.lifecycle.Observer | ||||||
| import androidx.lifecycle.ViewModelProviders | import androidx.lifecycle.ViewModelProvider | ||||||
| import androidx.preference.PreferenceManager | import androidx.preference.PreferenceManager | ||||||
| import icepick.State | import icepick.State | ||||||
| import java.util.Calendar | import java.util.Calendar | ||||||
| @@ -82,7 +82,7 @@ class FeedFragment : BaseListFragment<FeedState, Unit>() { | |||||||
|     override fun onViewCreated(rootView: View, savedInstanceState: Bundle?) { |     override fun onViewCreated(rootView: View, savedInstanceState: Bundle?) { | ||||||
|         super.onViewCreated(rootView, savedInstanceState) |         super.onViewCreated(rootView, savedInstanceState) | ||||||
|  |  | ||||||
|         viewModel = ViewModelProviders.of(this, FeedViewModel.Factory(requireContext(), groupId)).get(FeedViewModel::class.java) |         viewModel = ViewModelProvider(this, FeedViewModel.Factory(requireContext(), groupId)).get(FeedViewModel::class.java) | ||||||
|         viewModel.stateLiveData.observe(viewLifecycleOwner, Observer { it?.let(::handleResult) }) |         viewModel.stateLiveData.observe(viewLifecycleOwner, Observer { it?.let(::handleResult) }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -27,10 +27,10 @@ import android.content.Intent | |||||||
| import android.content.IntentFilter | import android.content.IntentFilter | ||||||
| import android.os.Build | import android.os.Build | ||||||
| import android.os.IBinder | import android.os.IBinder | ||||||
| import android.preference.PreferenceManager |  | ||||||
| import android.util.Log | import android.util.Log | ||||||
| import androidx.core.app.NotificationCompat | import androidx.core.app.NotificationCompat | ||||||
| import androidx.core.app.NotificationManagerCompat | import androidx.core.app.NotificationManagerCompat | ||||||
|  | import androidx.preference.PreferenceManager | ||||||
| import io.reactivex.Flowable | import io.reactivex.Flowable | ||||||
| import io.reactivex.Notification | import io.reactivex.Notification | ||||||
| import io.reactivex.Single | import io.reactivex.Single | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ package org.schabi.newpipe.local.history; | |||||||
|  |  | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
|  |  | ||||||
| import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -553,9 +553,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt | |||||||
|                 .setView(dialogView) |                 .setView(dialogView) | ||||||
|                 .setCancelable(true) |                 .setCancelable(true) | ||||||
|                 .setNegativeButton(R.string.cancel, null) |                 .setNegativeButton(R.string.cancel, null) | ||||||
|                 .setPositiveButton(R.string.rename, (dialogInterface, i) -> { |                 .setPositiveButton(R.string.rename, (dialogInterface, i) -> | ||||||
|                     changePlaylistName(nameEdit.getText().toString()); |                         changePlaylistName(nameEdit.getText().toString())); | ||||||
|                 }); |  | ||||||
|  |  | ||||||
|         dialogBuilder.show(); |         dialogBuilder.show(); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -11,15 +11,15 @@ import android.content.res.Configuration | |||||||
| import android.os.Bundle | import android.os.Bundle | ||||||
| import android.os.Environment | import android.os.Environment | ||||||
| import android.os.Parcelable | import android.os.Parcelable | ||||||
| import android.preference.PreferenceManager |  | ||||||
| import android.view.LayoutInflater | import android.view.LayoutInflater | ||||||
| import android.view.Menu | import android.view.Menu | ||||||
| import android.view.MenuInflater | import android.view.MenuInflater | ||||||
| import android.view.View | import android.view.View | ||||||
| import android.view.ViewGroup | import android.view.ViewGroup | ||||||
| import android.widget.Toast | import android.widget.Toast | ||||||
| import androidx.lifecycle.ViewModelProviders | import androidx.lifecycle.ViewModelProvider | ||||||
| import androidx.localbroadcastmanager.content.LocalBroadcastManager | import androidx.localbroadcastmanager.content.LocalBroadcastManager | ||||||
|  | import androidx.preference.PreferenceManager | ||||||
| import androidx.recyclerview.widget.GridLayoutManager | import androidx.recyclerview.widget.GridLayoutManager | ||||||
| import com.nononsenseapps.filepicker.Utils | import com.nononsenseapps.filepicker.Utils | ||||||
| import com.xwray.groupie.Group | import com.xwray.groupie.Group | ||||||
| @@ -277,7 +277,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() { | |||||||
|         } |         } | ||||||
|         items_list.adapter = groupAdapter |         items_list.adapter = groupAdapter | ||||||
|  |  | ||||||
|         viewModel = ViewModelProviders.of(this).get(SubscriptionViewModel::class.java) |         viewModel = ViewModelProvider(this).get(SubscriptionViewModel::class.java) | ||||||
|         viewModel.stateLiveData.observe(viewLifecycleOwner, androidx.lifecycle.Observer { it?.let(this::handleResult) }) |         viewModel.stateLiveData.observe(viewLifecycleOwner, androidx.lifecycle.Observer { it?.let(this::handleResult) }) | ||||||
|         viewModel.feedGroupsLiveData.observe(viewLifecycleOwner, androidx.lifecycle.Observer { it?.let(this::handleFeedGroups) }) |         viewModel.feedGroupsLiveData.observe(viewLifecycleOwner, androidx.lifecycle.Observer { it?.let(this::handleFeedGroups) }) | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -252,7 +252,7 @@ class FeedGroupDialog : DialogFragment(), BackPressable { | |||||||
|             } |             } | ||||||
|         }) |         }) | ||||||
|  |  | ||||||
|         subscriptionGroupAdapter?.setOnItemClickListener(subscriptionPickerItemListener) |         subscriptionGroupAdapter.setOnItemClickListener(subscriptionPickerItemListener) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun handlePositiveButton() = when { |     private fun handlePositiveButton() = when { | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ import android.view.View | |||||||
| import android.view.ViewGroup | import android.view.ViewGroup | ||||||
| import androidx.fragment.app.DialogFragment | import androidx.fragment.app.DialogFragment | ||||||
| import androidx.lifecycle.Observer | import androidx.lifecycle.Observer | ||||||
| import androidx.lifecycle.ViewModelProviders | import androidx.lifecycle.ViewModelProvider | ||||||
| import androidx.recyclerview.widget.ItemTouchHelper | import androidx.recyclerview.widget.ItemTouchHelper | ||||||
| import androidx.recyclerview.widget.ItemTouchHelper.SimpleCallback | import androidx.recyclerview.widget.ItemTouchHelper.SimpleCallback | ||||||
| import androidx.recyclerview.widget.LinearLayoutManager | import androidx.recyclerview.widget.LinearLayoutManager | ||||||
| @@ -49,7 +49,7 @@ class FeedGroupReorderDialog : DialogFragment() { | |||||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||||
|         super.onViewCreated(view, savedInstanceState) |         super.onViewCreated(view, savedInstanceState) | ||||||
|  |  | ||||||
|         viewModel = ViewModelProviders.of(this).get(FeedGroupReorderDialogViewModel::class.java) |         viewModel = ViewModelProvider(this).get(FeedGroupReorderDialogViewModel::class.java) | ||||||
|         viewModel.groupsLiveData.observe(viewLifecycleOwner, Observer(::handleGroups)) |         viewModel.groupsLiveData.observe(viewLifecycleOwner, Observer(::handleGroups)) | ||||||
|         viewModel.dialogEventLiveData.observe(viewLifecycleOwner, Observer { |         viewModel.dialogEventLiveData.observe(viewLifecycleOwner, Observer { | ||||||
|             when (it) { |             when (it) { | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ import android.content.SharedPreferences; | |||||||
| import android.graphics.Bitmap; | import android.graphics.Bitmap; | ||||||
| import android.graphics.BitmapFactory; | import android.graphics.BitmapFactory; | ||||||
| import android.media.AudioManager; | import android.media.AudioManager; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| import android.view.View; | import android.view.View; | ||||||
| import android.widget.Toast; | import android.widget.Toast; | ||||||
| @@ -1342,6 +1342,11 @@ public abstract class BasePlayer implements | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         final StreamInfo currentInfo = currentMetadata.getMetadata(); |         final StreamInfo currentInfo = currentMetadata.getMetadata(); | ||||||
|  |         if (playQueue != null) { | ||||||
|  |             // Save current position. It will help to restore this position once a user | ||||||
|  |             // wants to play prev or next stream from the queue | ||||||
|  |             playQueue.setRecovery(playQueue.getIndex(), simpleExoPlayer.getContentPosition()); | ||||||
|  |         } | ||||||
|         savePlaybackState(currentInfo, simpleExoPlayer.getCurrentPosition()); |         savePlaybackState(currentInfo, simpleExoPlayer.getCurrentPosition()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -162,6 +162,9 @@ public final class MainPlayer extends Service { | |||||||
|     @Override |     @Override | ||||||
|     public void onTaskRemoved(final Intent rootIntent) { |     public void onTaskRemoved(final Intent rootIntent) { | ||||||
|         super.onTaskRemoved(rootIntent); |         super.onTaskRemoved(rootIntent); | ||||||
|  |         if (!playerImpl.videoPlayerSelected()) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|         onDestroy(); |         onDestroy(); | ||||||
|         // Unload from memory completely |         // Unload from memory completely | ||||||
|         Runtime.getRuntime().halt(0); |         Runtime.getRuntime().halt(0); | ||||||
|   | |||||||
| @@ -30,9 +30,10 @@ import android.content.SharedPreferences; | |||||||
| import android.graphics.Bitmap; | import android.graphics.Bitmap; | ||||||
| import android.graphics.Color; | import android.graphics.Color; | ||||||
| import android.graphics.PorterDuff; | import android.graphics.PorterDuff; | ||||||
|  | import android.graphics.PorterDuffColorFilter; | ||||||
| import android.os.Build; | import android.os.Build; | ||||||
| import android.os.Handler; | import android.os.Handler; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
|  |  | ||||||
| import android.view.Menu; | import android.view.Menu; | ||||||
| @@ -210,18 +211,18 @@ public abstract class VideoPlayer extends BasePlayer | |||||||
|  |  | ||||||
|         this.captionTextView = view.findViewById(R.id.captionTextView); |         this.captionTextView = view.findViewById(R.id.captionTextView); | ||||||
|  |  | ||||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { |         playbackSeekBar.getThumb() | ||||||
|             playbackSeekBar.getThumb().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN); |                 .setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN)); | ||||||
|         } |         this.playbackSeekBar.getProgressDrawable() | ||||||
|         this.playbackSeekBar.getProgressDrawable(). |                 .setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY)); | ||||||
|                 setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY); |  | ||||||
|  |  | ||||||
|         this.qualityPopupMenu = new PopupMenu(context, qualityTextView); |         this.qualityPopupMenu = new PopupMenu(context, qualityTextView); | ||||||
|         this.playbackSpeedPopupMenu = new PopupMenu(context, playbackSpeedTextView); |         this.playbackSpeedPopupMenu = new PopupMenu(context, playbackSpeedTextView); | ||||||
|         this.captionPopupMenu = new PopupMenu(context, captionTextView); |         this.captionPopupMenu = new PopupMenu(context, captionTextView); | ||||||
|  |  | ||||||
|         ((ProgressBar) this.loadingPanel.findViewById(R.id.progressBarLoadingPanel)) |         ((ProgressBar) this.loadingPanel.findViewById(R.id.progressBarLoadingPanel)) | ||||||
|                 .getIndeterminateDrawable().setColorFilter(Color.WHITE, PorterDuff.Mode.MULTIPLY); |                 .getIndeterminateDrawable() | ||||||
|  |                 .setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.MULTIPLY)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected abstract void setupSubtitleView(@NonNull SubtitleView view, float captionScale, |     protected abstract void setupSubtitleView(@NonNull SubtitleView view, float captionScale, | ||||||
| @@ -249,7 +250,7 @@ public abstract class VideoPlayer extends BasePlayer | |||||||
|         simpleExoPlayer.addTextOutput(cues -> subtitleView.onCues(cues)); |         simpleExoPlayer.addTextOutput(cues -> subtitleView.onCues(cues)); | ||||||
|  |  | ||||||
|         // Setup audio session with onboard equalizer |         // Setup audio session with onboard equalizer | ||||||
|         if (Build.VERSION.SDK_INT >= 21) { |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||||
|             trackSelector.setParameters(trackSelector.buildUponParameters() |             trackSelector.setParameters(trackSelector.buildUponParameters() | ||||||
|                     .setTunnelingAudioSessionId(C.generateAudioSessionIdV21(context))); |                     .setTunnelingAudioSessionId(C.generateAudioSessionIdV21(context))); | ||||||
|         } |         } | ||||||
| @@ -456,11 +457,8 @@ public abstract class VideoPlayer extends BasePlayer | |||||||
|         animateView(controlsRoot, false, DEFAULT_CONTROLS_DURATION); |         animateView(controlsRoot, false, DEFAULT_CONTROLS_DURATION); | ||||||
|  |  | ||||||
|         playbackSeekBar.setEnabled(false); |         playbackSeekBar.setEnabled(false); | ||||||
|         // Bug on lower api, disabling and enabling the seekBar resets the thumb color -.-, |         playbackSeekBar.getThumb() | ||||||
|         // so sets the color again |                 .setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN)); | ||||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { |  | ||||||
|             playbackSeekBar.getThumb().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         loadingPanel.setBackgroundColor(Color.BLACK); |         loadingPanel.setBackgroundColor(Color.BLACK); | ||||||
|         animateView(loadingPanel, true, 0); |         animateView(loadingPanel, true, 0); | ||||||
| @@ -476,11 +474,8 @@ public abstract class VideoPlayer extends BasePlayer | |||||||
|         showAndAnimateControl(-1, true); |         showAndAnimateControl(-1, true); | ||||||
|  |  | ||||||
|         playbackSeekBar.setEnabled(true); |         playbackSeekBar.setEnabled(true); | ||||||
|         // Bug on lower api, disabling and enabling the seekBar resets the thumb color -.-, |         playbackSeekBar.getThumb() | ||||||
|         // so sets the color again |                 .setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN)); | ||||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { |  | ||||||
|             playbackSeekBar.getThumb().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         loadingPanel.setVisibility(View.GONE); |         loadingPanel.setVisibility(View.GONE); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ import android.graphics.Point; | |||||||
| import android.net.Uri; | import android.net.Uri; | ||||||
| import android.os.Build; | import android.os.Build; | ||||||
| import android.os.Handler; | import android.os.Handler; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.provider.Settings; | import android.provider.Settings; | ||||||
| import android.util.DisplayMetrics; | import android.util.DisplayMetrics; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| @@ -1489,9 +1489,10 @@ public class VideoPlayerImpl extends VideoPlayer | |||||||
|         // It doesn't include NavigationBar, notches, etc. |         // It doesn't include NavigationBar, notches, etc. | ||||||
|         display.getSize(size); |         display.getSize(size); | ||||||
|  |  | ||||||
|  |         final boolean isLandscape = service.isLandscape(); | ||||||
|         final int width = isFullscreen |         final int width = isFullscreen | ||||||
|                 ? (service.isLandscape() |                 ? (isLandscape ? size.x : size.y) | ||||||
|                 ? size.x : size.y) : ViewGroup.LayoutParams.MATCH_PARENT; |                 : ViewGroup.LayoutParams.MATCH_PARENT; | ||||||
|         final int gravity = isFullscreen |         final int gravity = isFullscreen | ||||||
|                 ? (display.getRotation() == Surface.ROTATION_90 |                 ? (display.getRotation() == Surface.ROTATION_90 | ||||||
|                 ? Gravity.START : Gravity.END) |                 ? Gravity.START : Gravity.END) | ||||||
| @@ -1522,14 +1523,16 @@ public class VideoPlayerImpl extends VideoPlayer | |||||||
|         // And the situations when we need to set custom height is |         // And the situations when we need to set custom height is | ||||||
|         // in fullscreen mode in tablet in non-multiWindow mode or with vertical video. |         // in fullscreen mode in tablet in non-multiWindow mode or with vertical video. | ||||||
|         // Other than that MATCH_PARENT is good |         // Other than that MATCH_PARENT is good | ||||||
|         final boolean navBarAtTheBottom = DeviceUtils.isTablet(service) || !service.isLandscape(); |         final boolean navBarAtTheBottom = DeviceUtils.isTablet(service) || !isLandscape; | ||||||
|         controlsRoot.getLayoutParams().height = isFullscreen && !isInMultiWindow() |         controlsRoot.getLayoutParams().height = isFullscreen && !isInMultiWindow() | ||||||
|                 && navBarAtTheBottom ? size.y : ViewGroup.LayoutParams.MATCH_PARENT; |                 && navBarAtTheBottom ? size.y : ViewGroup.LayoutParams.MATCH_PARENT; | ||||||
|         controlsRoot.requestLayout(); |         controlsRoot.requestLayout(); | ||||||
|  |  | ||||||
|         final int topPadding = isFullscreen && !isInMultiWindow() ? getStatusBarHeight() : 0; |         final DisplayMetrics metrics = getRootView().getResources().getDisplayMetrics(); | ||||||
|         getRootView().findViewById(R.id.playbackWindowRoot).setPadding(0, topPadding, 0, 0); |         int topPadding = isFullscreen && !isInMultiWindow() ? getStatusBarHeight() : 0; | ||||||
|         getRootView().findViewById(R.id.playbackWindowRoot).requestLayout(); |         topPadding = !isLandscape && DeviceUtils.hasCutout(topPadding, metrics) ? 0 : topPadding; | ||||||
|  |         getRootView().findViewById(R.id.playbackWindowRoot).setTranslationY(topPadding); | ||||||
|  |         getBottomControlsRoot().setTranslationY(-topPadding); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -1538,8 +1541,12 @@ public class VideoPlayerImpl extends VideoPlayer | |||||||
|      */ |      */ | ||||||
|     private int getStatusBarHeight() { |     private int getStatusBarHeight() { | ||||||
|         int statusBarHeight = 0; |         int statusBarHeight = 0; | ||||||
|         final int resourceId = service.getResources().getIdentifier( |         final int resourceId = service.isLandscape() | ||||||
|                 "status_bar_height_landscape", "dimen", "android"); |                 ? service.getResources().getIdentifier( | ||||||
|  |                 "status_bar_height_landscape", "dimen", "android") | ||||||
|  |                 : service.getResources().getIdentifier( | ||||||
|  |                 "status_bar_height", "dimen", "android"); | ||||||
|  |  | ||||||
|         if (resourceId > 0) { |         if (resourceId > 0) { | ||||||
|             statusBarHeight = service.getResources().getDimensionPixelSize(resourceId); |             statusBarHeight = service.getResources().getDimensionPixelSize(resourceId); | ||||||
|         } |         } | ||||||
| @@ -1915,7 +1922,7 @@ public class VideoPlayerImpl extends VideoPlayer | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private int popupLayoutParamType() { |     private int popupLayoutParamType() { | ||||||
|         return Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O |         return Build.VERSION.SDK_INT < Build.VERSION_CODES.O | ||||||
|                 ? WindowManager.LayoutParams.TYPE_PHONE |                 ? WindowManager.LayoutParams.TYPE_PHONE | ||||||
|                 : WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; |                 : WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; | ||||||
|     } |     } | ||||||
| @@ -2071,7 +2078,7 @@ public class VideoPlayerImpl extends VideoPlayer | |||||||
|      * This will be called when a user goes to another app/activity, turns off a screen. |      * This will be called when a user goes to another app/activity, turns off a screen. | ||||||
|      * We don't want to interrupt playback and don't want to see notification so |      * We don't want to interrupt playback and don't want to see notification so | ||||||
|      * next lines of code will enable audio-only playback only if needed |      * next lines of code will enable audio-only playback only if needed | ||||||
|      * */ |      */ | ||||||
|     private void onFragmentStopped() { |     private void onFragmentStopped() { | ||||||
|         if (videoPlayerSelected() && (isPlaying() || isLoading())) { |         if (videoPlayerSelected() && (isPlaying() || isLoading())) { | ||||||
|             if (backgroundPlaybackEnabled()) { |             if (backgroundPlaybackEnabled()) { | ||||||
|   | |||||||
| @@ -202,7 +202,8 @@ public class PlayerGestureListener | |||||||
|  |  | ||||||
|     private boolean onScrollInMain(final MotionEvent initialEvent, final MotionEvent movingEvent, |     private boolean onScrollInMain(final MotionEvent initialEvent, final MotionEvent movingEvent, | ||||||
|                                    final float distanceX, final float distanceY) { |                                    final float distanceX, final float distanceY) { | ||||||
|         if (!isVolumeGestureEnabled && !isBrightnessGestureEnabled) { |         if ((!isVolumeGestureEnabled && !isBrightnessGestureEnabled) | ||||||
|  |                 || !playerImpl.isFullscreen()) { | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ package org.schabi.newpipe.player.helper; | |||||||
| import android.app.Dialog; | import android.app.Dialog; | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| import android.view.View; | import android.view.View; | ||||||
| import android.widget.CheckBox; | import android.widget.CheckBox; | ||||||
| @@ -239,12 +239,13 @@ public class PlaybackParameterDialog extends DialogFragment { | |||||||
|         unhookingCheckbox = rootView.findViewById(R.id.unhookCheckbox); |         unhookingCheckbox = rootView.findViewById(R.id.unhookCheckbox); | ||||||
|         if (unhookingCheckbox != null) { |         if (unhookingCheckbox != null) { | ||||||
|             // restore whether pitch and tempo are unhooked or not |             // restore whether pitch and tempo are unhooked or not | ||||||
|             unhookingCheckbox.setChecked(PreferenceManager.getDefaultSharedPreferences(getContext()) |             unhookingCheckbox.setChecked(PreferenceManager | ||||||
|  |                     .getDefaultSharedPreferences(requireContext()) | ||||||
|                     .getBoolean(getString(R.string.playback_unhook_key), true)); |                     .getBoolean(getString(R.string.playback_unhook_key), true)); | ||||||
|  |  | ||||||
|             unhookingCheckbox.setOnCheckedChangeListener((compoundButton, isChecked) -> { |             unhookingCheckbox.setOnCheckedChangeListener((compoundButton, isChecked) -> { | ||||||
|                 // save whether pitch and tempo are unhooked or not |                 // save whether pitch and tempo are unhooked or not | ||||||
|                 PreferenceManager.getDefaultSharedPreferences(getContext()) |                 PreferenceManager.getDefaultSharedPreferences(requireContext()) | ||||||
|                         .edit() |                         .edit() | ||||||
|                         .putBoolean(getString(R.string.playback_unhook_key), isChecked) |                         .putBoolean(getString(R.string.playback_unhook_key), isChecked) | ||||||
|                         .apply(); |                         .apply(); | ||||||
|   | |||||||
| @@ -2,8 +2,7 @@ package org.schabi.newpipe.player.helper; | |||||||
|  |  | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.os.Build; | import androidx.preference.PreferenceManager; | ||||||
| import android.preference.PreferenceManager; |  | ||||||
| import android.provider.Settings; | import android.provider.Settings; | ||||||
| import android.view.accessibility.CaptioningManager; | import android.view.accessibility.CaptioningManager; | ||||||
|  |  | ||||||
| @@ -303,10 +302,6 @@ public final class PlayerHelper { | |||||||
|  |  | ||||||
|     @NonNull |     @NonNull | ||||||
|     public static CaptionStyleCompat getCaptionStyle(@NonNull final Context context) { |     public static CaptionStyleCompat getCaptionStyle(@NonNull final Context context) { | ||||||
|         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { |  | ||||||
|             return CaptionStyleCompat.DEFAULT; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         final CaptioningManager captioningManager = (CaptioningManager) |         final CaptioningManager captioningManager = (CaptioningManager) | ||||||
|                 context.getSystemService(Context.CAPTIONING_SERVICE); |                 context.getSystemService(Context.CAPTIONING_SERVICE); | ||||||
|         if (captioningManager == null || !captioningManager.isEnabled()) { |         if (captioningManager == null || !captioningManager.isEnabled()) { | ||||||
| @@ -331,10 +326,6 @@ public final class PlayerHelper { | |||||||
|      * @return caption scaling |      * @return caption scaling | ||||||
|      */ |      */ | ||||||
|     public static float getCaptionScale(@NonNull final Context context) { |     public static float getCaptionScale(@NonNull final Context context) { | ||||||
|         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { |  | ||||||
|             return 1f; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         final CaptioningManager captioningManager |         final CaptioningManager captioningManager | ||||||
|                 = (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE); |                 = (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE); | ||||||
|         if (captioningManager == null || !captioningManager.isEnabled()) { |         if (captioningManager == null || !captioningManager.isEnabled()) { | ||||||
|   | |||||||
| @@ -115,7 +115,7 @@ public class VideoPlaybackResolver implements PlaybackResolver { | |||||||
|             return mediaSources.get(0); |             return mediaSources.get(0); | ||||||
|         } else { |         } else { | ||||||
|             return new MergingMediaSource(mediaSources.toArray( |             return new MergingMediaSource(mediaSources.toArray( | ||||||
|                     new MediaSource[mediaSources.size()])); |                     new MediaSource[0])); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -216,18 +216,16 @@ public class ErrorActivity extends AppCompatActivity { | |||||||
|         addGuruMeditation(); |         addGuruMeditation(); | ||||||
|         currentTimeStamp = getCurrentTimeStamp(); |         currentTimeStamp = getCurrentTimeStamp(); | ||||||
|  |  | ||||||
|         reportEmailButton.setOnClickListener((View v) -> { |         reportEmailButton.setOnClickListener((View v) -> | ||||||
|             openPrivacyPolicyDialog(this, "EMAIL"); |                 openPrivacyPolicyDialog(this, "EMAIL")); | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         copyButton.setOnClickListener((View v) -> { |         copyButton.setOnClickListener((View v) -> { | ||||||
|             ShareUtils.copyToClipboard(this, buildMarkdown()); |             ShareUtils.copyToClipboard(this, buildMarkdown()); | ||||||
|             Toast.makeText(this, R.string.msg_copied, Toast.LENGTH_SHORT).show(); |             Toast.makeText(this, R.string.msg_copied, Toast.LENGTH_SHORT).show(); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         reportGithubButton.setOnClickListener((View v) -> { |         reportGithubButton.setOnClickListener((View v) -> | ||||||
|             openPrivacyPolicyDialog(this, "GITHUB"); |                 openPrivacyPolicyDialog(this, "GITHUB")); | ||||||
|         }); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|         // normal bugreport |         // normal bugreport | ||||||
| @@ -278,10 +276,9 @@ public class ErrorActivity extends AppCompatActivity { | |||||||
|                 .setTitle(R.string.privacy_policy_title) |                 .setTitle(R.string.privacy_policy_title) | ||||||
|                 .setMessage(R.string.start_accept_privacy_policy) |                 .setMessage(R.string.start_accept_privacy_policy) | ||||||
|                 .setCancelable(false) |                 .setCancelable(false) | ||||||
|                 .setNeutralButton(R.string.read_privacy_policy, (dialog, which) -> { |                 .setNeutralButton(R.string.read_privacy_policy, (dialog, which) -> | ||||||
|                         ShareUtils.openUrlInBrowser(context, |                         ShareUtils.openUrlInBrowser(context, | ||||||
|                             context.getString(R.string.privacy_policy_url)); |                                 context.getString(R.string.privacy_policy_url))) | ||||||
|                 }) |  | ||||||
|                 .setPositiveButton(R.string.accept, (dialog, which) -> { |                 .setPositiveButton(R.string.accept, (dialog, which) -> { | ||||||
|                     if (action.equals("EMAIL")) { // send on email |                     if (action.equals("EMAIL")) { // send on email | ||||||
|                         final Intent i = new Intent(Intent.ACTION_SENDTO) |                         final Intent i = new Intent(Intent.ACTION_SENDTO) | ||||||
| @@ -469,7 +466,8 @@ public class ErrorActivity extends AppCompatActivity { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private String getOsString() { |     private String getOsString() { | ||||||
|         final String osBase = Build.VERSION.SDK_INT >= 23 ? Build.VERSION.BASE_OS : "Android"; |         final String osBase = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M | ||||||
|  |                 ? Build.VERSION.BASE_OS : "Android"; | ||||||
|         return System.getProperty("os.name") |         return System.getProperty("os.name") | ||||||
|                 + " " + (osBase.isEmpty() ? "Android" : osBase) |                 + " " + (osBase.isEmpty() ? "Android" : osBase) | ||||||
|                 + " " + Build.VERSION.RELEASE |                 + " " + Build.VERSION.RELEASE | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ package org.schabi.newpipe.settings; | |||||||
|  |  | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.view.View; | import android.view.View; | ||||||
|  |  | ||||||
| import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||||
| @@ -20,7 +20,7 @@ public abstract class BasePreferenceFragment extends PreferenceFragmentCompat { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void onCreate(@Nullable final Bundle savedInstanceState) { |     public void onCreate(@Nullable final Bundle savedInstanceState) { | ||||||
|         defaultPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); |         defaultPreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity()); | ||||||
|         super.onCreate(savedInstanceState); |         super.onCreate(savedInstanceState); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ import android.content.DialogInterface; | |||||||
| import android.content.Intent; | import android.content.Intent; | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| import android.widget.Toast; | import android.widget.Toast; | ||||||
|  |  | ||||||
| @@ -74,7 +74,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment { | |||||||
|         initialSelectedContentCountry = org.schabi.newpipe.util.Localization |         initialSelectedContentCountry = org.schabi.newpipe.util.Localization | ||||||
|                 .getPreferredContentCountry(requireContext()); |                 .getPreferredContentCountry(requireContext()); | ||||||
|         initialLanguage = PreferenceManager |         initialLanguage = PreferenceManager | ||||||
|                 .getDefaultSharedPreferences(getContext()).getString("app_language_key", "en"); |                 .getDefaultSharedPreferences(requireContext()).getString("app_language_key", "en"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @@ -148,7 +148,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment { | |||||||
|         final ContentCountry selectedContentCountry = org.schabi.newpipe.util.Localization |         final ContentCountry selectedContentCountry = org.schabi.newpipe.util.Localization | ||||||
|                 .getPreferredContentCountry(requireContext()); |                 .getPreferredContentCountry(requireContext()); | ||||||
|         final String selectedLanguage = PreferenceManager |         final String selectedLanguage = PreferenceManager | ||||||
|                 .getDefaultSharedPreferences(getContext()).getString("app_language_key", "en"); |                 .getDefaultSharedPreferences(requireContext()).getString("app_language_key", "en"); | ||||||
|  |  | ||||||
|         if (!selectedLocalization.equals(initialSelectedLocalization) |         if (!selectedLocalization.equals(initialSelectedLocalization) | ||||||
|                 || !selectedContentCountry.equals(initialSelectedContentCountry) |                 || !selectedContentCountry.equals(initialSelectedContentCountry) | ||||||
| @@ -217,7 +217,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment { | |||||||
|         try { |         try { | ||||||
|             output = new ObjectOutputStream(new FileOutputStream(dst)); |             output = new ObjectOutputStream(new FileOutputStream(dst)); | ||||||
|             final SharedPreferences pref |             final SharedPreferences pref | ||||||
|                     = PreferenceManager.getDefaultSharedPreferences(getContext()); |                     = PreferenceManager.getDefaultSharedPreferences(requireContext()); | ||||||
|             output.writeObject(pref.getAll()); |             output.writeObject(pref.getAll()); | ||||||
|  |  | ||||||
|         } catch (final IOException e) { |         } catch (final IOException e) { | ||||||
| @@ -299,7 +299,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment { | |||||||
|         try { |         try { | ||||||
|             input = new ObjectInputStream(new FileInputStream(src)); |             input = new ObjectInputStream(new FileInputStream(src)); | ||||||
|             final SharedPreferences.Editor prefEdit = PreferenceManager |             final SharedPreferences.Editor prefEdit = PreferenceManager | ||||||
|                     .getDefaultSharedPreferences(getContext()).edit(); |                     .getDefaultSharedPreferences(requireContext()).edit(); | ||||||
|             prefEdit.clear(); |             prefEdit.clear(); | ||||||
|             final Map<String, ?> entries = (Map<String, ?>) input.readObject(); |             final Map<String, ?> entries = (Map<String, ?>) input.readObject(); | ||||||
|             for (final Map.Entry<String, ?> entry : entries.entrySet()) { |             for (final Map.Entry<String, ?> entry : entries.entrySet()) { | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ import android.annotation.SuppressLint; | |||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.text.InputType; | import android.text.InputType; | ||||||
| import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||||
| import android.view.Menu; | import android.view.Menu; | ||||||
| @@ -203,9 +203,8 @@ public class PeertubeInstanceListFragment extends Fragment { | |||||||
|  |  | ||||||
|     private void initButton(final View rootView) { |     private void initButton(final View rootView) { | ||||||
|         final FloatingActionButton fab = rootView.findViewById(R.id.addInstanceButton); |         final FloatingActionButton fab = rootView.findViewById(R.id.addInstanceButton); | ||||||
|         fab.setOnClickListener(v -> { |         fab.setOnClickListener(v -> | ||||||
|             showAddItemDialog(requireContext()); |                 showAddItemDialog(requireContext())); | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void showAddItemDialog(final Context c) { |     private void showAddItemDialog(final Context c) { | ||||||
|   | |||||||
| @@ -208,12 +208,7 @@ public class SelectChannelFragment extends DialogFragment { | |||||||
|         public void onBindViewHolder(final SelectChannelItemHolder holder, final int position) { |         public void onBindViewHolder(final SelectChannelItemHolder holder, final int position) { | ||||||
|             final SubscriptionEntity entry = subscriptions.get(position); |             final SubscriptionEntity entry = subscriptions.get(position); | ||||||
|             holder.titleView.setText(entry.getName()); |             holder.titleView.setText(entry.getName()); | ||||||
|             holder.view.setOnClickListener(new View.OnClickListener() { |             holder.view.setOnClickListener(view -> clickedItem(position)); | ||||||
|                 @Override |  | ||||||
|                 public void onClick(final View view) { |  | ||||||
|                     clickedItem(position); |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|             imageLoader.displayImage(entry.getAvatarUrl(), holder.thumbnailView, |             imageLoader.displayImage(entry.getAvatarUrl(), holder.thumbnailView, | ||||||
|                     DISPLAY_IMAGE_OPTIONS); |                     DISPLAY_IMAGE_OPTIONS); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -87,7 +87,7 @@ public class VideoAudioSettingsFragment extends BasePreferenceFragment { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         final ListPreference durations = (ListPreference) findPreference( |         final ListPreference durations = findPreference( | ||||||
|                 getString(R.string.seek_duration_key)); |                 getString(R.string.seek_duration_key)); | ||||||
|         durations.setEntryValues(displayedDurationValues.toArray(new CharSequence[0])); |         durations.setEntryValues(displayedDurationValues.toArray(new CharSequence[0])); | ||||||
|         durations.setEntries(displayedDescriptionValues.toArray(new CharSequence[0])); |         durations.setEntries(displayedDescriptionValues.toArray(new CharSequence[0])); | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ package org.schabi.newpipe.settings.tabs; | |||||||
|  |  | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.widget.Toast; | import android.widget.Toast; | ||||||
|  |  | ||||||
| import org.schabi.newpipe.R; | import org.schabi.newpipe.R; | ||||||
|   | |||||||
| @@ -236,7 +236,7 @@ public class DataReader { | |||||||
|  |  | ||||||
|         if (read != amount) { |         if (read != amount) { | ||||||
|             throw new EOFException("Truncated stream, missing " |             throw new EOFException("Truncated stream, missing " | ||||||
|                     + String.valueOf(amount - read) + " bytes"); |                     + (amount - read) + " bytes"); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         for (int i = 0; i < amount; i++) { |         for (int i = 0; i < amount; i++) { | ||||||
|   | |||||||
| @@ -5,8 +5,8 @@ import org.schabi.newpipe.streams.io.SharpStream; | |||||||
| import java.io.EOFException; | import java.io.EOFException; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| import java.io.UnsupportedEncodingException; |  | ||||||
| import java.nio.ByteBuffer; | import java.nio.ByteBuffer; | ||||||
|  | import java.nio.charset.StandardCharsets; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.NoSuchElementException; | import java.util.NoSuchElementException; | ||||||
|  |  | ||||||
| @@ -259,11 +259,7 @@ public class Mp4DashReader { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private String boxName(final int type) { |     private String boxName(final int type) { | ||||||
|         try { |         return new String(ByteBuffer.allocate(4).putInt(type).array(), StandardCharsets.UTF_8); | ||||||
|             return new String(ByteBuffer.allocate(4).putInt(type).array(), "UTF-8"); |  | ||||||
|         } catch (final UnsupportedEncodingException e) { |  | ||||||
|             return "0x" + Integer.toHexString(type); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private Box readBox() throws IOException { |     private Box readBox() throws IOException { | ||||||
|   | |||||||
| @@ -293,7 +293,7 @@ public class WebMReader { | |||||||
|         if (metadataExpected && (obj.info == null || obj.tracks == null)) { |         if (metadataExpected && (obj.info == null || obj.tracks == null)) { | ||||||
|             throw new RuntimeException( |             throw new RuntimeException( | ||||||
|                     "Cluster element found without Info and/or Tracks element at position " |                     "Cluster element found without Info and/or Tracks element at position " | ||||||
|                             + String.valueOf(ref.offset)); |                             + ref.offset); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return obj; |         return obj; | ||||||
| @@ -389,7 +389,7 @@ public class WebMReader { | |||||||
|  |  | ||||||
|         final Element elem = untilElement(ref, ID_TIMECODE); |         final Element elem = untilElement(ref, ID_TIMECODE); | ||||||
|         if (elem == null) { |         if (elem == null) { | ||||||
|             throw new NoSuchElementException("Cluster at " + String.valueOf(ref.offset) |             throw new NoSuchElementException("Cluster at " + ref.offset | ||||||
|                     + " without Timecode element"); |                     + " without Timecode element"); | ||||||
|         } |         } | ||||||
|         obj.timecode = readNumber(elem); |         obj.timecode = readNumber(elem); | ||||||
| @@ -520,7 +520,7 @@ public class WebMReader { | |||||||
|  |  | ||||||
|                 currentSimpleBlock = readSimpleBlock(elem); |                 currentSimpleBlock = readSimpleBlock(elem); | ||||||
|                 if (currentSimpleBlock.trackNumber == tracks[selectedTrack].trackNumber) { |                 if (currentSimpleBlock.trackNumber == tracks[selectedTrack].trackNumber) { | ||||||
|                     currentSimpleBlock.data = stream.getView((int) currentSimpleBlock.dataSize); |                     currentSimpleBlock.data = stream.getView(currentSimpleBlock.dataSize); | ||||||
|  |  | ||||||
|                     // calculate the timestamp in nanoseconds |                     // calculate the timestamp in nanoseconds | ||||||
|                     currentSimpleBlock.absoluteTimeCodeNs = currentSimpleBlock.relativeTimeCode |                     currentSimpleBlock.absoluteTimeCodeNs = currentSimpleBlock.relativeTimeCode | ||||||
|   | |||||||
| @@ -162,13 +162,9 @@ public final class AnimationUtils { | |||||||
|                 .ofObject(new ArgbEvaluator(), colorStart, colorEnd); |                 .ofObject(new ArgbEvaluator(), colorStart, colorEnd); | ||||||
|         viewPropertyAnimator.setInterpolator(new FastOutSlowInInterpolator()); |         viewPropertyAnimator.setInterpolator(new FastOutSlowInInterpolator()); | ||||||
|         viewPropertyAnimator.setDuration(duration); |         viewPropertyAnimator.setDuration(duration); | ||||||
|         viewPropertyAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |         viewPropertyAnimator.addUpdateListener(animation -> | ||||||
|             @Override |  | ||||||
|             public void onAnimationUpdate(final ValueAnimator animation) { |  | ||||||
|                 ViewCompat.setBackgroundTintList(view, |                 ViewCompat.setBackgroundTintList(view, | ||||||
|                         new ColorStateList(empty, new int[]{(int) animation.getAnimatedValue()})); |                         new ColorStateList(empty, new int[]{(int) animation.getAnimatedValue()}))); | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|         viewPropertyAnimator.addListener(new AnimatorListenerAdapter() { |         viewPropertyAnimator.addListener(new AnimatorListenerAdapter() { | ||||||
|             @Override |             @Override | ||||||
|             public void onAnimationEnd(final Animator animation) { |             public void onAnimationEnd(final Animator animation) { | ||||||
| @@ -205,12 +201,8 @@ public final class AnimationUtils { | |||||||
|                 .ofObject(new ArgbEvaluator(), colorStart, colorEnd); |                 .ofObject(new ArgbEvaluator(), colorStart, colorEnd); | ||||||
|         viewPropertyAnimator.setInterpolator(new FastOutSlowInInterpolator()); |         viewPropertyAnimator.setInterpolator(new FastOutSlowInInterpolator()); | ||||||
|         viewPropertyAnimator.setDuration(duration); |         viewPropertyAnimator.setDuration(duration); | ||||||
|         viewPropertyAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |         viewPropertyAnimator.addUpdateListener(animation -> | ||||||
|             @Override |                 view.setTextColor((int) animation.getAnimatedValue())); | ||||||
|             public void onAnimationUpdate(final ValueAnimator animation) { |  | ||||||
|                 view.setTextColor((int) animation.getAnimatedValue()); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|         viewPropertyAnimator.addListener(new AnimatorListenerAdapter() { |         viewPropertyAnimator.addListener(new AnimatorListenerAdapter() { | ||||||
|             @Override |             @Override | ||||||
|             public void onAnimationEnd(final Animator animation) { |             public void onAnimationEnd(final Animator animation) { | ||||||
| @@ -430,7 +422,7 @@ public final class AnimationUtils { | |||||||
|                                                   final long duration, final long delay, |                                                   final long duration, final long delay, | ||||||
|                                                   final Runnable execOnEnd) { |                                                   final Runnable execOnEnd) { | ||||||
|         if (enterOrExit) { |         if (enterOrExit) { | ||||||
|             view.setTranslationY(-view.getHeight() / 2); |             view.setTranslationY(-view.getHeight() / 2.0f); | ||||||
|             view.setAlpha(0f); |             view.setAlpha(0f); | ||||||
|             view.animate() |             view.animate() | ||||||
|                     .setInterpolator(new FastOutSlowInInterpolator()).alpha(1f).translationY(0) |                     .setInterpolator(new FastOutSlowInInterpolator()).alpha(1f).translationY(0) | ||||||
| @@ -445,7 +437,7 @@ public final class AnimationUtils { | |||||||
|             }).start(); |             }).start(); | ||||||
|         } else { |         } else { | ||||||
|             view.animate().setInterpolator(new FastOutSlowInInterpolator()) |             view.animate().setInterpolator(new FastOutSlowInInterpolator()) | ||||||
|                     .alpha(0f).translationY(-view.getHeight() / 2) |                     .alpha(0f).translationY(-view.getHeight() / 2.0f) | ||||||
|                     .setDuration(duration).setStartDelay(delay) |                     .setDuration(duration).setStartDelay(delay) | ||||||
|                     .setListener(new AnimatorListenerAdapter() { |                     .setListener(new AnimatorListenerAdapter() { | ||||||
|                 @Override |                 @Override | ||||||
|   | |||||||
| @@ -6,6 +6,8 @@ import android.content.pm.PackageManager; | |||||||
| import android.content.res.Configuration; | import android.content.res.Configuration; | ||||||
| import android.os.BatteryManager; | import android.os.BatteryManager; | ||||||
| import android.os.Build; | import android.os.Build; | ||||||
|  | import android.util.DisplayMetrics; | ||||||
|  | import android.util.TypedValue; | ||||||
| import android.view.KeyEvent; | import android.view.KeyEvent; | ||||||
|  |  | ||||||
| import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||||
| @@ -72,4 +74,17 @@ public final class DeviceUtils { | |||||||
|                 return false; |                 return false; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Compares current status bar height with default status bar height in Android and decides, | ||||||
|  |      * does the device has cutout or not | ||||||
|  |      * */ | ||||||
|  |     public static boolean hasCutout(final float statusBarHeight, final DisplayMetrics metrics) { | ||||||
|  |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { | ||||||
|  |             final float defaultStatusBarHeight = TypedValue.applyDimension( | ||||||
|  |                     TypedValue.COMPLEX_UNIT_DIP, 25, metrics); | ||||||
|  |             return statusBarHeight > defaultStatusBarHeight; | ||||||
|  |         } | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ package org.schabi.newpipe.util; | |||||||
|  |  | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
|  |  | ||||||
| import org.schabi.newpipe.R; | import org.schabi.newpipe.R; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ package org.schabi.newpipe.util; | |||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.net.ConnectivityManager; | import android.net.ConnectivityManager; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
|  |  | ||||||
| import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||||
| import androidx.annotation.StringRes; | import androidx.annotation.StringRes; | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ import android.content.Context; | |||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.content.res.Configuration; | import android.content.res.Configuration; | ||||||
| import android.content.res.Resources; | import android.content.res.Resources; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.text.TextUtils; | import android.text.TextUtils; | ||||||
| import android.util.DisplayMetrics; | import android.util.DisplayMetrics; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ import android.content.Context; | |||||||
| import android.content.Intent; | import android.content.Intent; | ||||||
| import android.net.Uri; | import android.net.Uri; | ||||||
| import android.os.Build; | import android.os.Build; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| import android.widget.Toast; | import android.widget.Toast; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ package org.schabi.newpipe.util; | |||||||
|  |  | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
|  |  | ||||||
| import com.grack.nanojson.JsonArray; | import com.grack.nanojson.JsonArray; | ||||||
| import com.grack.nanojson.JsonObject; | import com.grack.nanojson.JsonObject; | ||||||
|   | |||||||
| @@ -26,11 +26,9 @@ public final class PermissionHelper { | |||||||
|     private PermissionHelper() { } |     private PermissionHelper() { } | ||||||
|  |  | ||||||
|     public static boolean checkStoragePermissions(final Activity activity, final int requestCode) { |     public static boolean checkStoragePermissions(final Activity activity, final int requestCode) { | ||||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { |  | ||||||
|         if (!checkReadStoragePermissions(activity, requestCode)) { |         if (!checkReadStoragePermissions(activity, requestCode)) { | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         } |  | ||||||
|         return checkWriteStoragePermissions(activity, requestCode); |         return checkWriteStoragePermissions(activity, requestCode); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -20,8 +20,7 @@ public class RelatedStreamInfo extends ListInfo<InfoItem> { | |||||||
|                 info.getOriginalUrl(), info.getUrl(), info.getId(), Collections.emptyList(), null); |                 info.getOriginalUrl(), info.getUrl(), info.getId(), Collections.emptyList(), null); | ||||||
|         final RelatedStreamInfo relatedStreamInfo = new RelatedStreamInfo( |         final RelatedStreamInfo relatedStreamInfo = new RelatedStreamInfo( | ||||||
|                 info.getServiceId(), handler, info.getName()); |                 info.getServiceId(), handler, info.getName()); | ||||||
|         final List<InfoItem> streams = new ArrayList<>(); |         final List<InfoItem> streams = new ArrayList<>(info.getRelatedStreams()); | ||||||
|         streams.addAll(info.getRelatedStreams()); |  | ||||||
|         relatedStreamInfo.setRelatedItems(streams); |         relatedStreamInfo.setRelatedItems(streams); | ||||||
|         return relatedStreamInfo; |         return relatedStreamInfo; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ package org.schabi.newpipe.util; | |||||||
|  |  | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
|  |  | ||||||
| import androidx.annotation.DrawableRes; | import androidx.annotation.DrawableRes; | ||||||
| import androidx.annotation.StringRes; | import androidx.annotation.StringRes; | ||||||
|   | |||||||
| @@ -36,7 +36,6 @@ import org.schabi.newpipe.MainActivity; | |||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.FileInputStream; | import java.io.FileInputStream; | ||||||
| import java.io.FileOutputStream; | import java.io.FileOutputStream; | ||||||
| import java.io.FilenameFilter; |  | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.io.ObjectInputStream; | import java.io.ObjectInputStream; | ||||||
| import java.io.ObjectOutputStream; | import java.io.ObjectOutputStream; | ||||||
| @@ -254,12 +253,8 @@ public final class StateSaver { | |||||||
|                 return new SavedState(prefixFileName, file.getAbsolutePath()); |                 return new SavedState(prefixFileName, file.getAbsolutePath()); | ||||||
|             } else { |             } else { | ||||||
|                 // Delete any file that contains the prefix |                 // Delete any file that contains the prefix | ||||||
|                 final File[] files = cacheDir.listFiles(new FilenameFilter() { |                 final File[] files = cacheDir.listFiles((dir, name) -> | ||||||
|                     @Override |                         name.contains(prefixFileName)); | ||||||
|                     public boolean accept(final File dir, final String name) { |  | ||||||
|                         return name.contains(prefixFileName); |  | ||||||
|                     } |  | ||||||
|                 }); |  | ||||||
|                 for (final File fileToDelete : files) { |                 for (final File fileToDelete : files) { | ||||||
|                     fileToDelete.delete(); |                     fileToDelete.delete(); | ||||||
|                 } |                 } | ||||||
|   | |||||||
| @@ -106,7 +106,7 @@ public class TLSSocketFactoryCompat extends SSLSocketFactory { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private Socket enableTLSOnSocket(final Socket socket) { |     private Socket enableTLSOnSocket(final Socket socket) { | ||||||
|         if (socket != null && (socket instanceof SSLSocket)) { |         if (socket instanceof SSLSocket) { | ||||||
|             ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.1", "TLSv1.2"}); |             ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.1", "TLSv1.2"}); | ||||||
|         } |         } | ||||||
|         return socket; |         return socket; | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ package org.schabi.newpipe.util; | |||||||
| import android.app.Activity; | import android.app.Activity; | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.res.TypedArray; | import android.content.res.TypedArray; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.util.TypedValue; | import android.util.TypedValue; | ||||||
| import android.view.ContextThemeWrapper; | import android.view.ContextThemeWrapper; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -259,7 +259,7 @@ public final class FocusOverlayView extends Drawable implements | |||||||
|         // keyboard META key for moving between clusters). We have to fix this unfortunate accident |         // keyboard META key for moving between clusters). We have to fix this unfortunate accident | ||||||
|         // While we are at it, let's deal with touchscreenBlocksFocus too. |         // While we are at it, let's deal with touchscreenBlocksFocus too. | ||||||
|  |  | ||||||
|         if (Build.VERSION.SDK_INT < 26) { |         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -155,13 +155,13 @@ public class LargeTextMovementMethod extends LinkMovementMethod { | |||||||
|             int bestStart = -1; |             int bestStart = -1; | ||||||
|             int bestEnd = -1; |             int bestEnd = -1; | ||||||
|  |  | ||||||
|             for (int i = 0; i < candidates.length; i++) { |             for (final ClickableSpan candidate : candidates) { | ||||||
|                 final int start = buffer.getSpanStart(candidates[i]); |                 final int start = buffer.getSpanStart(candidate); | ||||||
|                 final int end = buffer.getSpanEnd(candidates[i]); |                 final int end = buffer.getSpanEnd(candidate); | ||||||
|  |  | ||||||
|                 if ((end < selEnd || selStart == selEnd) && start >= visibleStart) { |                 if ((end < selEnd || selStart == selEnd) && start >= visibleStart) { | ||||||
|                     if (end > bestEnd) { |                     if (end > bestEnd) { | ||||||
|                         bestStart = buffer.getSpanStart(candidates[i]); |                         bestStart = buffer.getSpanStart(candidate); | ||||||
|                         bestEnd = end; |                         bestEnd = end; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @@ -224,14 +224,14 @@ public class LargeTextMovementMethod extends LinkMovementMethod { | |||||||
|             int bestStart = Integer.MAX_VALUE; |             int bestStart = Integer.MAX_VALUE; | ||||||
|             int bestEnd = Integer.MAX_VALUE; |             int bestEnd = Integer.MAX_VALUE; | ||||||
|  |  | ||||||
|             for (int i = 0; i < candidates.length; i++) { |             for (final ClickableSpan candidate : candidates) { | ||||||
|                 final int start = buffer.getSpanStart(candidates[i]); |                 final int start = buffer.getSpanStart(candidate); | ||||||
|                 final int end = buffer.getSpanEnd(candidates[i]); |                 final int end = buffer.getSpanEnd(candidate); | ||||||
|  |  | ||||||
|                 if ((start > selStart || selStart == selEnd) && end <= visibleEnd) { |                 if ((start > selStart || selStart == selEnd) && end <= visibleEnd) { | ||||||
|                     if (start < bestStart) { |                     if (start < bestStart) { | ||||||
|                         bestStart = start; |                         bestStart = start; | ||||||
|                         bestEnd = buffer.getSpanEnd(candidates[i]); |                         bestEnd = buffer.getSpanEnd(candidate); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -142,7 +142,7 @@ public class NewPipeRecyclerView extends RecyclerView { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private boolean tryFocusFinder(final int direction) { |     private boolean tryFocusFinder(final int direction) { | ||||||
|         if (Build.VERSION.SDK_INT >= 28) { |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { | ||||||
|             // Android 9 implemented bunch of handy changes to focus, that render code below less |             // Android 9 implemented bunch of handy changes to focus, that render code below less | ||||||
|             // useful, and also broke findNextFocusFromRect in way, that render this hack useless |             // useful, and also broke findNextFocusFromRect in way, that render this hack useless | ||||||
|             return false; |             return false; | ||||||
|   | |||||||
| @@ -633,7 +633,7 @@ public class DownloadMission extends Mission { | |||||||
|         calculated = offsets[current < offsets.length ? current : (offsets.length - 1)] + length; |         calculated = offsets[current < offsets.length ? current : (offsets.length - 1)] + length; | ||||||
|         calculated -= offsets[0];// don't count reserved space |         calculated -= offsets[0];// don't count reserved space | ||||||
|  |  | ||||||
|         return calculated > nearLength ? calculated : nearLength; |         return Math.max(calculated, nearLength); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -30,12 +30,12 @@ public class FileStream extends SharpStream { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public int read(byte b[]) throws IOException { |     public int read(byte[] b) throws IOException { | ||||||
|         return source.read(b); |         return source.read(b); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public int read(byte b[], int off, int len) throws IOException { |     public int read(byte[] b, int off, int len) throws IOException { | ||||||
|         return source.read(b, off, len); |         return source.read(b, off, len); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -115,7 +115,7 @@ public abstract class Postprocessing implements Serializable { | |||||||
|         mission.done = 0; |         mission.done = 0; | ||||||
|  |  | ||||||
|         long length = mission.storage.length() - mission.offsets[0]; |         long length = mission.storage.length() - mission.offsets[0]; | ||||||
|         mission.length = length > mission.nearLength ? length : mission.nearLength; |         mission.length = Math.max(length, mission.nearLength); | ||||||
|  |  | ||||||
|         final ProgressReport readProgress = (long position) -> { |         final ProgressReport readProgress = (long position) -> { | ||||||
|             position -= mission.offsets[0]; |             position -= mission.offsets[0]; | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ import android.os.Handler.Callback; | |||||||
| import android.os.IBinder; | import android.os.IBinder; | ||||||
| import android.os.Message; | import android.os.Message; | ||||||
| import android.os.Parcelable; | import android.os.Parcelable; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| import android.util.SparseArray; | import android.util.SparseArray; | ||||||
| import android.widget.Toast; | import android.widget.Toast; | ||||||
| @@ -160,7 +160,7 @@ public class DownloadManagerService extends Service { | |||||||
|         mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); |         mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); | ||||||
|         mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); |         mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); | ||||||
|  |  | ||||||
|         if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||||
|             mNetworkStateListenerL = new ConnectivityManager.NetworkCallback() { |             mNetworkStateListenerL = new ConnectivityManager.NetworkCallback() { | ||||||
|                 @Override |                 @Override | ||||||
|                 public void onAvailable(Network network) { |                 public void onAvailable(Network network) { | ||||||
| @@ -240,7 +240,7 @@ public class DownloadManagerService extends Service { | |||||||
|  |  | ||||||
|         manageLock(false); |         manageLock(false); | ||||||
|  |  | ||||||
|         if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) | ||||||
|             mConnectivityManager.unregisterNetworkCallback(mNetworkStateListenerL); |             mConnectivityManager.unregisterNetworkCallback(mNetworkStateListenerL); | ||||||
|         else |         else | ||||||
|             unregisterReceiver(mNetworkStateListener); |             unregisterReceiver(mNetworkStateListener); | ||||||
| @@ -466,7 +466,7 @@ public class DownloadManagerService extends Service { | |||||||
|         if (downloadDoneCount < 1) { |         if (downloadDoneCount < 1) { | ||||||
|             downloadDoneList.append(name); |             downloadDoneList.append(name); | ||||||
|  |  | ||||||
|             if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { |             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { | ||||||
|                 downloadDoneNotification.setContentTitle(getString(R.string.app_name)); |                 downloadDoneNotification.setContentTitle(getString(R.string.app_name)); | ||||||
|             } else { |             } else { | ||||||
|                 downloadDoneNotification.setContentTitle(null); |                 downloadDoneNotification.setContentTitle(null); | ||||||
| @@ -505,7 +505,7 @@ public class DownloadManagerService extends Service { | |||||||
|                     .setContentIntent(mOpenDownloadList); |                     .setContentIntent(mOpenDownloadList); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { |         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { | ||||||
|             downloadFailedNotification.setContentTitle(getString(R.string.app_name)); |             downloadFailedNotification.setContentTitle(getString(R.string.app_name)); | ||||||
|             downloadFailedNotification.setStyle(new NotificationCompat.BigTextStyle() |             downloadFailedNotification.setStyle(new NotificationCompat.BigTextStyle() | ||||||
|                     .bigText(getString(R.string.download_failed).concat(": ").concat(mission.storage.getName()))); |                     .bigText(getString(R.string.download_failed).concat(": ").concat(mission.storage.getName()))); | ||||||
|   | |||||||
| @@ -49,6 +49,7 @@ import java.io.File; | |||||||
| import java.lang.ref.WeakReference; | import java.lang.ref.WeakReference; | ||||||
| import java.net.URI; | import java.net.URI; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
|  | import java.util.Arrays; | ||||||
| import java.util.Iterator; | import java.util.Iterator; | ||||||
|  |  | ||||||
| import us.shandian.giga.get.DownloadMission; | import us.shandian.giga.get.DownloadMission; | ||||||
| @@ -302,9 +303,7 @@ public class MissionAdapter extends Adapter<ViewHolder> implements Handler.Callb | |||||||
|             float averageSpeed = speed; |             float averageSpeed = speed; | ||||||
|  |  | ||||||
|             if (h.lastSpeedIdx < 0) { |             if (h.lastSpeedIdx < 0) { | ||||||
|                 for (int i = 0; i < h.lastSpeed.length; i++) { |                 Arrays.fill(h.lastSpeed, speed); | ||||||
|                     h.lastSpeed[i] = speed; |  | ||||||
|                 } |  | ||||||
|                 h.lastSpeedIdx = 0; |                 h.lastSpeedIdx = 0; | ||||||
|             } else { |             } else { | ||||||
|                 for (int i = 0; i < h.lastSpeed.length; i++) { |                 for (int i = 0; i < h.lastSpeed.length; i++) { | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ import android.net.Uri; | |||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.os.Environment; | import android.os.Environment; | ||||||
| import android.os.IBinder; | import android.os.IBinder; | ||||||
| import android.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||||
| import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||||
| import android.view.Menu; | import android.view.Menu; | ||||||
| import android.view.MenuItem; | import android.view.MenuItem; | ||||||
| @@ -97,7 +97,7 @@ public class MissionsFragment extends Fragment { | |||||||
|     public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { |     public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | ||||||
|         View v = inflater.inflate(R.layout.missions, container, false); |         View v = inflater.inflate(R.layout.missions, container, false); | ||||||
|  |  | ||||||
|         mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); |         mPrefs = PreferenceManager.getDefaultSharedPreferences(requireActivity()); | ||||||
|         mLinear = mPrefs.getBoolean("linear", false); |         mLinear = mPrefs.getBoolean("linear", false); | ||||||
|  |  | ||||||
|         // Bind the service |         // Bind the service | ||||||
|   | |||||||
| @@ -212,7 +212,6 @@ | |||||||
|     <string name="playback_skip_silence_key" translatable="false">playback_skip_silence_key</string> |     <string name="playback_skip_silence_key" translatable="false">playback_skip_silence_key</string> | ||||||
|  |  | ||||||
|     <string name="app_language_key" translatable="false">app_language_key</string> |     <string name="app_language_key" translatable="false">app_language_key</string> | ||||||
|     <string name="enable_lock_screen_video_thumbnail_key" translatable="false">enable_lock_screen_video_thumbnail</string> |  | ||||||
|  |  | ||||||
|     <string name="feed_update_threshold_key" translatable="false">feed_update_threshold_key</string> |     <string name="feed_update_threshold_key" translatable="false">feed_update_threshold_key</string> | ||||||
|     <string name="feed_update_threshold_default_value" translatable="false">300</string> |     <string name="feed_update_threshold_default_value" translatable="false">300</string> | ||||||
| @@ -249,6 +248,11 @@ | |||||||
|     <string name="clear_playback_states_key" translatable="false">clear_playback_states</string> |     <string name="clear_playback_states_key" translatable="false">clear_playback_states</string> | ||||||
|     <string name="clear_search_history_key" translatable="false">clear_search_history</string> |     <string name="clear_search_history_key" translatable="false">clear_search_history</string> | ||||||
|  |  | ||||||
|  |     <string name="last_used_download_type" translatable="false">@string/last_download_type_video_key</string> | ||||||
|  |     <string name="last_download_type_video_key" translatable="false">last_dl_type_video</string> | ||||||
|  |     <string name="last_download_type_audio_key" translatable="false">last_dl_type_audio</string> | ||||||
|  |     <string name="last_download_type_subtitle_key" translatable="false">last_dl_type_subtitle</string> | ||||||
|  |  | ||||||
|     <string name="downloads_storage_ask" translatable="false">downloads_storage_ask</string> |     <string name="downloads_storage_ask" translatable="false">downloads_storage_ask</string> | ||||||
|     <string name="storage_use_saf" translatable="false">storage_use_saf</string> |     <string name="storage_use_saf" translatable="false">storage_use_saf</string> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
|         android:title="@string/theme_title" |         android:title="@string/theme_title" | ||||||
|         app:iconSpaceReserved="false" /> |         app:iconSpaceReserved="false" /> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         android:defaultValue="true" |         android:defaultValue="true" | ||||||
|         android:key="@string/show_hold_to_append_key" |         android:key="@string/show_hold_to_append_key" | ||||||
|         android:summary="@string/show_hold_to_append_summary" |         android:summary="@string/show_hold_to_append_summary" | ||||||
|   | |||||||
| @@ -45,39 +45,39 @@ | |||||||
|         android:title="@string/peertube_instance_url_title" |         android:title="@string/peertube_instance_url_title" | ||||||
|         android:summary="@string/peertube_instance_url_summary"/> |         android:summary="@string/peertube_instance_url_summary"/> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         app:iconSpaceReserved="false" |         app:iconSpaceReserved="false" | ||||||
|         android:defaultValue="false" |         android:defaultValue="false" | ||||||
|         android:key="@string/show_age_restricted_content" |         android:key="@string/show_age_restricted_content" | ||||||
|         android:title="@string/show_age_restricted_content_title"/> |         android:title="@string/show_age_restricted_content_title"/> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         app:iconSpaceReserved="false" |         app:iconSpaceReserved="false" | ||||||
|         android:defaultValue="false" |         android:defaultValue="false" | ||||||
|         android:key="@string/youtube_restricted_mode_enabled" |         android:key="@string/youtube_restricted_mode_enabled" | ||||||
|         android:title="@string/youtube_restricted_mode_enabled_title"/> |         android:title="@string/youtube_restricted_mode_enabled_title"/> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         app:iconSpaceReserved="false" |         app:iconSpaceReserved="false" | ||||||
|         android:defaultValue="true" |         android:defaultValue="true" | ||||||
|         android:key="@string/show_search_suggestions_key" |         android:key="@string/show_search_suggestions_key" | ||||||
|         android:summary="@string/show_search_suggestions_summary" |         android:summary="@string/show_search_suggestions_summary" | ||||||
|         android:title="@string/show_search_suggestions_title"/> |         android:title="@string/show_search_suggestions_title"/> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         app:iconSpaceReserved="false" |         app:iconSpaceReserved="false" | ||||||
|         android:defaultValue="true" |         android:defaultValue="true" | ||||||
|         android:key="@string/download_thumbnail_key" |         android:key="@string/download_thumbnail_key" | ||||||
|         android:title="@string/download_thumbnail_title" |         android:title="@string/download_thumbnail_title" | ||||||
|         android:summary="@string/download_thumbnail_summary"/> |         android:summary="@string/download_thumbnail_summary"/> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         app:iconSpaceReserved="false" |         app:iconSpaceReserved="false" | ||||||
|         android:defaultValue="true" |         android:defaultValue="true" | ||||||
|         android:key="@string/show_next_video_key" |         android:key="@string/show_next_video_key" | ||||||
|         android:title="@string/show_next_and_similar_title"/> |         android:title="@string/show_next_and_similar_title"/> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         app:iconSpaceReserved="false" |         app:iconSpaceReserved="false" | ||||||
|         android:defaultValue="true" |         android:defaultValue="true" | ||||||
|         android:key="@string/show_comments_key" |         android:key="@string/show_comments_key" | ||||||
| @@ -109,7 +109,7 @@ | |||||||
|             android:title="@string/feed_update_threshold_title" |             android:title="@string/feed_update_threshold_title" | ||||||
|             android:summary="@string/feed_update_threshold_summary"/> |             android:summary="@string/feed_update_threshold_summary"/> | ||||||
|  |  | ||||||
|         <SwitchPreference |         <SwitchPreferenceCompat | ||||||
|             app:iconSpaceReserved="false" |             app:iconSpaceReserved="false" | ||||||
|             android:defaultValue="false" |             android:defaultValue="false" | ||||||
|             android:key="@string/feed_use_dedicated_fetch_method_key" |             android:key="@string/feed_use_dedicated_fetch_method_key" | ||||||
|   | |||||||
| @@ -5,21 +5,21 @@ | |||||||
|     android:key="general_preferences" |     android:key="general_preferences" | ||||||
|     android:title="@string/settings_category_debug_title"> |     android:title="@string/settings_category_debug_title"> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         app:iconSpaceReserved="false" |         app:iconSpaceReserved="false" | ||||||
|         android:defaultValue="false" |         android:defaultValue="false" | ||||||
|         android:key="@string/allow_heap_dumping_key" |         android:key="@string/allow_heap_dumping_key" | ||||||
|         android:title="@string/enable_leak_canary_title" |         android:title="@string/enable_leak_canary_title" | ||||||
|         android:summary="@string/enable_leak_canary_summary"/> |         android:summary="@string/enable_leak_canary_summary"/> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         app:iconSpaceReserved="false" |         app:iconSpaceReserved="false" | ||||||
|         android:defaultValue="false" |         android:defaultValue="false" | ||||||
|         android:key="@string/allow_disposed_exceptions_key" |         android:key="@string/allow_disposed_exceptions_key" | ||||||
|         android:title="@string/enable_disposed_exceptions_title" |         android:title="@string/enable_disposed_exceptions_title" | ||||||
|         android:summary="@string/enable_disposed_exceptions_summary"/> |         android:summary="@string/enable_disposed_exceptions_summary"/> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         app:iconSpaceReserved="false" |         app:iconSpaceReserved="false" | ||||||
|         android:defaultValue="false" |         android:defaultValue="false" | ||||||
|         android:key="@string/show_original_time_ago_key" |         android:key="@string/show_original_time_ago_key" | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
|         android:summary="@string/downloads_storage_ask_summary_kitkat" |         android:summary="@string/downloads_storage_ask_summary_kitkat" | ||||||
|         android:title="@string/downloads_storage_ask_title" /> |         android:title="@string/downloads_storage_ask_title" /> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         app:iconSpaceReserved="false" |         app:iconSpaceReserved="false" | ||||||
|         android:defaultValue="false" |         android:defaultValue="false" | ||||||
|         android:key="@string/storage_use_saf" |         android:key="@string/storage_use_saf" | ||||||
| @@ -58,14 +58,14 @@ | |||||||
|         android:summary="@string/max_retry_desc" |         android:summary="@string/max_retry_desc" | ||||||
|         android:title="@string/max_retry_msg" /> |         android:title="@string/max_retry_msg" /> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         app:iconSpaceReserved="false" |         app:iconSpaceReserved="false" | ||||||
|         android:defaultValue="false" |         android:defaultValue="false" | ||||||
|         android:key="@string/downloads_cross_network" |         android:key="@string/downloads_cross_network" | ||||||
|         android:summary="@string/pause_downloads_on_mobile_desc" |         android:summary="@string/pause_downloads_on_mobile_desc" | ||||||
|         android:title="@string/pause_downloads_on_mobile" /> |         android:title="@string/pause_downloads_on_mobile" /> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         app:iconSpaceReserved="false" |         app:iconSpaceReserved="false" | ||||||
|         android:defaultValue="true" |         android:defaultValue="true" | ||||||
|         android:key="@string/downloads_queue_limit" |         android:key="@string/downloads_queue_limit" | ||||||
|   | |||||||
| @@ -4,14 +4,14 @@ | |||||||
|     android:key="general_preferences" |     android:key="general_preferences" | ||||||
|     android:title="@string/settings_category_history_title"> |     android:title="@string/settings_category_history_title"> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         android:defaultValue="true" |         android:defaultValue="true" | ||||||
|         android:key="@string/enable_watch_history_key" |         android:key="@string/enable_watch_history_key" | ||||||
|         android:summary="@string/enable_watch_history_summary" |         android:summary="@string/enable_watch_history_summary" | ||||||
|         android:title="@string/enable_watch_history_title" |         android:title="@string/enable_watch_history_title" | ||||||
|         app:iconSpaceReserved="false" /> |         app:iconSpaceReserved="false" /> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         android:defaultValue="true" |         android:defaultValue="true" | ||||||
|         android:dependency="@string/enable_watch_history_key" |         android:dependency="@string/enable_watch_history_key" | ||||||
|         android:key="@string/enable_playback_resume_key" |         android:key="@string/enable_playback_resume_key" | ||||||
| @@ -19,14 +19,14 @@ | |||||||
|         android:title="@string/enable_playback_resume_title" |         android:title="@string/enable_playback_resume_title" | ||||||
|         app:iconSpaceReserved="false" /> |         app:iconSpaceReserved="false" /> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         android:defaultValue="true" |         android:defaultValue="true" | ||||||
|         android:key="@string/enable_playback_state_lists_key" |         android:key="@string/enable_playback_state_lists_key" | ||||||
|         android:summary="@string/enable_playback_state_lists_summary" |         android:summary="@string/enable_playback_state_lists_summary" | ||||||
|         android:title="@string/enable_playback_state_lists_title" |         android:title="@string/enable_playback_state_lists_title" | ||||||
|         app:iconSpaceReserved="false" /> |         app:iconSpaceReserved="false" /> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         android:defaultValue="true" |         android:defaultValue="true" | ||||||
|         android:key="@string/enable_search_history_key" |         android:key="@string/enable_search_history_key" | ||||||
|         android:summary="@string/enable_search_history_summary" |         android:summary="@string/enable_search_history_summary" | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|     android:key="general_preferences" |     android:key="general_preferences" | ||||||
|     android:title="@string/settings_category_updates_title"> |     android:title="@string/settings_category_updates_title"> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         app:iconSpaceReserved="false" |         app:iconSpaceReserved="false" | ||||||
|         android:defaultValue="true" |         android:defaultValue="true" | ||||||
|         android:key="@string/update_app_key" |         android:key="@string/update_app_key" | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ | |||||||
|         android:summary="%s" |         android:summary="%s" | ||||||
|         android:title="@string/limit_mobile_data_usage_title" /> |         android:title="@string/limit_mobile_data_usage_title" /> | ||||||
|  |  | ||||||
|     <SwitchPreference |     <SwitchPreferenceCompat | ||||||
|         app:iconSpaceReserved="false" |         app:iconSpaceReserved="false" | ||||||
|         android:defaultValue="false" |         android:defaultValue="false" | ||||||
|         android:key="@string/show_higher_resolutions_key" |         android:key="@string/show_higher_resolutions_key" | ||||||
| @@ -61,20 +61,20 @@ | |||||||
|         android:layout="@layout/settings_category_header_layout" |         android:layout="@layout/settings_category_header_layout" | ||||||
|         android:title="@string/settings_category_player_title"> |         android:title="@string/settings_category_player_title"> | ||||||
|  |  | ||||||
|         <SwitchPreference |         <SwitchPreferenceCompat | ||||||
|             app:iconSpaceReserved="false" |             app:iconSpaceReserved="false" | ||||||
|             android:defaultValue="false" |             android:defaultValue="false" | ||||||
|             android:key="@string/use_external_video_player_key" |             android:key="@string/use_external_video_player_key" | ||||||
|             android:summary="@string/use_external_video_player_summary" |             android:summary="@string/use_external_video_player_summary" | ||||||
|             android:title="@string/use_external_video_player_title"/> |             android:title="@string/use_external_video_player_title"/> | ||||||
|  |  | ||||||
|         <SwitchPreference |         <SwitchPreferenceCompat | ||||||
|             app:iconSpaceReserved="false" |             app:iconSpaceReserved="false" | ||||||
|             android:defaultValue="false" |             android:defaultValue="false" | ||||||
|             android:key="@string/use_external_audio_player_key" |             android:key="@string/use_external_audio_player_key" | ||||||
|             android:title="@string/use_external_audio_player_title"/> |             android:title="@string/use_external_audio_player_title"/> | ||||||
|  |  | ||||||
|         <SwitchPreference |         <SwitchPreferenceCompat | ||||||
|             app:iconSpaceReserved="false" |             app:iconSpaceReserved="false" | ||||||
|             android:defaultValue="false" |             android:defaultValue="false" | ||||||
|             android:key="@string/show_play_with_kodi_key" |             android:key="@string/show_play_with_kodi_key" | ||||||
| @@ -114,42 +114,42 @@ | |||||||
|                 android:summary="@string/autoplay_summary" |                 android:summary="@string/autoplay_summary" | ||||||
|                 android:title="@string/autoplay_title"/> |                 android:title="@string/autoplay_title"/> | ||||||
|  |  | ||||||
|         <SwitchPreference |         <SwitchPreferenceCompat | ||||||
|             app:iconSpaceReserved="false" |             app:iconSpaceReserved="false" | ||||||
|             android:defaultValue="false" |             android:defaultValue="false" | ||||||
|             android:key="@string/auto_queue_key" |             android:key="@string/auto_queue_key" | ||||||
|             android:summary="@string/auto_queue_summary" |             android:summary="@string/auto_queue_summary" | ||||||
|             android:title="@string/auto_queue_title"/> |             android:title="@string/auto_queue_title"/> | ||||||
|  |  | ||||||
|         <SwitchPreference |         <SwitchPreferenceCompat | ||||||
|             app:iconSpaceReserved="false" |             app:iconSpaceReserved="false" | ||||||
|             android:defaultValue="false" |             android:defaultValue="false" | ||||||
|             android:key="@string/resume_on_audio_focus_gain_key" |             android:key="@string/resume_on_audio_focus_gain_key" | ||||||
|             android:summary="@string/resume_on_audio_focus_gain_summary" |             android:summary="@string/resume_on_audio_focus_gain_summary" | ||||||
|             android:title="@string/resume_on_audio_focus_gain_title"/> |             android:title="@string/resume_on_audio_focus_gain_title"/> | ||||||
|  |  | ||||||
|         <SwitchPreference |         <SwitchPreferenceCompat | ||||||
|             app:iconSpaceReserved="false" |             app:iconSpaceReserved="false" | ||||||
|             android:defaultValue="true" |             android:defaultValue="true" | ||||||
|             android:key="@string/volume_gesture_control_key" |             android:key="@string/volume_gesture_control_key" | ||||||
|             android:summary="@string/volume_gesture_control_summary" |             android:summary="@string/volume_gesture_control_summary" | ||||||
|             android:title="@string/volume_gesture_control_title"/> |             android:title="@string/volume_gesture_control_title"/> | ||||||
|  |  | ||||||
|         <SwitchPreference |         <SwitchPreferenceCompat | ||||||
|             app:iconSpaceReserved="false" |             app:iconSpaceReserved="false" | ||||||
|             android:defaultValue="true" |             android:defaultValue="true" | ||||||
|             android:key="@string/brightness_gesture_control_key" |             android:key="@string/brightness_gesture_control_key" | ||||||
|             android:summary="@string/brightness_gesture_control_summary" |             android:summary="@string/brightness_gesture_control_summary" | ||||||
|             android:title="@string/brightness_gesture_control_title"/> |             android:title="@string/brightness_gesture_control_title"/> | ||||||
|  |  | ||||||
|         <SwitchPreference |         <SwitchPreferenceCompat | ||||||
|             app:iconSpaceReserved="false" |             app:iconSpaceReserved="false" | ||||||
|             android:defaultValue="true" |             android:defaultValue="true" | ||||||
|             android:key="@string/popup_remember_size_pos_key" |             android:key="@string/popup_remember_size_pos_key" | ||||||
|             android:summary="@string/popup_remember_size_pos_summary" |             android:summary="@string/popup_remember_size_pos_summary" | ||||||
|             android:title="@string/popup_remember_size_pos_title"/> |             android:title="@string/popup_remember_size_pos_title"/> | ||||||
|  |  | ||||||
|         <SwitchPreference |         <SwitchPreferenceCompat | ||||||
|             app:iconSpaceReserved="false" |             app:iconSpaceReserved="false" | ||||||
|             android:defaultValue="false" |             android:defaultValue="false" | ||||||
|             android:key="@string/use_inexact_seek_key" |             android:key="@string/use_inexact_seek_key" | ||||||
| @@ -165,7 +165,7 @@ | |||||||
|           android:summary="%s" |           android:summary="%s" | ||||||
|           android:title="@string/seek_duration_title"/> |           android:title="@string/seek_duration_title"/> | ||||||
|  |  | ||||||
|         <SwitchPreference |         <SwitchPreferenceCompat | ||||||
|             app:iconSpaceReserved="false" |             app:iconSpaceReserved="false" | ||||||
|             android:defaultValue="false" |             android:defaultValue="false" | ||||||
|             android:key="@string/clear_queue_confirmation_key" |             android:key="@string/clear_queue_confirmation_key" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Stypox
					Stypox