Skip to content
This repository has been archived by the owner on Oct 26, 2024. It is now read-only.

Commit

Permalink
fix(YouTube - Playback speed): Restore old playback speed menu
Browse files Browse the repository at this point in the history
  • Loading branch information
LisoUseInAIKyrios committed Oct 25, 2024
1 parent 966268f commit 0a77c18
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 43 deletions.
5 changes: 3 additions & 2 deletions app/src/main/java/app/revanced/integrations/shared/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -317,9 +317,10 @@ public static ViewParent getParentView(@NonNull View view, int nthParent) {
return parent;
}

final int currentDepthLog = currentDepth;
final int finalDepthLog = currentDepth;
final ViewParent finalParent = parent;
Logger.printDebug(() -> "Could not find parent view of depth: " + nthParent
+ " and instead found at: " + currentDepthLog + " view: " + view);
+ " and instead found at: " + finalDepthLog + " view: " + finalParent);
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,41 @@
* Abuse LithoFilter for {@link CustomPlaybackSpeedPatch}.
*/
public final class PlaybackSpeedMenuFilterPatch extends Filter {
// Must be volatile or synchronized, as litho filtering runs off main thread and this field is then access from the main thread.
public static volatile boolean isPlaybackSpeedMenuVisible;

/**
* Old litho based speed selection menu.
*/
public static volatile boolean isOldPlaybackSpeedMenuVisible;
/**
* 0.05x speed selection menu.
*/
public static volatile boolean isPlaybackRateSelectorMenuVisible;

private final StringFilterGroup playbackRateSelector;

public PlaybackSpeedMenuFilterPatch() {
addPathCallbacks(new StringFilterGroup(
// 0.05x speed menu.
playbackRateSelector = new StringFilterGroup(
null,
"playback_speed_sheet_content.eml-js"
));
"playback_rate_selector_menu_sheet.eml-js"
);

// Old litho based speed menu.
var oldPlaybackMenu = new StringFilterGroup(
null,
"playback_speed_sheet_content.eml-js");

addPathCallbacks(playbackRateSelector, oldPlaybackMenu);
}

@Override
boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
isPlaybackSpeedMenuVisible = true;
if (matchedGroup == playbackRateSelector) {
isPlaybackRateSelectorMenuVisible = true;
} else {
isOldPlaybackSpeedMenuVisible = true;
}

return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,20 @@ private static void loadCustomSpeeds() {
if (speedStrings.length == 0) {
throw new IllegalArgumentException();
}

customPlaybackSpeeds = new float[speedStrings.length];
for (int i = 0, length = speedStrings.length; i < length; i++) {
final float speed = Float.parseFloat(speedStrings[i]);
if (speed <= 0 || arrayContains(customPlaybackSpeeds, speed)) {
throw new IllegalArgumentException();
}

if (speed >= MAXIMUM_PLAYBACK_SPEED) {
resetCustomSpeeds(str("revanced_custom_playback_speeds_invalid", MAXIMUM_PLAYBACK_SPEED));
loadCustomSpeeds();
return;
}

customPlaybackSpeeds[i] = speed;
}
} catch (Exception ex) {
Expand All @@ -89,10 +92,12 @@ private static boolean arrayContains(float[] array, float value) {
/**
* Initialize a settings preference list with the available playback speeds.
*/
@SuppressWarnings("deprecation")
public static void initializeListPreference(ListPreference preference) {
if (preferenceListEntries == null) {
preferenceListEntries = new String[customPlaybackSpeeds.length];
preferenceListEntryValues = new String[customPlaybackSpeeds.length];

int i = 0;
for (float speed : customPlaybackSpeeds) {
String speedString = String.valueOf(speed);
Expand All @@ -101,6 +106,7 @@ public static void initializeListPreference(ListPreference preference) {
i++;
}
}

preference.setEntries(preferenceListEntries);
preference.setEntryValues(preferenceListEntryValues);
}
Expand All @@ -111,52 +117,69 @@ public static void initializeListPreference(ListPreference preference) {
public static void onFlyoutMenuCreate(RecyclerView recyclerView) {
recyclerView.getViewTreeObserver().addOnDrawListener(() -> {
try {
// For some reason, the custom playback speed flyout panel is activated when the user opens the share panel. (A/B tests)
// 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 || recyclerView.getChildCount() == 0) {
if (PlaybackSpeedMenuFilterPatch.isPlaybackRateSelectorMenuVisible) {
if (hideLithoMenuAndShowOldSpeedMenu(recyclerView, 5)) {
PlaybackSpeedMenuFilterPatch.isPlaybackRateSelectorMenuVisible = false;
}
return;
}
} catch (Exception ex) {
Logger.printException(() -> "isPlaybackRateSelectorMenuVisible failure failure: ", ex);
}

View firstChild = recyclerView.getChildAt(0);
if (!(firstChild instanceof ViewGroup)) {
return;
}
ViewGroup PlaybackSpeedParentView = (ViewGroup) firstChild;
if (PlaybackSpeedParentView.getChildCount() != 8) {
return;
try {
if (PlaybackSpeedMenuFilterPatch.isOldPlaybackSpeedMenuVisible) {
if (hideLithoMenuAndShowOldSpeedMenu(recyclerView, 7)) {
PlaybackSpeedMenuFilterPatch.isOldPlaybackSpeedMenuVisible = false;
}
}
} catch (Exception ex) {
Logger.printException(() -> "isOldPlaybackSpeedMenuVisible failure: ", ex);
}
});
}

PlaybackSpeedMenuFilterPatch.isPlaybackSpeedMenuVisible = false;
private static boolean hideLithoMenuAndShowOldSpeedMenu(RecyclerView recyclerView, int expectedChildCount) {
if (recyclerView.getChildCount() == 0) {
return false;
}

ViewParent parentView3rd = Utils.getParentView(recyclerView, 3);
if (!(parentView3rd instanceof ViewGroup)) {
return;
}
ViewParent parentView4th = parentView3rd.getParent();
if (!(parentView4th instanceof ViewGroup)) {
return;
}
View firstChild = recyclerView.getChildAt(0);
if (!(firstChild instanceof ViewGroup)) {
return false;
}

// Dismiss View [R.id.touch_outside] is the 1st ChildView of the 4th ParentView.
// This only shows in phone layout.
final var touchInsidedView = ((ViewGroup) parentView4th).getChildAt(0);
touchInsidedView.setSoundEffectsEnabled(false);
touchInsidedView.performClick();
ViewGroup PlaybackSpeedParentView = (ViewGroup) firstChild;
if (PlaybackSpeedParentView.getChildCount() != expectedChildCount) {
return false;
}

// In tablet layout there is no Dismiss View, instead we just hide all two parent views.
((ViewGroup) parentView3rd).setVisibility(View.GONE);
((ViewGroup) parentView4th).setVisibility(View.GONE);
PlaybackSpeedMenuFilterPatch.isPlaybackRateSelectorMenuVisible = false;

// 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.
ViewParent parentView3rd = Utils.getParentView(recyclerView, 3);
if (!(parentView3rd instanceof ViewGroup)) {
return true;
}

// Close the new Playback speed menu and show the old one.
showOldPlaybackSpeedMenu();
} catch (Exception ex) {
Logger.printException(() -> "onFlyoutMenuCreate failure", ex);
ViewParent parentView4th = parentView3rd.getParent();
if (!(parentView4th instanceof ViewGroup)) {
return true;
}
});

// Dismiss View [R.id.touch_outside] is the 1st ChildView of the 4th ParentView.
// This only shows in phone layout.
final var touchInsidedView = ((ViewGroup) parentView4th).getChildAt(0);
touchInsidedView.setSoundEffectsEnabled(false);
touchInsidedView.performClick();

// In tablet layout there is no Dismiss View, instead we just hide all two parent views.
((ViewGroup) parentView3rd).setVisibility(View.GONE);
((ViewGroup) parentView4th).setVisibility(View.GONE);

// Close the litho speed menu and show the old one.
showOldPlaybackSpeedMenu();

return true;
}

public static void showOldPlaybackSpeedMenu() {
Expand Down

0 comments on commit 0a77c18

Please sign in to comment.