Merge branch 'TeamNewPipe:dev' into dev

This commit is contained in:
LingYinTianMeng 2022-05-03 09:26:32 +08:00 committed by GitHub
commit 01d996a5c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
89 changed files with 1692 additions and 927 deletions

View file

@ -25,7 +25,6 @@ import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import android.os.Bundle
import android.os.Parcelable
@ -37,7 +36,6 @@ import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.annotation.AttrRes
import androidx.annotation.Nullable
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.content.res.AppCompatResources
@ -80,6 +78,7 @@ import org.schabi.newpipe.util.DeviceUtils
import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.NavigationHelper
import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountStreams
import org.schabi.newpipe.util.ThemeHelper.resolveDrawable
import org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout
import java.time.OffsetDateTime
import java.util.function.Consumer
@ -579,19 +578,6 @@ class FeedFragment : BaseStateFragment<FeedState>() {
lastNewItemsCount = highlightCount
}
private fun resolveDrawable(context: Context, @AttrRes attrResId: Int): Drawable? {
return androidx.core.content.ContextCompat.getDrawable(
context,
android.util.TypedValue().apply {
context.theme.resolveAttribute(
attrResId,
this,
true
)
}.resourceId
)
}
private fun showNewItemsLoaded() {
tryGetNewItemsLoadedButton()?.clearAnimation()
tryGetNewItemsLoadedButton()

View file

@ -3557,15 +3557,27 @@ public final class Player implements
}
// apply caption language from previous user preference
final List<String> selectedPreferredLanguages =
trackSelector.getParameters().preferredTextLanguages;
final int textRendererIndex = getCaptionRendererIndex();
if (textRendererIndex == RENDERER_UNAVAILABLE) {
return;
}
// If user prefers to show no caption, then disable the renderer.
// Otherwise, DefaultTrackSelector may automatically find an available caption
// and display that.
final String userPreferredLanguage =
prefs.getString(context.getString(R.string.caption_user_set_key), null);
final int textRendererIndex = getCaptionRendererIndex();
if (userPreferredLanguage == null) {
trackSelector.setParameters(trackSelector.buildUponParameters()
.setRendererDisabled(textRendererIndex, true));
return;
}
if (userPreferredLanguage != null
&& !selectedPreferredLanguages.contains(userPreferredLanguage)
&& textRendererIndex != RENDERER_UNAVAILABLE) {
// Only set preferred language if it does not match the user preference,
// otherwise there might be an infinite cycle at onTextTracksChanged.
final List<String> selectedPreferredLanguages =
trackSelector.getParameters().preferredTextLanguages;
if (!selectedPreferredLanguages.contains(userPreferredLanguage)) {
trackSelector.setParameters(trackSelector.buildUponParameters()
.setPreferredTextLanguages(userPreferredLanguage,
PlayerHelper.captionLanguageStemOf(userPreferredLanguage))

View file

@ -78,6 +78,20 @@ public final class PlayerHelper {
private static final NumberFormat SPEED_FORMATTER = new DecimalFormat("0.##x");
private static final NumberFormat PITCH_FORMATTER = new DecimalFormat("##%");
/**
* Maximum opacity allowed for Android 12 and higher to allow touches on other apps when using
* NewPipe's popup player.
*
* <p>
* This value is hardcoded instead of being get dynamically with the method linked of the
* constant documentation below, because it is not static and popup player layout parameters
* are generated with static methods.
* </p>
*
* @see WindowManager.LayoutParams#FLAG_NOT_TOUCHABLE
*/
private static final float MAXIMUM_OPACITY_ALLOWED_FOR_S_AND_HIGHER = 0.8f;
@Retention(SOURCE)
@IntDef({AUTOPLAY_TYPE_ALWAYS, AUTOPLAY_TYPE_WIFI,
AUTOPLAY_TYPE_NEVER})
@ -412,7 +426,7 @@ public final class PlayerHelper {
context.getString(R.string.progressive_load_interval_key),
context.getString(R.string.progressive_load_interval_default_value));
if (context.getString(R.string.progressive_load_interval_default_value)
if (context.getString(R.string.progressive_load_interval_exoplayer_default_value)
.equals(preferredIntervalBytes)) {
return ProgressiveMediaSource.DEFAULT_LOADING_CHECK_INTERVAL_BYTES;
}
@ -587,6 +601,12 @@ public final class PlayerHelper {
flags,
PixelFormat.TRANSLUCENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// Setting maximum opacity allowed for touch events to other apps for Android 12 and
// higher to prevent non interaction when using other apps with the popup player
closeOverlayLayoutParams.alpha = MAXIMUM_OPACITY_ALLOWED_FOR_S_AND_HIGHER;
}
closeOverlayLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
closeOverlayLayoutParams.softInputMode =
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;

View file

@ -0,0 +1,38 @@
package org.schabi.newpipe.player.helper;
/**
* Converts between percent and 12-tone equal temperament semitones.
* <br/>
* @see
* <a href="https://en.wikipedia.org/wiki/Equal_temperament#Twelve-tone_equal_temperament">
* Wikipedia: Equal temperament#Twelve-tone equal temperament
* </a>
*/
public final class PlayerSemitoneHelper {
public static final int SEMITONE_COUNT = 12;
private PlayerSemitoneHelper() {
// No impl
}
public static String formatPitchSemitones(final double percent) {
return formatPitchSemitones(percentToSemitones(percent));
}
public static String formatPitchSemitones(final int semitones) {
return semitones > 0 ? "+" + semitones : "" + semitones;
}
public static double semitonesToPercent(final int semitones) {
return Math.pow(2, ensureSemitonesInRange(semitones) / (double) SEMITONE_COUNT);
}
public static int percentToSemitones(final double percent) {
return ensureSemitonesInRange(
(int) Math.round(SEMITONE_COUNT * Math.log(percent) / Math.log(2)));
}
private static int ensureSemitonesInRange(final int semitones) {
return Math.max(-SEMITONE_COUNT, Math.min(SEMITONE_COUNT, semitones));
}
}

View file

@ -26,6 +26,10 @@ class NotificationsSettingsFragment : BasePreferenceFragment(), OnSharedPreferen
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.notifications_settings)
// main check is done in onResume, but also do it here to prevent flickering
preferenceScreen.isEnabled =
NotificationHelper.areNotificationsEnabledOnDevice(requireContext())
}
override fun onStart() {
@ -64,7 +68,7 @@ class NotificationsSettingsFragment : BasePreferenceFragment(), OnSharedPreferen
// If they are disabled, show a snackbar informing the user about that
// while allowing them to open the device's app settings.
val enabled = NotificationHelper.areNotificationsEnabledOnDevice(requireContext())
preferenceScreen.isEnabled = enabled
preferenceScreen.isEnabled = enabled // it is disabled by default, see the xml
if (!enabled) {
if (notificationWarningSnackbar == null) {
notificationWarningSnackbar = Snackbar.make(
@ -85,9 +89,6 @@ class NotificationsSettingsFragment : BasePreferenceFragment(), OnSharedPreferen
show()
}
}
} else {
notificationWarningSnackbar?.dismiss()
notificationWarningSnackbar = null
}
// (Re-)Create loader
@ -102,6 +103,9 @@ class NotificationsSettingsFragment : BasePreferenceFragment(), OnSharedPreferen
loader?.dispose()
loader = null
notificationWarningSnackbar?.dismiss()
notificationWarningSnackbar = null
super.onPause()
}

View file

@ -23,9 +23,11 @@ import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
import androidx.annotation.AttrRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.appcompat.app.ActionBar;
@ -227,6 +229,22 @@ public final class ThemeHelper {
return value.data;
}
/**
* Resolves a {@link Drawable} by it's id.
*
* @param context Context
* @param attrResId Resource id
* @return the {@link Drawable}
*/
public static Drawable resolveDrawable(
@NonNull final Context context,
@AttrRes final int attrResId
) {
final TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(attrResId, typedValue, true);
return ContextCompat.getDrawable(context, typedValue.resourceId);
}
private static String getSelectedThemeKey(final Context context) {
final String themeKey = context.getString(R.string.theme_key);
final String defaultTheme = context.getResources().getString(R.string.default_theme_value);