mirror of
https://github.com/revanced/revanced-patches
synced 2025-02-16 08:16:48 +01:00
fix(YouTube): fix old quality and custom speed not working on tablets (#477)
This commit is contained in:
parent
d945af94f3
commit
dbec9b80eb
@ -3,71 +3,44 @@ package app.revanced.integrations.patches.playback.quality;
|
|||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewTreeObserver;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import app.revanced.integrations.patches.components.VideoQualityMenuFilterPatch;
|
import app.revanced.integrations.patches.components.VideoQualityMenuFilterPatch;
|
||||||
import app.revanced.integrations.settings.SettingsEnum;
|
import app.revanced.integrations.settings.SettingsEnum;
|
||||||
import app.revanced.integrations.utils.LogHelper;
|
import app.revanced.integrations.utils.LogHelper;
|
||||||
import com.facebook.litho.ComponentHost;
|
|
||||||
import kotlin.Deprecated;
|
|
||||||
|
|
||||||
// This patch contains the logic to show the old video quality menu.
|
/**
|
||||||
// Two methods are required, because the quality menu is a RecyclerView in the new YouTube version
|
* This patch contains the logic to show the old video quality menu.
|
||||||
// and a ListView in the old one.
|
* Two methods are required, because the quality menu is a RecyclerView in the new YouTube version
|
||||||
|
* and a ListView in the old one.
|
||||||
|
*/
|
||||||
public final class OldVideoQualityMenuPatch {
|
public final class OldVideoQualityMenuPatch {
|
||||||
|
|
||||||
public static void onFlyoutMenuCreate(final LinearLayout linearLayout) {
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static void onFlyoutMenuCreate(RecyclerView recyclerView) {
|
||||||
if (!SettingsEnum.SHOW_OLD_VIDEO_QUALITY_MENU.getBoolean()) return;
|
if (!SettingsEnum.SHOW_OLD_VIDEO_QUALITY_MENU.getBoolean()) return;
|
||||||
|
|
||||||
// The quality menu is a RecyclerView with 3 children. The third child is the "Advanced" quality menu.
|
recyclerView.getViewTreeObserver().addOnDrawListener(() -> {
|
||||||
addRecyclerListener(linearLayout, 3, 2, recyclerView -> {
|
try {
|
||||||
// Check if the current view is the quality menu.
|
// Check if the current view is the quality menu.
|
||||||
if (VideoQualityMenuFilterPatch.isVideoQualityMenuVisible) {
|
if (VideoQualityMenuFilterPatch.isVideoQualityMenuVisible) {
|
||||||
VideoQualityMenuFilterPatch.isVideoQualityMenuVisible = false;
|
VideoQualityMenuFilterPatch.isVideoQualityMenuVisible = false;
|
||||||
linearLayout.setVisibility(View.GONE);
|
((ViewGroup) recyclerView.getParent().getParent().getParent()).setVisibility(View.GONE);
|
||||||
|
|
||||||
// Click the "Advanced" quality menu to show the "old" quality menu.
|
// Click the "Advanced" quality menu to show the "old" quality menu.
|
||||||
((ComponentHost) recyclerView.getChildAt(0)).getChildAt(3).performClick();
|
((ViewGroup) recyclerView.getChildAt(0)).getChildAt(3).performClick();
|
||||||
LogHelper.printDebug(() -> "Advanced quality menu in new type of quality menu clicked");
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printException(() -> "onFlyoutMenuCreate failure", ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addRecyclerListener(@NonNull LinearLayout linearLayout,
|
/**
|
||||||
int expectedLayoutChildCount, int recyclerViewIndex,
|
* Injection point. Only used if spoofing to an old app version.
|
||||||
@NonNull RecyclerViewGlobalLayoutListener listener) {
|
*/
|
||||||
if (linearLayout.getChildCount() != expectedLayoutChildCount) return;
|
|
||||||
|
|
||||||
var layoutChild = linearLayout.getChildAt(recyclerViewIndex);
|
|
||||||
if (!(layoutChild instanceof RecyclerView)) return;
|
|
||||||
final var recyclerView = (RecyclerView) layoutChild;
|
|
||||||
|
|
||||||
recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(
|
|
||||||
new ViewTreeObserver.OnGlobalLayoutListener() {
|
|
||||||
@Override
|
|
||||||
public void onGlobalLayout() {
|
|
||||||
try {
|
|
||||||
listener.recyclerOnGlobalLayout(recyclerView);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
LogHelper.printException(() -> "addRecyclerListener failure", ex);
|
|
||||||
} finally {
|
|
||||||
// Remove the listener because it will be added again.
|
|
||||||
recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface RecyclerViewGlobalLayoutListener {
|
|
||||||
void recyclerOnGlobalLayout(@NonNull RecyclerView recyclerView);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated(message = "This patch is deprecated because the quality menu is not a ListView anymore")
|
|
||||||
public static void showOldVideoQualityMenu(final ListView listView) {
|
public static void showOldVideoQualityMenu(final ListView listView) {
|
||||||
if (!SettingsEnum.SHOW_OLD_VIDEO_QUALITY_MENU.getBoolean()) return;
|
if (!SettingsEnum.SHOW_OLD_VIDEO_QUALITY_MENU.getBoolean()) return;
|
||||||
|
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
package app.revanced.integrations.patches.playback.speed;
|
package app.revanced.integrations.patches.playback.speed;
|
||||||
|
|
||||||
import android.preference.ListPreference;
|
import android.preference.ListPreference;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import app.revanced.integrations.patches.components.PlaybackSpeedMenuFilterPatch;
|
import app.revanced.integrations.patches.components.PlaybackSpeedMenuFilterPatch;
|
||||||
import app.revanced.integrations.settings.SettingsEnum;
|
import app.revanced.integrations.settings.SettingsEnum;
|
||||||
import app.revanced.integrations.utils.LogHelper;
|
import app.revanced.integrations.utils.LogHelper;
|
||||||
import app.revanced.integrations.utils.ReVancedUtils;
|
import app.revanced.integrations.utils.ReVancedUtils;
|
||||||
import com.facebook.litho.ComponentHost;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import static app.revanced.integrations.patches.playback.quality.OldVideoQualityMenuPatch.addRecyclerListener;
|
|
||||||
|
|
||||||
public class CustomPlaybackSpeedPatch {
|
public class CustomPlaybackSpeedPatch {
|
||||||
/**
|
/**
|
||||||
* Maximum playback speed, exclusive value. Custom speeds must be less than this value.
|
* Maximum playback speed, exclusive value. Custom speeds must be less than this value.
|
||||||
|
* Limit is required otherwise double digit speeds show up out of order in the UI selector.
|
||||||
*/
|
*/
|
||||||
public static final float MAXIMUM_PLAYBACK_SPEED = 10;
|
public static final float MAXIMUM_PLAYBACK_SPEED = 10;
|
||||||
|
|
||||||
@ -26,16 +26,6 @@ public class CustomPlaybackSpeedPatch {
|
|||||||
*/
|
*/
|
||||||
public static float[] customPlaybackSpeeds;
|
public static float[] customPlaybackSpeeds;
|
||||||
|
|
||||||
/**
|
|
||||||
* Minimum value of {@link #customPlaybackSpeeds}
|
|
||||||
*/
|
|
||||||
public static float minPlaybackSpeed;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maxium value of {@link #customPlaybackSpeeds}
|
|
||||||
*/
|
|
||||||
public static float maxPlaybackSpeed;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PreferenceList entries and values, of all available playback speeds.
|
* PreferenceList entries and values, of all available playback speeds.
|
||||||
*/
|
*/
|
||||||
@ -69,8 +59,6 @@ public class CustomPlaybackSpeedPatch {
|
|||||||
loadCustomSpeeds();
|
loadCustomSpeeds();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
minPlaybackSpeed = Math.min(minPlaybackSpeed, speed);
|
|
||||||
maxPlaybackSpeed = Math.max(maxPlaybackSpeed, speed);
|
|
||||||
customPlaybackSpeeds[i] = speed;
|
customPlaybackSpeeds[i] = speed;
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
@ -106,25 +94,37 @@ public class CustomPlaybackSpeedPatch {
|
|||||||
preference.setEntryValues(preferenceListEntryValues);
|
preference.setEntryValues(preferenceListEntryValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* To reduce copy and paste between two similar code paths.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
public static void onFlyoutMenuCreate(final LinearLayout linearLayout) {
|
public static void onFlyoutMenuCreate(RecyclerView recyclerView) {
|
||||||
// The playback rate menu is a RecyclerView with 2 children. The third child is the "Advanced" quality menu.
|
recyclerView.getViewTreeObserver().addOnDrawListener(() -> {
|
||||||
addRecyclerListener(linearLayout, 2, 1, recyclerView -> {
|
try {
|
||||||
if (PlaybackSpeedMenuFilterPatch.isPlaybackSpeedMenuVisible) {
|
// For some reason, the custom playback speed flyout panel is activated when the user opens the share panel. (A/B tests)
|
||||||
PlaybackSpeedMenuFilterPatch.isPlaybackSpeedMenuVisible = false;
|
// Check the child count of playback speed flyout panel to prevent this issue.
|
||||||
|
// Child count of playback speed flyout panel is always 8.
|
||||||
|
if (PlaybackSpeedMenuFilterPatch.isPlaybackSpeedMenuVisible
|
||||||
|
&& ((ViewGroup) recyclerView.getChildAt(0)).getChildCount() == 8) {
|
||||||
|
PlaybackSpeedMenuFilterPatch.isPlaybackSpeedMenuVisible = false;
|
||||||
|
ViewGroup parentView3rd = (ViewGroup) recyclerView.getParent().getParent().getParent();
|
||||||
|
ViewGroup parentView4th = (ViewGroup) parentView3rd.getParent();
|
||||||
|
|
||||||
if (recyclerView.getChildCount() == 1 && recyclerView.getChildAt(0) instanceof ComponentHost) {
|
// Dismiss View [R.id.touch_outside] is the 1st ChildView of the 4th ParentView.
|
||||||
linearLayout.setVisibility(View.GONE);
|
// This only shows in phone layout.
|
||||||
|
parentView4th.getChildAt(0).performClick();
|
||||||
|
|
||||||
// Close the new Playback speed menu and instead show the old one.
|
// In tablet layout there is no Dismiss View, instead we just hide all two parent views.
|
||||||
|
parentView3rd.setVisibility(View.GONE);
|
||||||
|
parentView4th.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
// This works without issues for both tablet and phone layouts,
|
||||||
|
// So no code is needed to check whether the current device is a tablet or phone.
|
||||||
|
|
||||||
|
// Close the new Playback speed menu and show the old one.
|
||||||
showOldPlaybackSpeedMenu();
|
showOldPlaybackSpeedMenu();
|
||||||
|
|
||||||
// DismissView [R.id.touch_outside] is the 1st ChildView of the 3rd ParentView.
|
|
||||||
((ViewGroup) linearLayout.getParent().getParent().getParent())
|
|
||||||
.getChildAt(0).performClick();
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printException(() -> "onFlyoutMenuCreate failure", ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user