mirror of
https://github.com/revanced/revanced-integrations.git
synced 2025-01-23 02:07:33 +01:00
feat(YouTube): Bump compatibility to 18.37.36
(#483)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
This commit is contained in:
parent
1e6fabceea
commit
5dadb0d523
@ -1,25 +1,12 @@
|
|||||||
package app.revanced.integrations.patches;
|
package app.revanced.integrations.patches;
|
||||||
|
|
||||||
import static app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike.Vote;
|
|
||||||
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.text.Editable;
|
import android.text.*;
|
||||||
import android.text.Spannable;
|
|
||||||
import android.text.SpannableString;
|
|
||||||
import android.text.Spanned;
|
|
||||||
import android.text.TextWatcher;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike;
|
import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike;
|
||||||
import app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
|
import app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
|
||||||
import app.revanced.integrations.settings.SettingsEnum;
|
import app.revanced.integrations.settings.SettingsEnum;
|
||||||
@ -27,6 +14,13 @@ import app.revanced.integrations.shared.PlayerType;
|
|||||||
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 java.lang.ref.WeakReference;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import static app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike.Vote;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles all interaction of UI patch components.
|
* Handles all interaction of UI patch components.
|
||||||
*
|
*
|
||||||
@ -149,23 +143,27 @@ public class ReturnYouTubeDislikePatch {
|
|||||||
@NonNull AtomicReference<CharSequence> textRef,
|
@NonNull AtomicReference<CharSequence> textRef,
|
||||||
@NonNull CharSequence original) {
|
@NonNull CharSequence original) {
|
||||||
try {
|
try {
|
||||||
if (!SettingsEnum.RYD_ENABLED.getBoolean() || PlayerType.getCurrent().isNoneOrHidden()) {
|
if (!SettingsEnum.RYD_ENABLED.getBoolean()) {
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
String conversionContextString = conversionContext.toString();
|
String conversionContextString = conversionContext.toString();
|
||||||
LogHelper.printDebug(() -> "conversionContext: " + conversionContextString);
|
LogHelper.printDebug(() -> "conversionContext: " + conversionContextString);
|
||||||
|
|
||||||
final boolean isSegmentedButton;
|
final Spanned replacement;
|
||||||
if (conversionContextString.contains("|segmented_like_dislike_button.eml|")) {
|
if (conversionContextString.contains("|segmented_like_dislike_button.eml|")) {
|
||||||
isSegmentedButton = true;
|
replacement = ReturnYouTubeDislike.getDislikesSpanForRegularVideo((Spannable) original, true);
|
||||||
} else if (conversionContextString.contains("|dislike_button.eml|") ) {
|
} else if (conversionContextString.contains("|dislike_button.eml|") ) {
|
||||||
isSegmentedButton = false;
|
// This code path is basically dead because it's only used when spoofing between 17.09.xx and 17.30.xx
|
||||||
|
// but spoofing to that range gives a broken UI layout.
|
||||||
|
// Keep this check here anyways just in case the old litho layout is somehow still used.
|
||||||
|
replacement = ReturnYouTubeDislike.getDislikesSpanForRegularVideo((Spannable) original, false);
|
||||||
|
} else if (conversionContextString.contains("|shorts_dislike_button.eml|")) {
|
||||||
|
replacement = ReturnYouTubeDislike.getDislikeSpanForShort((Spannable) original);
|
||||||
} else {
|
} else {
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
Spanned replacement = ReturnYouTubeDislike.getDislikesSpanForRegularVideo((Spannable) original, isSegmentedButton);
|
|
||||||
textRef.set(replacement);
|
textRef.set(replacement);
|
||||||
return replacement;
|
return replacement;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
@ -292,10 +292,10 @@ abstract class Filter {
|
|||||||
boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
|
boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
|
||||||
FilterGroupList matchedList, FilterGroup matchedGroup, int matchedIndex) {
|
FilterGroupList matchedList, FilterGroup matchedGroup, int matchedIndex) {
|
||||||
if (SettingsEnum.DEBUG.getBoolean()) {
|
if (SettingsEnum.DEBUG.getBoolean()) {
|
||||||
if (pathFilterGroupList == matchedList) {
|
if (matchedList == identifierFilterGroupList) {
|
||||||
LogHelper.printDebug(() -> getClass().getSimpleName() + " Filtered path: " + path);
|
|
||||||
} else if (identifierFilterGroupList == matchedList) {
|
|
||||||
LogHelper.printDebug(() -> getClass().getSimpleName() + " Filtered identifier: " + identifier);
|
LogHelper.printDebug(() -> getClass().getSimpleName() + " Filtered identifier: " + identifier);
|
||||||
|
} else {
|
||||||
|
LogHelper.printDebug(() -> getClass().getSimpleName() + " Filtered path: " + path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,31 +1,29 @@
|
|||||||
package app.revanced.integrations.patches.components;
|
package app.revanced.integrations.patches.components;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
|
import android.view.View;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
import app.revanced.integrations.settings.SettingsEnum;
|
||||||
|
import com.google.android.libraries.youtube.rendering.ui.pivotbar.PivotBar;
|
||||||
|
|
||||||
import static app.revanced.integrations.utils.ReVancedUtils.hideViewBy1dpUnderCondition;
|
import static app.revanced.integrations.utils.ReVancedUtils.hideViewBy1dpUnderCondition;
|
||||||
import static app.revanced.integrations.utils.ReVancedUtils.hideViewUnderCondition;
|
import static app.revanced.integrations.utils.ReVancedUtils.hideViewUnderCondition;
|
||||||
|
|
||||||
import android.view.View;
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.google.android.libraries.youtube.rendering.ui.pivotbar.PivotBar;
|
|
||||||
|
|
||||||
import app.revanced.integrations.settings.SettingsEnum;
|
|
||||||
|
|
||||||
public final class ShortsFilter extends Filter {
|
public final class ShortsFilter extends Filter {
|
||||||
private static final String REEL_CHANNEL_BAR_PATH = "reel_channel_bar.eml";
|
|
||||||
public static PivotBar pivotBar; // Set by patch.
|
public static PivotBar pivotBar; // Set by patch.
|
||||||
|
private final String REEL_CHANNEL_BAR_PATH = "reel_channel_bar.eml";
|
||||||
|
|
||||||
private final StringFilterGroup channelBar;
|
private final StringFilterGroup channelBar;
|
||||||
private final StringFilterGroup soundButton;
|
private final StringFilterGroup soundButton;
|
||||||
private final StringFilterGroup infoPanel;
|
private final StringFilterGroup infoPanel;
|
||||||
private final StringFilterGroup shortsShelfHeader;
|
private final StringFilterGroup shelfHeader;
|
||||||
|
|
||||||
|
private final StringFilterGroup videoActionButton;
|
||||||
|
private final ByteArrayFilterGroupList videoActionButtonGroupList = new ByteArrayFilterGroupList();
|
||||||
|
|
||||||
public ShortsFilter() {
|
public ShortsFilter() {
|
||||||
// Home / subscription feed components.
|
|
||||||
var thanksButton = new StringFilterGroup(
|
|
||||||
SettingsEnum.HIDE_SHORTS_THANKS_BUTTON,
|
|
||||||
"suggested_action"
|
|
||||||
);
|
|
||||||
var shorts = new StringFilterGroup(
|
var shorts = new StringFilterGroup(
|
||||||
SettingsEnum.HIDE_SHORTS,
|
SettingsEnum.HIDE_SHORTS,
|
||||||
"shorts_shelf",
|
"shorts_shelf",
|
||||||
@ -33,14 +31,22 @@ public final class ShortsFilter extends Filter {
|
|||||||
"shorts_grid",
|
"shorts_grid",
|
||||||
"shorts_video_cell",
|
"shorts_video_cell",
|
||||||
"shorts_pivot_item"
|
"shorts_pivot_item"
|
||||||
|
|
||||||
);
|
);
|
||||||
|
// Feed Shorts shelf header.
|
||||||
// Use a different filter group for this pattern, as it requires an additional check after matching.
|
// Use a different filter group for this pattern, as it requires an additional check after matching.
|
||||||
shortsShelfHeader = new StringFilterGroup(
|
shelfHeader = new StringFilterGroup(
|
||||||
SettingsEnum.HIDE_SHORTS,
|
SettingsEnum.HIDE_SHORTS,
|
||||||
"shelf_header.eml"
|
"shelf_header.eml"
|
||||||
);
|
);
|
||||||
identifierFilterGroupList.addAll(shorts, shortsShelfHeader, thanksButton);
|
|
||||||
|
|
||||||
|
// Home / subscription feed components.
|
||||||
|
var thanksButton = new StringFilterGroup(
|
||||||
|
SettingsEnum.HIDE_SHORTS_THANKS_BUTTON,
|
||||||
|
"suggested_action"
|
||||||
|
);
|
||||||
|
|
||||||
|
identifierFilterGroupList.addAll(shorts, shelfHeader, thanksButton);
|
||||||
|
|
||||||
// Shorts player components.
|
// Shorts player components.
|
||||||
var joinButton = new StringFilterGroup(
|
var joinButton = new StringFilterGroup(
|
||||||
@ -51,6 +57,7 @@ public final class ShortsFilter extends Filter {
|
|||||||
SettingsEnum.HIDE_SHORTS_SUBSCRIBE_BUTTON,
|
SettingsEnum.HIDE_SHORTS_SUBSCRIBE_BUTTON,
|
||||||
"subscribe_button"
|
"subscribe_button"
|
||||||
);
|
);
|
||||||
|
|
||||||
channelBar = new StringFilterGroup(
|
channelBar = new StringFilterGroup(
|
||||||
SettingsEnum.HIDE_SHORTS_CHANNEL_BAR,
|
SettingsEnum.HIDE_SHORTS_CHANNEL_BAR,
|
||||||
REEL_CHANNEL_BAR_PATH
|
REEL_CHANNEL_BAR_PATH
|
||||||
@ -59,11 +66,37 @@ public final class ShortsFilter extends Filter {
|
|||||||
SettingsEnum.HIDE_SHORTS_SOUND_BUTTON,
|
SettingsEnum.HIDE_SHORTS_SOUND_BUTTON,
|
||||||
"reel_pivot_button"
|
"reel_pivot_button"
|
||||||
);
|
);
|
||||||
|
|
||||||
infoPanel = new StringFilterGroup(
|
infoPanel = new StringFilterGroup(
|
||||||
SettingsEnum.HIDE_SHORTS_INFO_PANEL,
|
SettingsEnum.HIDE_SHORTS_INFO_PANEL,
|
||||||
"shorts_info_panel_overview"
|
"shorts_info_panel_overview"
|
||||||
);
|
);
|
||||||
pathFilterGroupList.addAll(joinButton, subscribeButton, channelBar, soundButton, infoPanel);
|
|
||||||
|
videoActionButton = new StringFilterGroup(
|
||||||
|
null,
|
||||||
|
"ContainerType|shorts_video_action_button"
|
||||||
|
);
|
||||||
|
|
||||||
|
pathFilterGroupList.addAll(
|
||||||
|
joinButton, subscribeButton, channelBar, soundButton, infoPanel, videoActionButton
|
||||||
|
);
|
||||||
|
|
||||||
|
var shortsCommentButton = new ByteArrayAsStringFilterGroup(
|
||||||
|
SettingsEnum.HIDE_SHORTS_COMMENTS_BUTTON,
|
||||||
|
"reel_comment_button"
|
||||||
|
);
|
||||||
|
|
||||||
|
var shortsShareButton = new ByteArrayAsStringFilterGroup(
|
||||||
|
SettingsEnum.HIDE_SHORTS_SHARE_BUTTON,
|
||||||
|
"reel_share_button"
|
||||||
|
);
|
||||||
|
|
||||||
|
var shortsRemixButton = new ByteArrayAsStringFilterGroup(
|
||||||
|
SettingsEnum.HIDE_SHORTS_REMIX_BUTTON,
|
||||||
|
"reel_remix_button"
|
||||||
|
);
|
||||||
|
|
||||||
|
videoActionButtonGroupList.addAll(shortsCommentButton, shortsShareButton, shortsRemixButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -72,27 +105,34 @@ public final class ShortsFilter extends Filter {
|
|||||||
if (matchedList == pathFilterGroupList) {
|
if (matchedList == pathFilterGroupList) {
|
||||||
// Always filter if matched.
|
// Always filter if matched.
|
||||||
if (matchedGroup == soundButton || matchedGroup == infoPanel || matchedGroup == channelBar)
|
if (matchedGroup == soundButton || matchedGroup == infoPanel || matchedGroup == channelBar)
|
||||||
return super.isFiltered(path, identifier, protobufBufferArray, matchedList, matchedGroup, matchedIndex);
|
return super.isFiltered(identifier, path, protobufBufferArray, matchedList, matchedGroup, matchedIndex);
|
||||||
|
|
||||||
|
// Video action buttons (comment, share, remix) have the same path.
|
||||||
|
if (matchedGroup == videoActionButton) {
|
||||||
|
if (videoActionButtonGroupList.check(protobufBufferArray).isFiltered())
|
||||||
|
return super.isFiltered(identifier, path, protobufBufferArray, matchedList, matchedGroup, matchedIndex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Filter other path groups from pathFilterGroupList, only when reelChannelBar is visible
|
// Filter other path groups from pathFilterGroupList, only when reelChannelBar is visible
|
||||||
// to avoid false positives.
|
// to avoid false positives.
|
||||||
if (!path.startsWith(REEL_CHANNEL_BAR_PATH))
|
if (!path.startsWith(REEL_CHANNEL_BAR_PATH))
|
||||||
return false;
|
return false;
|
||||||
} else if (matchedGroup == shortsShelfHeader) {
|
} else if (matchedGroup == shelfHeader) {
|
||||||
// Because the header is used in watch history and possibly other places, check for the index,
|
// Because the header is used in watch history and possibly other places, check for the index,
|
||||||
// which is 0 when the shelf header is used for Shorts.
|
// which is 0 when the shelf header is used for Shorts.
|
||||||
if (matchedIndex != 0) return false;
|
if (matchedIndex != 0) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Super class handles logging.
|
// Super class handles logging.
|
||||||
return super.isFiltered(path, identifier, protobufBufferArray, matchedList, matchedGroup, matchedIndex);
|
return super.isFiltered(identifier, path, protobufBufferArray, matchedList, matchedGroup, matchedIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void hideShortsShelf(final View shortsShelfView) {
|
public static void hideShortsShelf(final View shortsShelfView) {
|
||||||
hideViewBy1dpUnderCondition(SettingsEnum.HIDE_SHORTS, shortsShelfView);
|
hideViewBy1dpUnderCondition(SettingsEnum.HIDE_SHORTS, shortsShelfView);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional components that have to be hidden by setting their visibility
|
// region Hide the buttons in older versions of YouTube. New versions use Litho.
|
||||||
|
|
||||||
public static void hideShortsCommentsButton(final View commentsButtonView) {
|
public static void hideShortsCommentsButton(final View commentsButtonView) {
|
||||||
hideViewUnderCondition(SettingsEnum.HIDE_SHORTS_COMMENTS_BUTTON, commentsButtonView);
|
hideViewUnderCondition(SettingsEnum.HIDE_SHORTS_COMMENTS_BUTTON, commentsButtonView);
|
||||||
@ -106,6 +146,8 @@ public final class ShortsFilter extends Filter {
|
|||||||
hideViewUnderCondition(SettingsEnum.HIDE_SHORTS_SHARE_BUTTON, shareButtonView);
|
hideViewUnderCondition(SettingsEnum.HIDE_SHORTS_SHARE_BUTTON, shareButtonView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
public static void hideNavigationBar() {
|
public static void hideNavigationBar() {
|
||||||
if (!SettingsEnum.HIDE_SHORTS_NAVIGATION_BAR.getBoolean()) return;
|
if (!SettingsEnum.HIDE_SHORTS_NAVIGATION_BAR.getBoolean()) return;
|
||||||
if (pivotBar == null) return;
|
if (pivotBar == null) return;
|
||||||
|
@ -100,10 +100,10 @@ public class StoryboardRendererRequester {
|
|||||||
|
|
||||||
var renderer = getStoryboardRendererUsingBody(String.format(ANDROID_INNER_TUBE_BODY, videoId));
|
var renderer = getStoryboardRendererUsingBody(String.format(ANDROID_INNER_TUBE_BODY, videoId));
|
||||||
if (renderer == null) {
|
if (renderer == null) {
|
||||||
LogHelper.printDebug(() -> videoId + " not available using android client");
|
LogHelper.printDebug(() -> videoId + " not available using Android client");
|
||||||
renderer = getStoryboardRendererUsingBody(String.format(TV_EMBED_INNER_TUBE_BODY, videoId, videoId));
|
renderer = getStoryboardRendererUsingBody(String.format(TV_EMBED_INNER_TUBE_BODY, videoId, videoId));
|
||||||
if (renderer == null) {
|
if (renderer == null) {
|
||||||
LogHelper.printDebug(() -> videoId + " not available using tv embedded client");
|
LogHelper.printDebug(() -> videoId + " not available using TV embedded client");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ public class ReturnYouTubeDislike {
|
|||||||
// 2. opened a short (without closing the regular video)
|
// 2. opened a short (without closing the regular video)
|
||||||
// 3. closed the short
|
// 3. closed the short
|
||||||
// 4. regular video is now present, but the videoId and RYD data is still for the short
|
// 4. regular video is now present, but the videoId and RYD data is still for the short
|
||||||
LogHelper.printDebug(() -> "Ignoring getDislikeSpanForContext(), as data loaded is for prior short");
|
LogHelper.printDebug(() -> "Ignoring dislike span, as data loaded is for prior short");
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
return waitForFetchAndUpdateReplacementSpan(original, isSegmentedButton);
|
return waitForFetchAndUpdateReplacementSpan(original, isSegmentedButton);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user