Compare commits

...

20 Commits

Author SHA1 Message Date
semantic-release-bot
4b77d27c77 chore: Release v5.13.0-dev.2 [skip ci]
# [5.13.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.13.0-dev.1...v5.13.0-dev.2) (2025-02-18)

### Bug Fixes

* **YouTube - Hide video action buttons:** Move 'Disable Like and Subscribe glow' to action buttons settings menu ([7991c80](7991c80129))
2025-02-18 07:29:55 +00:00
LisoUseInAIKyrios
7991c80129 fix(YouTube - Hide video action buttons): Move 'Disable Like and Subscribe glow' to action buttons settings menu 2025-02-18 09:26:30 +02:00
github-actions[bot]
6baf4ea2ac chore: Sync translations (#4473) 2025-02-18 09:24:59 +02:00
semantic-release-bot
c89538c8f5 chore: Release v5.13.0-dev.1 [skip ci]
# [5.13.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.12.0...v5.13.0-dev.1) (2025-02-18)

### Bug Fixes

* **YouTube - Hide layout components:** Do not hide 'Show anyway' button in search results ([94fb367](94fb367618))

### Features

* **YouTube - Swipe controls:** Swipe controls UI improvements ([#4422](https://github.com/ReVanced/revanced-patches/issues/4422)) ([3548359](354835966d))
2025-02-18 07:11:45 +00:00
LisoUseInAIKyrios
94fb367618 fix(YouTube - Hide layout components): Do not hide 'Show anyway' button in search results 2025-02-18 09:08:37 +02:00
MarcaD
354835966d feat(YouTube - Swipe controls): Swipe controls UI improvements (#4422) 2025-02-18 09:07:28 +02:00
github-actions[bot]
168f9b769e chore: Sync translations (#4472) 2025-02-18 09:06:39 +02:00
ILoveOpenSourceApplications
e4c4b3a73a refactor(YouTube): Use more consistent strings (#4376) 2025-02-17 10:07:24 +02:00
semantic-release-bot
fce98b4960 chore: Release v5.12.0 [skip ci]
# [5.12.0](https://github.com/ReVanced/revanced-patches/compare/v5.11.0...v5.12.0) (2025-02-17)

### Bug Fixes

* Allow changing default settings for existing app installs ([#4464](https://github.com/ReVanced/revanced-patches/issues/4464)) ([a959d79](a959d798e8))
* **Windy.app:** Remove obsolete `Unlock pro` patch ([#4428](https://github.com/ReVanced/revanced-patches/issues/4428)) ([421af92](421af92f4c))
* **YouTube - Spoof video streams:** Change default client to `Android TV` ([#4465](https://github.com/ReVanced/revanced-patches/issues/4465)) ([04b37dd](04b37dd55a))
* **YouTube:** Remove obsolete 18.x targets ([#4454](https://github.com/ReVanced/revanced-patches/issues/4454)) ([92c38b2](92c38b2cb4))

### Features

* **Return YouTube Dislike:** add `Show estimated likes` setting ([#4443](https://github.com/ReVanced/revanced-patches/issues/4443)) ([7c4285e](7c4285e3e6))
* **YouTube - SponsorBlock:** Redesign skip buttons ([#4427](https://github.com/ReVanced/revanced-patches/issues/4427)) ([0079ece](0079eceb87))
* **YouTube Music:** Support version `8.05.50` ([#4439](https://github.com/ReVanced/revanced-patches/issues/4439)) ([bcd157d](bcd157dd2b))
* **YouTube Music:** Support version `8.05.51` ([2382e9d](2382e9d09e))
2025-02-17 06:23:44 +00:00
LisoUseInAIKyrios
839aa81e9c chore: Merge branch dev to main (#4437) 2025-02-17 08:20:23 +02:00
semantic-release-bot
905bb0ea5f chore: Release v5.12.0-dev.7 [skip ci]
# [5.12.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.12.0-dev.6...v5.12.0-dev.7) (2025-02-16)

### Bug Fixes

* **YouTube - Spoof video streams:** Change default client to `Android TV` ([#4465](https://github.com/ReVanced/revanced-patches/issues/4465)) ([04b37dd](04b37dd55a))

### Features

* **YouTube Music:** Support version `8.05.51` ([2382e9d](2382e9d09e))
2025-02-16 16:41:43 +00:00
github-actions[bot]
a94a663859 chore: Sync translations (#4468) 2025-02-16 18:38:36 +02:00
LisoUseInAIKyrios
04b37dd55a fix(YouTube - Spoof video streams): Change default client to Android TV (#4465) 2025-02-16 18:34:12 +02:00
LisoUseInAIKyrios
2382e9d09e feat(YouTube Music): Support version 8.05.51 2025-02-16 18:31:52 +02:00
github-actions[bot]
97f504976a chore: Sync translations (#4467) 2025-02-16 18:30:04 +02:00
semantic-release-bot
0a6c5158e0 chore: Release v5.12.0-dev.6 [skip ci]
# [5.12.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.12.0-dev.5...v5.12.0-dev.6) (2025-02-16)

### Bug Fixes

* Allow changing default settings for existing app installs ([#4464](https://github.com/ReVanced/revanced-patches/issues/4464)) ([a959d79](a959d798e8))
2025-02-16 13:19:31 +00:00
LisoUseInAIKyrios
a959d798e8 fix: Allow changing default settings for existing app installs (#4464) 2025-02-16 15:16:24 +02:00
semantic-release-bot
39a0b9bda6 chore: Release v5.12.0-dev.5 [skip ci]
# [5.12.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.12.0-dev.4...v5.12.0-dev.5) (2025-02-13)

### Bug Fixes

* **YouTube:** Remove obsolete 18.x targets ([#4454](https://github.com/ReVanced/revanced-patches/issues/4454)) ([92c38b2](92c38b2cb4))
2025-02-13 12:41:16 +00:00
LisoUseInAIKyrios
92c38b2cb4 fix(YouTube): Remove obsolete 18.x targets (#4454) 2025-02-13 14:38:23 +02:00
github-actions[bot]
4732210d4b chore: Sync translations (#4455) 2025-02-13 14:35:32 +02:00
189 changed files with 3754 additions and 3564 deletions

View File

@@ -1,3 +1,66 @@
# [5.13.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.13.0-dev.1...v5.13.0-dev.2) (2025-02-18)
### Bug Fixes
* **YouTube - Hide video action buttons:** Move 'Disable Like and Subscribe glow' to action buttons settings menu ([29b265d](https://github.com/ReVanced/revanced-patches/commit/29b265d8fdaa48502650be9623bfc518a57a0bb1))
# [5.13.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.12.0...v5.13.0-dev.1) (2025-02-18)
### Bug Fixes
* **YouTube - Hide layout components:** Do not hide 'Show anyway' button in search results ([4ac8854](https://github.com/ReVanced/revanced-patches/commit/4ac8854b99808a8957f3b0b7438e1e0cdedffbaf))
### Features
* **YouTube - Swipe controls:** Swipe controls UI improvements ([#4422](https://github.com/ReVanced/revanced-patches/issues/4422)) ([198e4d2](https://github.com/ReVanced/revanced-patches/commit/198e4d2a2315c24a09eb9ecfefbd131a75384d2c))
# [5.12.0](https://github.com/ReVanced/revanced-patches/compare/v5.11.0...v5.12.0) (2025-02-17)
### Bug Fixes
* Allow changing default settings for existing app installs ([#4464](https://github.com/ReVanced/revanced-patches/issues/4464)) ([1bd7986](https://github.com/ReVanced/revanced-patches/commit/1bd7986823e774a929c8a9102a7cc96e245d5274))
* **Windy.app:** Remove obsolete `Unlock pro` patch ([#4428](https://github.com/ReVanced/revanced-patches/issues/4428)) ([83d116e](https://github.com/ReVanced/revanced-patches/commit/83d116e8fd3935ee431cfdf0b8e095d04ee77259))
* **YouTube - Spoof video streams:** Change default client to `Android TV` ([#4465](https://github.com/ReVanced/revanced-patches/issues/4465)) ([0412c79](https://github.com/ReVanced/revanced-patches/commit/0412c7901dc8599b6079d9c3ba26452f88af642b))
* **YouTube:** Remove obsolete 18.x targets ([#4454](https://github.com/ReVanced/revanced-patches/issues/4454)) ([a006758](https://github.com/ReVanced/revanced-patches/commit/a0067581d0f877e1b4eb1f888a25786f09676b2e))
### Features
* **Return YouTube Dislike:** add `Show estimated likes` setting ([#4443](https://github.com/ReVanced/revanced-patches/issues/4443)) ([9a88b42](https://github.com/ReVanced/revanced-patches/commit/9a88b4239fd63d5f91105fec8e7d59d318a5d09a))
* **YouTube - SponsorBlock:** Redesign skip buttons ([#4427](https://github.com/ReVanced/revanced-patches/issues/4427)) ([8f4883f](https://github.com/ReVanced/revanced-patches/commit/8f4883fc002420bfb4056401e23445c99e1d3fce))
* **YouTube Music:** Support version `8.05.50` ([#4439](https://github.com/ReVanced/revanced-patches/issues/4439)) ([b31fed9](https://github.com/ReVanced/revanced-patches/commit/b31fed98901fcda1bce6f05eb0de63280c689fa0))
* **YouTube Music:** Support version `8.05.51` ([128441e](https://github.com/ReVanced/revanced-patches/commit/128441e78bc0d096c3fc2f57782ab90c39c3ae4b))
# [5.12.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.12.0-dev.6...v5.12.0-dev.7) (2025-02-16)
### Bug Fixes
* **YouTube - Spoof video streams:** Change default client to `Android TV` ([#4465](https://github.com/ReVanced/revanced-patches/issues/4465)) ([0412c79](https://github.com/ReVanced/revanced-patches/commit/0412c7901dc8599b6079d9c3ba26452f88af642b))
### Features
* **YouTube Music:** Support version `8.05.51` ([128441e](https://github.com/ReVanced/revanced-patches/commit/128441e78bc0d096c3fc2f57782ab90c39c3ae4b))
# [5.12.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.12.0-dev.5...v5.12.0-dev.6) (2025-02-16)
### Bug Fixes
* Allow changing default settings for existing app installs ([#4464](https://github.com/ReVanced/revanced-patches/issues/4464)) ([1bd7986](https://github.com/ReVanced/revanced-patches/commit/1bd7986823e774a929c8a9102a7cc96e245d5274))
# [5.12.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.12.0-dev.4...v5.12.0-dev.5) (2025-02-13)
### Bug Fixes
* **YouTube:** Remove obsolete 18.x targets ([#4454](https://github.com/ReVanced/revanced-patches/issues/4454)) ([a006758](https://github.com/ReVanced/revanced-patches/commit/a0067581d0f877e1b4eb1f888a25786f09676b2e))
# [5.12.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.12.0-dev.3...v5.12.0-dev.4) (2025-02-11) # [5.12.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.12.0-dev.3...v5.12.0-dev.4) (2025-02-11)

View File

@@ -29,6 +29,6 @@ public class BaseSettings {
public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true, public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true,
"revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofiOSAvailability()); "revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofiOSAvailability());
// Client type must be last spoof setting due to cyclic references. // Client type must be last spoof setting due to cyclic references.
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client_type", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS)); public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client_type", ClientType.ANDROID_UNPLUGGED, true, parent(SPOOF_VIDEO_STREAMS));
} }

View File

@@ -47,6 +47,10 @@ public class BooleanSetting extends Setting<Boolean> {
*/ */
public static void privateSetValue(@NonNull BooleanSetting setting, @NonNull Boolean newValue) { public static void privateSetValue(@NonNull BooleanSetting setting, @NonNull Boolean newValue) {
setting.value = Objects.requireNonNull(newValue); setting.value = Objects.requireNonNull(newValue);
if (setting.isSetToDefault()) {
setting.removeFromPreferences();
}
} }
@Override @Override
@@ -65,10 +69,8 @@ public class BooleanSetting extends Setting<Boolean> {
} }
@Override @Override
public void save(@NonNull Boolean newValue) { public void saveToPreferences() {
// Must set before saving to preferences (otherwise importing fails to update UI correctly). preferences.saveBoolean(key, value);
value = Objects.requireNonNull(newValue);
preferences.saveBoolean(key, newValue);
} }
@NonNull @NonNull

View File

@@ -89,10 +89,8 @@ public class EnumSetting<T extends Enum<?>> extends Setting<T> {
} }
@Override @Override
public void save(@NonNull T newValue) { public void saveToPreferences() {
// Must set before saving to preferences (otherwise importing fails to update UI correctly). preferences.saveEnumAsString(key, value);
value = Objects.requireNonNull(newValue);
preferences.saveEnumAsString(key, newValue);
} }
@NonNull @NonNull

View File

@@ -55,10 +55,8 @@ public class FloatSetting extends Setting<Float> {
} }
@Override @Override
public void save(@NonNull Float newValue) { public void saveToPreferences() {
// Must set before saving to preferences (otherwise importing fails to update UI correctly). preferences.saveFloatString(key, value);
value = Objects.requireNonNull(newValue);
preferences.saveFloatString(key, newValue);
} }
@NonNull @NonNull

View File

@@ -55,10 +55,8 @@ public class IntegerSetting extends Setting<Integer> {
} }
@Override @Override
public void save(@NonNull Integer newValue) { public void saveToPreferences() {
// Must set before saving to preferences (otherwise importing fails to update UI correctly). preferences.saveIntegerString(key, value);
value = Objects.requireNonNull(newValue);
preferences.saveIntegerString(key, newValue);
} }
@NonNull @NonNull

View File

@@ -55,10 +55,8 @@ public class LongSetting extends Setting<Long> {
} }
@Override @Override
public void save(@NonNull Long newValue) { public void saveToPreferences() {
// Must set before saving to preferences (otherwise importing fails to update UI correctly). preferences.saveLongString(key, value);
value = Objects.requireNonNull(newValue);
preferences.saveLongString(key, newValue);
} }
@NonNull @NonNull

View File

@@ -14,7 +14,6 @@ import java.util.*;
import static app.revanced.extension.shared.StringRef.str; import static app.revanced.extension.shared.StringRef.str;
@SuppressWarnings("unused")
public abstract class Setting<T> { public abstract class Setting<T> {
/** /**
@@ -288,6 +287,13 @@ public abstract class Setting<T> {
*/ */
public static void privateSetValueFromString(@NonNull Setting<?> setting, @NonNull String newValue) { public static void privateSetValueFromString(@NonNull Setting<?> setting, @NonNull String newValue) {
setting.setValueFromString(newValue); setting.setValueFromString(newValue);
// Clear the preference value since default is used, to allow changing
// the changing the default for a future release. Without this after upgrading
// the saved value will be whatever was the default when the app was first installed.
if (setting.isSetToDefault()) {
setting.removeFromPreferences();
}
} }
/** /**
@@ -303,7 +309,33 @@ public abstract class Setting<T> {
/** /**
* Persistently saves the value. * Persistently saves the value.
*/ */
public abstract void save(@NonNull T newValue); public final void save(@NonNull T newValue) {
if (value.equals(newValue)) {
return;
}
// Must set before saving to preferences (otherwise importing fails to update UI correctly).
value = Objects.requireNonNull(newValue);
if (defaultValue.equals(newValue)) {
removeFromPreferences();
} else {
saveToPreferences();
}
}
/**
* Save {@link #value} to {@link #preferences}.
*/
protected abstract void saveToPreferences();
/**
* Remove {@link #value} from {@link #preferences}.
*/
protected final void removeFromPreferences() {
Logger.printDebug(() -> "Clearing stored preference value (reset to default): " + key);
preferences.removeKey(key);
}
@NonNull @NonNull
public abstract T get(); public abstract T get();

View File

@@ -55,10 +55,8 @@ public class StringSetting extends Setting<String> {
} }
@Override @Override
public void save(@NonNull String newValue) { public void saveToPreferences() {
// Must set before saving to preferences (otherwise importing fails to update UI correctly). preferences.saveString(key, value);
value = Objects.requireNonNull(newValue);
preferences.saveString(key, newValue);
} }
@NonNull @NonNull

View File

@@ -66,22 +66,6 @@ public enum ClientType {
true, true,
"Android Creator" "Android Creator"
), ),
ANDROID_VR(
ANDROID_VR_NO_AUTH.id,
ANDROID_VR_NO_AUTH.clientName,
ANDROID_VR_NO_AUTH.packageName,
ANDROID_VR_NO_AUTH.deviceMake,
ANDROID_VR_NO_AUTH.deviceModel,
ANDROID_VR_NO_AUTH.osName,
ANDROID_VR_NO_AUTH.osVersion,
ANDROID_VR_NO_AUTH.androidSdkVersion,
ANDROID_VR_NO_AUTH.buildId,
ANDROID_VR_NO_AUTH.cronetVersion,
ANDROID_VR_NO_AUTH.clientVersion,
ANDROID_VR_NO_AUTH.requiresAuth,
true,
"Android VR"
),
IOS_UNPLUGGED( IOS_UNPLUGGED(
33, 33,
"IOS_UNPLUGGED", "IOS_UNPLUGGED",
@@ -112,6 +96,22 @@ public enum ClientType {
forceAVC() forceAVC()
? "iOS TV Force AVC" ? "iOS TV Force AVC"
: "iOS TV" : "iOS TV"
),
ANDROID_VR_AUTH(
ANDROID_VR_NO_AUTH.id,
ANDROID_VR_NO_AUTH.clientName,
ANDROID_VR_NO_AUTH.packageName,
ANDROID_VR_NO_AUTH.deviceMake,
ANDROID_VR_NO_AUTH.deviceModel,
ANDROID_VR_NO_AUTH.osName,
ANDROID_VR_NO_AUTH.osVersion,
ANDROID_VR_NO_AUTH.androidSdkVersion,
ANDROID_VR_NO_AUTH.buildId,
ANDROID_VR_NO_AUTH.cronetVersion,
ANDROID_VR_NO_AUTH.clientVersion,
ANDROID_VR_NO_AUTH.requiresAuth,
true,
"Android VR"
); );
private static boolean forceAVC() { private static boolean forceAVC() {

View File

@@ -5,8 +5,6 @@ dependencies {
} }
android { android {
compileSdk = 33 // TODO: Update Swipe controls code to allow updating this to the latest sdk.
defaultConfig { defaultConfig {
minSdk = 26 minSdk = 26
} }

View File

@@ -1,9 +1,6 @@
package app.revanced.extension.youtube.patches; package app.revanced.extension.youtube.patches;
import android.app.Activity; import android.app.Activity;
import android.os.Build;
import androidx.annotation.RequiresApi;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Objects; import java.util.Objects;
@@ -58,7 +55,6 @@ public class ShortsAutoplayPatch {
/** /**
* @return If the app is currently in background PiP mode. * @return If the app is currently in background PiP mode.
*/ */
@RequiresApi(api = Build.VERSION_CODES.N)
private static boolean isAppInBackgroundPiPMode() { private static boolean isAppInBackgroundPiPMode() {
Activity activity = mainActivityRef.get(); Activity activity = mainActivityRef.get();
return activity != null && activity.isInPictureInPictureMode(); return activity != null && activity.isInPictureInPictureMode();
@@ -80,7 +76,6 @@ public class ShortsAutoplayPatch {
/** /**
* Injection point. * Injection point.
*/ */
@RequiresApi(api = Build.VERSION_CODES.N)
public static Enum<?> changeShortsRepeatBehavior(Enum<?> original) { public static Enum<?> changeShortsRepeatBehavior(Enum<?> original) {
try { try {
final boolean autoplay; final boolean autoplay;

View File

@@ -7,13 +7,10 @@ import static app.revanced.extension.youtube.patches.announcements.requests.Anno
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.os.Build;
import android.text.Html; import android.text.Html;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.RequiresApi;
import org.json.JSONArray; import org.json.JSONArray;
import java.io.IOException; import java.io.IOException;
@@ -31,7 +28,6 @@ public final class AnnouncementsPatch {
private AnnouncementsPatch() { private AnnouncementsPatch() {
} }
@RequiresApi(api = Build.VERSION_CODES.O)
private static boolean isLatestAlready() throws IOException { private static boolean isLatestAlready() throws IOException {
HttpURLConnection connection = HttpURLConnection connection =
AnnouncementsRoutes.getAnnouncementsConnectionFromRoute(GET_LATEST_ANNOUNCEMENT_IDS); AnnouncementsRoutes.getAnnouncementsConnectionFromRoute(GET_LATEST_ANNOUNCEMENT_IDS);
@@ -70,7 +66,6 @@ public final class AnnouncementsPatch {
return Settings.ANNOUNCEMENT_LAST_ID.get() == id; return Settings.ANNOUNCEMENT_LAST_ID.get() == id;
} }
@RequiresApi(api = Build.VERSION_CODES.O)
public static void showAnnouncement(final Activity context) { public static void showAnnouncement(final Activity context) {
if (!Settings.ANNOUNCEMENTS.get()) return; if (!Settings.ANNOUNCEMENTS.get()) return;

View File

@@ -6,8 +6,12 @@ import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused") @SuppressWarnings("unused")
final class ButtonsFilter extends Filter { final class ButtonsFilter extends Filter {
private static final String COMPACT_CHANNEL_BAR_PATH_PREFIX = "compact_channel_bar.eml";
private static final String VIDEO_ACTION_BAR_PATH_PREFIX = "video_action_bar.eml";
private static final String VIDEO_ACTION_BAR_PATH = "video_action_bar.eml"; private static final String VIDEO_ACTION_BAR_PATH = "video_action_bar.eml";
private static final String ANIMATED_VECTOR_TYPE_PATH = "AnimatedVectorType";
private final StringFilterGroup likeSubscribeGlow;
private final StringFilterGroup actionBarGroup; private final StringFilterGroup actionBarGroup;
private final StringFilterGroup bufferFilterPathGroup; private final StringFilterGroup bufferFilterPathGroup;
private final ByteArrayFilterGroupList bufferButtonsGroupList = new ByteArrayFilterGroupList(); private final ByteArrayFilterGroupList bufferButtonsGroupList = new ByteArrayFilterGroupList();
@@ -20,11 +24,19 @@ final class ButtonsFilter extends Filter {
addIdentifierCallbacks(actionBarGroup); addIdentifierCallbacks(actionBarGroup);
likeSubscribeGlow = new StringFilterGroup(
Settings.DISABLE_LIKE_SUBSCRIBE_GLOW,
"animated_button_border.eml"
);
bufferFilterPathGroup = new StringFilterGroup( bufferFilterPathGroup = new StringFilterGroup(
null, null,
"|ContainerType|button.eml|" "|ContainerType|button.eml|"
); );
addPathCallbacks( addPathCallbacks(
likeSubscribeGlow,
bufferFilterPathGroup,
new StringFilterGroup( new StringFilterGroup(
Settings.HIDE_LIKE_DISLIKE_BUTTON, Settings.HIDE_LIKE_DISLIKE_BUTTON,
"|segmented_like_dislike_button" "|segmented_like_dislike_button"
@@ -40,8 +52,7 @@ final class ButtonsFilter extends Filter {
new StringFilterGroup( new StringFilterGroup(
Settings.HIDE_CLIP_BUTTON, Settings.HIDE_CLIP_BUTTON,
"|clip_button.eml|" "|clip_button.eml|"
), )
bufferFilterPathGroup
); );
bufferButtonsGroupList.addAll( bufferButtonsGroupList.addAll(
@@ -83,6 +94,15 @@ final class ButtonsFilter extends Filter {
@Override @Override
boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray, boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) { StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
if (matchedGroup == likeSubscribeGlow) {
if ((path.startsWith(VIDEO_ACTION_BAR_PATH_PREFIX) || path.startsWith(COMPACT_CHANNEL_BAR_PATH_PREFIX))
&& path.contains(ANIMATED_VECTOR_TYPE_PATH)) {
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
}
return false;
}
// If the current matched group is the action bar group, // If the current matched group is the action bar group,
// in case every filter group is enabled, hide the action bar. // in case every filter group is enabled, hide the action bar.
if (matchedGroup == actionBarGroup) { if (matchedGroup == actionBarGroup) {

View File

@@ -1,9 +1,6 @@
package app.revanced.extension.youtube.patches.components; package app.revanced.extension.youtube.patches.components;
import android.os.Build;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import java.util.*; import java.util.*;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -44,13 +41,11 @@ abstract class FilterGroupList<V, T extends FilterGroup<V>> implements Iterable<
return filterGroups.iterator(); return filterGroups.iterator();
} }
@RequiresApi(api = Build.VERSION_CODES.N)
@Override @Override
public void forEach(@NonNull Consumer<? super T> action) { public void forEach(@NonNull Consumer<? super T> action) {
filterGroups.forEach(action); filterGroups.forEach(action);
} }
@RequiresApi(api = Build.VERSION_CODES.N)
@NonNull @NonNull
@Override @Override
public Spliterator<T> spliterator() { public Spliterator<T> spliterator() {

View File

@@ -4,11 +4,8 @@ import static app.revanced.extension.shared.StringRef.str;
import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton; import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton;
import static java.lang.Character.UnicodeBlock.*; import static java.lang.Character.UnicodeBlock.*;
import android.os.Build;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@@ -44,7 +41,6 @@ import app.revanced.extension.youtube.shared.PlayerType;
* - When using whole word syntax, some keywords may need additional pluralized variations. * - When using whole word syntax, some keywords may need additional pluralized variations.
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
@RequiresApi(api = Build.VERSION_CODES.N)
final class KeywordContentFilter extends Filter { final class KeywordContentFilter extends Filter {
/** /**

View File

@@ -3,11 +3,9 @@ package app.revanced.extension.youtube.patches.components;
import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton; import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.View; import android.view.View;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
@@ -18,10 +16,6 @@ import app.revanced.extension.youtube.shared.PlayerType;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class LayoutComponentsFilter extends Filter { public final class LayoutComponentsFilter extends Filter {
private static final String COMPACT_CHANNEL_BAR_PATH_PREFIX = "compact_channel_bar.eml";
private static final String VIDEO_ACTION_BAR_PATH_PREFIX = "video_action_bar.eml";
private static final String ANIMATED_VECTOR_TYPE_PATH = "AnimatedVectorType";
private static final StringTrieSearch mixPlaylistsExceptions = new StringTrieSearch( private static final StringTrieSearch mixPlaylistsExceptions = new StringTrieSearch(
"V.ED", // Playlist browse id. "V.ED", // Playlist browse id.
"java.lang.ref.WeakReference" "java.lang.ref.WeakReference"
@@ -38,16 +32,15 @@ public final class LayoutComponentsFilter extends Filter {
private final StringTrieSearch exceptions = new StringTrieSearch(); private final StringTrieSearch exceptions = new StringTrieSearch();
private final StringFilterGroup inFeedSurvey; private final StringFilterGroup inFeedSurvey;
private final StringFilterGroup notifyMe; private final StringFilterGroup notifyMe;
private final StringFilterGroup singleItemInformationPanel;
private final StringFilterGroup expandableMetadata; private final StringFilterGroup expandableMetadata;
private final ByteArrayFilterGroup searchResultRecommendations; private final ByteArrayFilterGroup searchResultRecommendations;
private final StringFilterGroup searchResultVideo; private final StringFilterGroup searchResultVideo;
private final StringFilterGroup compactChannelBarInner; private final StringFilterGroup compactChannelBarInner;
private final StringFilterGroup compactChannelBarInnerButton; private final StringFilterGroup compactChannelBarInnerButton;
private final ByteArrayFilterGroup joinMembershipButton; private final ByteArrayFilterGroup joinMembershipButton;
private final StringFilterGroup likeSubscribeGlow;
private final StringFilterGroup horizontalShelves; private final StringFilterGroup horizontalShelves;
@RequiresApi(api = Build.VERSION_CODES.N)
public LayoutComponentsFilter() { public LayoutComponentsFilter() {
exceptions.addPatterns( exceptions.addPatterns(
"home_video_with_context", "home_video_with_context",
@@ -123,8 +116,12 @@ public final class LayoutComponentsFilter extends Filter {
); );
final var infoPanel = new StringFilterGroup( final var infoPanel = new StringFilterGroup(
Settings.HIDE_HIDE_INFO_PANELS, Settings.HIDE_INFO_PANELS,
"publisher_transparency_panel", "publisher_transparency_panel"
);
singleItemInformationPanel = new StringFilterGroup(
Settings.HIDE_INFO_PANELS,
"single_item_information_panel" "single_item_information_panel"
); );
@@ -217,10 +214,6 @@ public final class LayoutComponentsFilter extends Filter {
"sponsorships" "sponsorships"
); );
likeSubscribeGlow = new StringFilterGroup(
Settings.DISABLE_LIKE_SUBSCRIBE_GLOW,
"animated_button_border.eml"
);
final var channelWatermark = new StringFilterGroup( final var channelWatermark = new StringFilterGroup(
Settings.HIDE_VIDEO_CHANNEL_WATERMARK, Settings.HIDE_VIDEO_CHANNEL_WATERMARK,
@@ -254,7 +247,6 @@ public final class LayoutComponentsFilter extends Filter {
expandableMetadata, expandableMetadata,
inFeedSurvey, inFeedSurvey,
notifyMe, notifyMe,
likeSubscribeGlow,
compactChannelBar, compactChannelBar,
communityPosts, communityPosts,
paidPromotion, paidPromotion,
@@ -269,6 +261,7 @@ public final class LayoutComponentsFilter extends Filter {
compactChannelBarInner, compactChannelBarInner,
medicalPanel, medicalPanel,
infoPanel, infoPanel,
singleItemInformationPanel,
emergencyBox, emergencyBox,
subscribersCommunityGuidelines, subscribersCommunityGuidelines,
channelGuidelines, channelGuidelines,
@@ -285,6 +278,19 @@ public final class LayoutComponentsFilter extends Filter {
@Override @Override
boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray, boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) { StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
// This identifier is used not only in players but also in search results:
// https://github.com/ReVanced/revanced-patches/issues/3245
// Until 2024, medical information panels such as Covid 19 also used this identifier and were shown in the search results.
// From 2025, the medical information panel is no longer shown in the search results.
// Therefore, this identifier does not filter when the search bar is activated.
if (matchedGroup == singleItemInformationPanel) {
if (PlayerType.getCurrent().isMaximizedOrFullscreen() || !NavigationBar.isSearchBarActive()) {
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
}
return false;
}
if (matchedGroup == searchResultVideo) { if (matchedGroup == searchResultVideo) {
if (searchResultRecommendations.check(protobufBufferArray).isFiltered()) { if (searchResultRecommendations.check(protobufBufferArray).isFiltered()) {
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex); return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
@@ -292,15 +298,6 @@ public final class LayoutComponentsFilter extends Filter {
return false; return false;
} }
if (matchedGroup == likeSubscribeGlow) {
if ((path.startsWith(VIDEO_ACTION_BAR_PATH_PREFIX) || path.startsWith(COMPACT_CHANNEL_BAR_PATH_PREFIX))
&& path.contains(ANIMATED_VECTOR_TYPE_PATH)) {
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
}
return false;
}
// The groups are excluded from the filter due to the exceptions list below. // The groups are excluded from the filter due to the exceptions list below.
// Filter them separately here. // Filter them separately here.
if (matchedGroup == notifyMe || matchedGroup == inFeedSurvey || matchedGroup == expandableMetadata) if (matchedGroup == notifyMe || matchedGroup == inFeedSurvey || matchedGroup == expandableMetadata)

View File

@@ -1,9 +1,6 @@
package app.revanced.extension.youtube.patches.components; package app.revanced.extension.youtube.patches.components;
import android.os.Build;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.PlayerType; import app.revanced.extension.youtube.shared.PlayerType;
@@ -16,7 +13,6 @@ public class PlayerFlyoutMenuItemsFilter extends Filter {
private final ByteArrayFilterGroup exception; private final ByteArrayFilterGroup exception;
private final StringFilterGroup videoQualityMenuFooter; private final StringFilterGroup videoQualityMenuFooter;
@RequiresApi(api = Build.VERSION_CODES.N)
public PlayerFlyoutMenuItemsFilter() { public PlayerFlyoutMenuItemsFilter() {
exception = new ByteArrayFilterGroup( exception = new ByteArrayFilterGroup(
// Whitelist Quality menu item when "Hide Additional settings menu" is enabled // Whitelist Quality menu item when "Hide Additional settings menu" is enabled

View File

@@ -5,15 +5,12 @@ import static app.revanced.extension.shared.Utils.getResourceIdentifier;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.os.Build;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toolbar; import android.widget.Toolbar;
import androidx.annotation.RequiresApi;
import java.util.Objects; import java.util.Objects;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
@@ -79,7 +76,6 @@ public class LicenseActivityHook {
* <p> * <p>
* Hooks LicenseActivity#onCreate in order to inject our own fragment. * Hooks LicenseActivity#onCreate in order to inject our own fragment.
*/ */
@RequiresApi(api = Build.VERSION_CODES.N)
public static void initialize(Activity licenseActivity) { public static void initialize(Activity licenseActivity) {
try { try {
ThemeHelper.setActivityTheme(licenseActivity); ThemeHelper.setActivityTheme(licenseActivity);
@@ -119,7 +115,6 @@ public class LicenseActivityHook {
} }
} }
@RequiresApi(api = Build.VERSION_CODES.N)
@SuppressLint("UseCompatLoadingForDrawables") @SuppressLint("UseCompatLoadingForDrawables")
private static void createToolbar(Activity activity, String toolbarTitleResourceName) { private static void createToolbar(Activity activity, String toolbarTitleResourceName) {
// Replace dummy placeholder toolbar. // Replace dummy placeholder toolbar.

View File

@@ -124,7 +124,6 @@ public class Settings extends BaseSettings {
public static final BooleanSetting COPY_VIDEO_URL = new BooleanSetting("revanced_copy_video_url", FALSE); public static final BooleanSetting COPY_VIDEO_URL = new BooleanSetting("revanced_copy_video_url", FALSE);
public static final BooleanSetting COPY_VIDEO_URL_TIMESTAMP = new BooleanSetting("revanced_copy_video_url_timestamp", TRUE); public static final BooleanSetting COPY_VIDEO_URL_TIMESTAMP = new BooleanSetting("revanced_copy_video_url_timestamp", TRUE);
public static final BooleanSetting DISABLE_FULLSCREEN_AMBIENT_MODE = new BooleanSetting("revanced_disable_fullscreen_ambient_mode", TRUE, true); public static final BooleanSetting DISABLE_FULLSCREEN_AMBIENT_MODE = new BooleanSetting("revanced_disable_fullscreen_ambient_mode", TRUE, true);
public static final BooleanSetting DISABLE_LIKE_SUBSCRIBE_GLOW = new BooleanSetting("revanced_disable_like_subscribe_glow", FALSE);
public static final BooleanSetting DISABLE_ROLLING_NUMBER_ANIMATIONS = new BooleanSetting("revanced_disable_rolling_number_animations", FALSE); public static final BooleanSetting DISABLE_ROLLING_NUMBER_ANIMATIONS = new BooleanSetting("revanced_disable_rolling_number_animations", FALSE);
public static final BooleanSetting DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE, true); public static final BooleanSetting DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE, true);
public static final EnumSetting<FullscreenMode> EXIT_FULLSCREEN = new EnumSetting<>("revanced_exit_fullscreen", FullscreenMode.DISABLED); public static final EnumSetting<FullscreenMode> EXIT_FULLSCREEN = new EnumSetting<>("revanced_exit_fullscreen", FullscreenMode.DISABLED);
@@ -137,7 +136,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_EMERGENCY_BOX = new BooleanSetting("revanced_hide_emergency_box", TRUE); public static final BooleanSetting HIDE_EMERGENCY_BOX = new BooleanSetting("revanced_hide_emergency_box", TRUE);
public static final BooleanSetting HIDE_ENDSCREEN_CARDS = new BooleanSetting("revanced_hide_endscreen_cards", FALSE); public static final BooleanSetting HIDE_ENDSCREEN_CARDS = new BooleanSetting("revanced_hide_endscreen_cards", FALSE);
public static final BooleanSetting HIDE_HIDE_CHANNEL_GUIDELINES = new BooleanSetting("revanced_hide_channel_guidelines", TRUE); public static final BooleanSetting HIDE_HIDE_CHANNEL_GUIDELINES = new BooleanSetting("revanced_hide_channel_guidelines", TRUE);
public static final BooleanSetting HIDE_HIDE_INFO_PANELS = new BooleanSetting("revanced_hide_info_panels", TRUE); public static final BooleanSetting HIDE_INFO_PANELS = new BooleanSetting("revanced_hide_info_panels", TRUE);
public static final BooleanSetting HIDE_INFO_CARDS = new BooleanSetting("revanced_hide_info_cards", FALSE); public static final BooleanSetting HIDE_INFO_CARDS = new BooleanSetting("revanced_hide_info_cards", FALSE);
public static final BooleanSetting HIDE_JOIN_MEMBERSHIP_BUTTON = new BooleanSetting("revanced_hide_join_membership_button", TRUE); public static final BooleanSetting HIDE_JOIN_MEMBERSHIP_BUTTON = new BooleanSetting("revanced_hide_join_membership_button", TRUE);
public static final BooleanSetting HIDE_MEDICAL_PANELS = new BooleanSetting("revanced_hide_medical_panels", TRUE); public static final BooleanSetting HIDE_MEDICAL_PANELS = new BooleanSetting("revanced_hide_medical_panels", TRUE);
@@ -185,6 +184,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_PODCAST_SECTION = new BooleanSetting("revanced_hide_podcast_section", TRUE); public static final BooleanSetting HIDE_PODCAST_SECTION = new BooleanSetting("revanced_hide_podcast_section", TRUE);
public static final BooleanSetting HIDE_TRANSCRIPT_SECTION = new BooleanSetting("revanced_hide_transcript_section", TRUE); public static final BooleanSetting HIDE_TRANSCRIPT_SECTION = new BooleanSetting("revanced_hide_transcript_section", TRUE);
// Action buttons // Action buttons
public static final BooleanSetting DISABLE_LIKE_SUBSCRIBE_GLOW = new BooleanSetting("revanced_disable_like_subscribe_glow", FALSE);
public static final BooleanSetting HIDE_CLIP_BUTTON = new BooleanSetting("revanced_hide_clip_button", TRUE); public static final BooleanSetting HIDE_CLIP_BUTTON = new BooleanSetting("revanced_hide_clip_button", TRUE);
public static final BooleanSetting HIDE_DOWNLOAD_BUTTON = new BooleanSetting("revanced_hide_download_button", FALSE); public static final BooleanSetting HIDE_DOWNLOAD_BUTTON = new BooleanSetting("revanced_hide_download_button", FALSE);
public static final BooleanSetting HIDE_LIKE_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_like_dislike_button", FALSE); public static final BooleanSetting HIDE_LIKE_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_like_dislike_button", FALSE);
@@ -306,21 +306,21 @@ public class Settings extends BaseSettings {
// Swipe controls // Swipe controls
public static final BooleanSetting SWIPE_CHANGE_VIDEO = new BooleanSetting("revanced_swipe_change_video", FALSE, true); public static final BooleanSetting SWIPE_CHANGE_VIDEO = new BooleanSetting("revanced_swipe_change_video", FALSE, true);
public static final BooleanSetting SWIPE_BRIGHTNESS = new BooleanSetting("revanced_swipe_brightness", FALSE); public static final BooleanSetting SWIPE_BRIGHTNESS = new BooleanSetting("revanced_swipe_brightness", FALSE, true);
public static final BooleanSetting SWIPE_VOLUME = new BooleanSetting("revanced_swipe_volume", FALSE); public static final BooleanSetting SWIPE_VOLUME = new BooleanSetting("revanced_swipe_volume", FALSE, true);
public static final BooleanSetting SWIPE_PRESS_TO_ENGAGE = new BooleanSetting("revanced_swipe_press_to_engage", FALSE, true, public static final BooleanSetting SWIPE_PRESS_TO_ENGAGE = new BooleanSetting("revanced_swipe_press_to_engage", FALSE, true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final BooleanSetting SWIPE_HAPTIC_FEEDBACK = new BooleanSetting("revanced_swipe_haptic_feedback", TRUE, true, public static final BooleanSetting SWIPE_HAPTIC_FEEDBACK = new BooleanSetting("revanced_swipe_haptic_feedback", TRUE, true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final IntegerSetting SWIPE_MAGNITUDE_THRESHOLD = new IntegerSetting("revanced_swipe_threshold", 30, true, public static final IntegerSetting SWIPE_MAGNITUDE_THRESHOLD = new IntegerSetting("revanced_swipe_threshold", 30, true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final IntegerSetting SWIPE_OVERLAY_OPACITY = new IntegerSetting("revanced_swipe_overlay_background_opacity", 50, true, public static final BooleanSetting SWIPE_SHOW_CIRCULAR_OVERLAY = new BooleanSetting("revanced_swipe_show_circular_overlay", FALSE, true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final BooleanSetting SWIPE_OVERLAY_MINIMAL_STYLE = new BooleanSetting("revanced_swipe_overlay_minimal_style", FALSE, true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final IntegerSetting SWIPE_OVERLAY_OPACITY = new IntegerSetting("revanced_swipe_overlay_background_opacity", 60, true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
private static final IntegerSetting DEPRECATED_SWIPE_OVERLAY_BACKGROUND_ALPHA = new IntegerSetting("revanced_swipe_overlay_background_alpha", 127); private static final IntegerSetting DEPRECATED_SWIPE_OVERLAY_BACKGROUND_ALPHA = new IntegerSetting("revanced_swipe_overlay_background_alpha", 127);
// Debugging
public static final IntegerSetting SWIPE_OVERLAY_TEXT_SIZE = new IntegerSetting("revanced_swipe_text_overlay_size", 22, true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final LongSetting SWIPE_OVERLAY_TIMEOUT = new LongSetting("revanced_swipe_overlay_timeout", 500L, true, public static final LongSetting SWIPE_OVERLAY_TIMEOUT = new LongSetting("revanced_swipe_overlay_timeout", 500L, true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final BooleanSetting SWIPE_SAVE_AND_RESTORE_BRIGHTNESS = new BooleanSetting("revanced_swipe_save_and_restore_brightness", TRUE, true, parent(SWIPE_BRIGHTNESS)); public static final BooleanSetting SWIPE_SAVE_AND_RESTORE_BRIGHTNESS = new BooleanSetting("revanced_swipe_save_and_restore_brightness", TRUE, true, parent(SWIPE_BRIGHTNESS));

View File

@@ -3,18 +3,14 @@ package app.revanced.extension.youtube.settings.preference;
import static android.text.Html.FROM_HTML_MODE_COMPACT; import static android.text.Html.FROM_HTML_MODE_COMPACT;
import android.content.Context; import android.content.Context;
import android.os.Build;
import android.preference.Preference; import android.preference.Preference;
import android.text.Html; import android.text.Html;
import android.util.AttributeSet; import android.util.AttributeSet;
import androidx.annotation.RequiresApi;
/** /**
* Allows using basic html for the summary text. * Allows using basic html for the summary text.
*/ */
@SuppressWarnings({"unused", "deprecation"}) @SuppressWarnings({"unused", "deprecation"})
@RequiresApi(api = Build.VERSION_CODES.O)
public class HtmlPreference extends Preference { public class HtmlPreference extends Preference {
{ {
setSummary(Html.fromHtml(getSummary().toString(), FROM_HTML_MODE_COMPACT)); setSummary(Html.fromHtml(getSummary().toString(), FROM_HTML_MODE_COMPACT));

View File

@@ -17,8 +17,6 @@ import android.view.WindowInsets;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toolbar; import android.widget.Toolbar;
import androidx.annotation.RequiresApi;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -98,7 +96,6 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment {
listPreference.setEntryValues(sortedEntryValues); listPreference.setEntryValues(sortedEntryValues);
} }
@RequiresApi(api = Build.VERSION_CODES.O)
@Override @Override
protected void initialize() { protected void initialize() {
super.initialize(); super.initialize();

View File

@@ -85,7 +85,7 @@ public class SpoofStreamingDataSideEffectsPreference extends Preference {
String summary = str(key + "_summary"); String summary = str(key + "_summary");
// Android VR supports AV1 but all other clients do not. // Android VR supports AV1 but all other clients do not.
if (clientType != ClientType.ANDROID_VR && clientType != ClientType.ANDROID_VR_NO_AUTH) { if (clientType != ClientType.ANDROID_VR_AUTH && clientType != ClientType.ANDROID_VR_NO_AUTH) {
summary += '\n' + str("revanced_spoof_video_streams_about_no_av1"); summary += '\n' + str("revanced_spoof_video_streams_about_no_av1");
} }

View File

@@ -3,11 +3,9 @@ package app.revanced.extension.youtube.shared;
import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton.CREATE; import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton.CREATE;
import android.app.Activity; import android.app.Activity;
import android.os.Build;
import android.view.View; import android.view.View;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Arrays; import java.util.Arrays;
@@ -257,7 +255,6 @@ public final class NavigationBar {
* Injection point. * Injection point.
* Fixes missing drawable. * Fixes missing drawable.
*/ */
@RequiresApi(api = Build.VERSION_CODES.N)
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings({"unchecked", "rawtypes"})
public static void setCairoNotificationFilledIcon(EnumMap enumMap, Enum tabActivityCairo) { public static void setCairoNotificationFilledIcon(EnumMap enumMap, Enum tabActivityCairo) {
if (fillBellCairoBlack != 0) { if (fillBellCairoBlack != 0) {

View File

@@ -20,19 +20,17 @@ class SwipeControlsConfigurationProvider(
* should swipe controls be enabled? (global setting) * should swipe controls be enabled? (global setting)
*/ */
val enableSwipeControls: Boolean val enableSwipeControls: Boolean
get() = isFullscreenVideo && (enableVolumeControls || enableBrightnessControl) get() = (enableVolumeControls || enableBrightnessControl) && isFullscreenVideo
/** /**
* should swipe controls for volume be enabled? * should swipe controls for volume be enabled?
*/ */
val enableVolumeControls: Boolean val enableVolumeControls = Settings.SWIPE_VOLUME.get()
get() = Settings.SWIPE_VOLUME.get()
/** /**
* should swipe controls for volume be enabled? * should swipe controls for volume be enabled?
*/ */
val enableBrightnessControl: Boolean val enableBrightnessControl = Settings.SWIPE_BRIGHTNESS.get()
get() = Settings.SWIPE_BRIGHTNESS.get()
/** /**
* is the video player currently in fullscreen mode? * is the video player currently in fullscreen mode?
@@ -46,7 +44,7 @@ class SwipeControlsConfigurationProvider(
* should volume key controls be overwritten? (global setting) * should volume key controls be overwritten? (global setting)
*/ */
val overwriteVolumeKeyControls: Boolean val overwriteVolumeKeyControls: Boolean
get() = isFullscreenVideo && enableVolumeControls get() = enableVolumeControls && isFullscreenVideo
//endregion //endregion
//region gesture adjustments //region gesture adjustments
@@ -65,7 +63,6 @@ class SwipeControlsConfigurationProvider(
//endregion //endregion
//region overlay adjustments //region overlay adjustments
/** /**
* should the overlay enable haptic feedback? * should the overlay enable haptic feedback?
*/ */
@@ -79,15 +76,10 @@ class SwipeControlsConfigurationProvider(
get() = Settings.SWIPE_OVERLAY_TIMEOUT.get() get() = Settings.SWIPE_OVERLAY_TIMEOUT.get()
/** /**
* text size for the overlay, in sp * Gets the opacity value (0-100%) is converted to an alpha value (0-255) for transparency.
* If the opacity value is out of range, it resets to the default and displays a warning message.
*/ */
val overlayTextSize: Int val overlayBackgroundOpacity: Int
get() = Settings.SWIPE_OVERLAY_TEXT_SIZE.get()
/**
* get the background color for text on the overlay, as a color int
*/
val overlayTextBackgroundColor: Int
get() { get() {
var opacity = Settings.SWIPE_OVERLAY_OPACITY.get() var opacity = Settings.SWIPE_OVERLAY_OPACITY.get()
@@ -102,11 +94,34 @@ class SwipeControlsConfigurationProvider(
} }
/** /**
* get the foreground color for text on the overlay, as a color int * The color of the progress overlay.
*/ */
val overlayForegroundColor: Int val overlayProgressColor: Int
get() = 0xBFFFFFFF.toInt()
/**
* The color used for the background of the progress overlay fill.
*/
val overlayFillBackgroundPaint: Int
get() = 0x80D3D3D3.toInt()
/**
* The color used for the text and icons in the overlay.
*/
val overlayTextColor: Int
get() = Color.WHITE get() = Color.WHITE
/**
* A flag that determines if the overlay should only show the icon.
*/
val overlayShowOverlayMinimalStyle: Boolean
get() = Settings.SWIPE_OVERLAY_MINIMAL_STYLE.get()
/**
* A flag that determines if the progress bar should be circular.
*/
val isCircularProgressBar: Boolean
get() = Settings.SWIPE_SHOW_CIRCULAR_OVERLAY.get()
//endregion //endregion
//region behaviour //region behaviour

View File

@@ -82,11 +82,15 @@ abstract class BaseGestureController(
} }
override fun onScroll( override fun onScroll(
from: MotionEvent, from: MotionEvent?,
to: MotionEvent, to: MotionEvent,
distanceX: Float, distanceX: Float,
distanceY: Float, distanceY: Float,
): Boolean { ): Boolean {
if (from == null) {
return false
}
// submit to swipe detector // submit to swipe detector
submitForSwipe(from, to, distanceX, distanceY) submitForSwipe(from, to, distanceX, distanceY)

View File

@@ -1,138 +1,145 @@
package app.revanced.extension.youtube.swipecontrols.views package app.revanced.extension.youtube.swipecontrols.views
import android.content.Context import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.TypedValue import android.util.AttributeSet
import android.view.HapticFeedbackConstants import android.view.HapticFeedbackConstants
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout import android.widget.RelativeLayout
import android.widget.TextView
import app.revanced.extension.shared.StringRef.str
import app.revanced.extension.shared.Utils import app.revanced.extension.shared.Utils
import app.revanced.extension.youtube.swipecontrols.SwipeControlsConfigurationProvider import app.revanced.extension.youtube.swipecontrols.SwipeControlsConfigurationProvider
import app.revanced.extension.youtube.swipecontrols.misc.SwipeControlsOverlay import app.revanced.extension.youtube.swipecontrols.misc.SwipeControlsOverlay
import app.revanced.extension.youtube.swipecontrols.misc.applyDimension import kotlin.math.min
import kotlin.math.round import kotlin.math.round
/** /**
* main overlay layout for volume and brightness swipe controls * Main overlay layout for displaying volume and brightness level with both circular and rectangular progress bars.
*
* @param context context to create in
*/ */
class SwipeControlsOverlayLayout( class SwipeControlsOverlayLayout(
context: Context, context: Context,
private val config: SwipeControlsConfigurationProvider, private val config: SwipeControlsConfigurationProvider,
) : RelativeLayout(context), SwipeControlsOverlay { ) : RelativeLayout(context), SwipeControlsOverlay {
/**
* DO NOT use this, for tools only
*/
constructor(context: Context) : this(context, SwipeControlsConfigurationProvider(context)) constructor(context: Context) : this(context, SwipeControlsConfigurationProvider(context))
private val feedbackTextView: TextView // Drawable icons for brightness and volume
private val autoBrightnessIcon: Drawable private val autoBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_auto")
private val manualBrightnessIcon: Drawable private val lowBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_low")
private val mutedVolumeIcon: Drawable private val mediumBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_medium")
private val normalVolumeIcon: Drawable private val highBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_high")
private val fullBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_full")
private val mutedVolumeIcon: Drawable = getDrawable("revanced_ic_sc_volume_mute")
private val lowVolumeIcon: Drawable = getDrawable("revanced_ic_sc_volume_low")
private val normalVolumeIcon: Drawable = getDrawable("revanced_ic_sc_volume_normal")
private val fullVolumeIcon: Drawable = getDrawable("revanced_ic_sc_volume_high")
private fun getDrawable(name: String, width: Int, height: Int): Drawable { // Function to retrieve drawable resources by name
return resources.getDrawable( private fun getDrawable(name: String): Drawable {
val drawable = resources.getDrawable(
Utils.getResourceIdentifier(context, name, "drawable"), Utils.getResourceIdentifier(context, name, "drawable"),
context.theme, context.theme,
).apply { )
setTint(config.overlayForegroundColor) drawable.setTint(config.overlayTextColor)
setBounds( return drawable
0,
0,
width,
height,
)
}
} }
// Initialize progress bars
private val circularProgressView: CircularProgressView
private val horizontalProgressView: HorizontalProgressView
init { init {
// init views // Initialize circular progress bar
val feedbackTextViewPadding = 2.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP) circularProgressView = CircularProgressView(
val compoundIconPadding = 4.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP) context,
feedbackTextView = TextView(context).apply { config.overlayBackgroundOpacity,
layoutParams = LayoutParams( config.overlayShowOverlayMinimalStyle,
LayoutParams.WRAP_CONTENT, config.overlayProgressColor,
LayoutParams.WRAP_CONTENT, config.overlayFillBackgroundPaint,
).apply { config.overlayTextColor
).apply {
layoutParams = LayoutParams(300, 300).apply {
addRule(CENTER_IN_PARENT, TRUE) addRule(CENTER_IN_PARENT, TRUE)
setPadding(
feedbackTextViewPadding,
feedbackTextViewPadding,
feedbackTextViewPadding,
feedbackTextViewPadding,
)
} }
background = GradientDrawable().apply { visibility = GONE // Initially hidden
cornerRadius = 8f
setColor(config.overlayTextBackgroundColor)
}
setTextColor(config.overlayForegroundColor)
setTextSize(TypedValue.COMPLEX_UNIT_SP, config.overlayTextSize.toFloat())
compoundDrawablePadding = compoundIconPadding
visibility = GONE
} }
addView(feedbackTextView) addView(circularProgressView)
// get icons scaled, assuming square icons // Initialize rectangular progress bar
val iconHeight = round(feedbackTextView.lineHeight * .8).toInt() val screenWidth = resources.displayMetrics.widthPixels
autoBrightnessIcon = getDrawable("revanced_ic_sc_brightness_auto", iconHeight, iconHeight) val layoutWidth = (screenWidth * 2 / 3).toInt() // 2/3 of screen width
manualBrightnessIcon = getDrawable("revanced_ic_sc_brightness_manual", iconHeight, iconHeight) horizontalProgressView = HorizontalProgressView(
mutedVolumeIcon = getDrawable("revanced_ic_sc_volume_mute", iconHeight, iconHeight) context,
normalVolumeIcon = getDrawable("revanced_ic_sc_volume_normal", iconHeight, iconHeight) config.overlayBackgroundOpacity,
config.overlayShowOverlayMinimalStyle,
config.overlayProgressColor,
config.overlayFillBackgroundPaint,
config.overlayTextColor
).apply {
layoutParams = LayoutParams(layoutWidth, 100).apply {
addRule(CENTER_HORIZONTAL)
topMargin = 40 // Top margin
}
visibility = GONE // Initially hidden
}
addView(horizontalProgressView)
} }
// Handler and callback for hiding progress bars
private val feedbackHideHandler = Handler(Looper.getMainLooper()) private val feedbackHideHandler = Handler(Looper.getMainLooper())
private val feedbackHideCallback = Runnable { private val feedbackHideCallback = Runnable {
feedbackTextView.visibility = GONE circularProgressView.visibility = GONE
horizontalProgressView.visibility = GONE
} }
/** /**
* show the feedback view for a given time * Displays the progress bar with the appropriate value, icon, and type (brightness or volume).
*
* @param message the message to show
* @param icon the icon to use
*/ */
private fun showFeedbackView(message: String, icon: Drawable) { private fun showFeedbackView(value: String, progress: Int, max: Int, icon: Drawable, isBrightness: Boolean) {
feedbackHideHandler.removeCallbacks(feedbackHideCallback) feedbackHideHandler.removeCallbacks(feedbackHideCallback)
feedbackHideHandler.postDelayed(feedbackHideCallback, config.overlayShowTimeoutMillis) feedbackHideHandler.postDelayed(feedbackHideCallback, config.overlayShowTimeoutMillis)
feedbackTextView.apply {
text = message val viewToShow = if (config.isCircularProgressBar) circularProgressView else horizontalProgressView
setCompoundDrawablesRelative( viewToShow.apply {
icon, setProgress(progress, max, value, isBrightness)
null, this.icon = icon
null,
null,
)
visibility = VISIBLE visibility = VISIBLE
} }
} }
// Handle volume change
override fun onVolumeChanged(newVolume: Int, maximumVolume: Int) { override fun onVolumeChanged(newVolume: Int, maximumVolume: Int) {
showFeedbackView( val volumePercentage = (newVolume.toFloat() / maximumVolume) * 100
"$newVolume", val icon = when {
if (newVolume > 0) normalVolumeIcon else mutedVolumeIcon, newVolume == 0 -> mutedVolumeIcon
) volumePercentage < 33 -> lowVolumeIcon
volumePercentage < 66 -> normalVolumeIcon
else -> fullVolumeIcon
}
showFeedbackView("$newVolume", newVolume, maximumVolume, icon, isBrightness = false)
} }
// Handle brightness change
override fun onBrightnessChanged(brightness: Double) { override fun onBrightnessChanged(brightness: Double) {
if (config.shouldLowestValueEnableAutoBrightness && brightness <= 0) { if (config.shouldLowestValueEnableAutoBrightness && brightness <= 0) {
showFeedbackView( showFeedbackView("Auto", 0, 100, autoBrightnessIcon, isBrightness = true)
str("revanced_swipe_lowest_value_enable_auto_brightness_overlay_text"), } else {
autoBrightnessIcon, val brightnessValue = round(brightness).toInt()
) val icon = when {
} else if (brightness >= 0) { brightnessValue < 25 -> lowBrightnessIcon
showFeedbackView("${round(brightness).toInt()}%", manualBrightnessIcon) brightnessValue < 50 -> mediumBrightnessIcon
brightnessValue < 75 -> highBrightnessIcon
else -> fullBrightnessIcon
}
showFeedbackView("$brightnessValue%", brightnessValue, 100, icon, isBrightness = true)
} }
} }
// Begin swipe session
override fun onEnterSwipeSession() { override fun onEnterSwipeSession() {
if (config.shouldEnableHapticFeedback) { if (config.shouldEnableHapticFeedback) {
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
@@ -143,3 +150,233 @@ class SwipeControlsOverlayLayout(
} }
} }
} }
/**
* Abstract base class for progress views to reduce code duplication.
*/
/**
* Abstract base class for progress views to reduce code duplication.
*/
abstract class AbstractProgressView(
context: Context,
protected val overlayBackgroundOpacity: Int,
protected val overlayShowOverlayMinimalStyle: Boolean,
protected val overlayProgressColor: Int,
protected val overlayFillBackgroundPaint: Int,
protected val overlayTextColor: Int,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
// Combined paint creation function for both fill and stroke styles
private fun createPaint(color: Int, style: Paint.Style = Paint.Style.FILL, strokeCap: Paint.Cap = Paint.Cap.BUTT, strokeWidth: Float = 0f) = Paint(Paint.ANTI_ALIAS_FLAG).apply {
this.style = style
this.color = color
this.strokeCap = strokeCap
this.strokeWidth = strokeWidth
}
// Initialize paints
public val backgroundPaint = createPaint(overlayBackgroundOpacity, style = Paint.Style.FILL)
public val progressPaint = createPaint(overlayProgressColor, style = Paint.Style.STROKE, strokeCap = Paint.Cap.ROUND, strokeWidth = 20f)
public val fillBackgroundPaint = createPaint(overlayFillBackgroundPaint, style = Paint.Style.FILL)
public val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = overlayTextColor
textAlign = Paint.Align.CENTER
textSize = 30f // Can adjust based on need
}
protected var progress = 0
protected var maxProgress = 100
protected var displayText: String = "0"
protected var isBrightness = true
public var icon: Drawable? = null
init {
// Stroke widths are now set in createPaint for progressPaint and fillBackgroundPaint
}
fun setProgress(value: Int, max: Int, text: String, isBrightnessMode: Boolean) {
progress = value
maxProgress = max
displayText = text
isBrightness = isBrightnessMode
invalidate()
}
override fun onDraw(canvas: Canvas) {
// Base class implementation can be empty
}
}
/**
* Custom view for rendering a circular progress indicator with text and icon.
*/
class CircularProgressView(
context: Context,
overlayBackgroundOpacity: Int,
overlayShowOverlayMinimalStyle: Boolean,
overlayProgressColor: Int,
overlayFillBackgroundPaint: Int,
overlayTextColor: Int,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : AbstractProgressView(
context,
overlayBackgroundOpacity,
overlayShowOverlayMinimalStyle,
overlayProgressColor,
overlayFillBackgroundPaint,
overlayTextColor,
attrs,
defStyleAttr
) {
private val rectF = RectF()
init {
textPaint.textSize = 40f // Override default text size for horizontal view
progressPaint.strokeWidth = 20f
fillBackgroundPaint.strokeWidth = 20f
progressPaint.strokeCap = Paint.Cap.ROUND
fillBackgroundPaint.strokeCap = Paint.Cap.BUTT
progressPaint.style = Paint.Style.STROKE
fillBackgroundPaint.style = Paint.Style.STROKE
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val size = min(width, height).toFloat()
rectF.set(20f, 20f, size - 20f, size - 20f)
canvas.drawOval(rectF, fillBackgroundPaint) // Draw the outer ring.
canvas.drawCircle(width / 2f, height / 2f, size / 3, backgroundPaint) // Draw the inner circle.
// Select the paint for drawing based on whether it's brightness or volume.
val sweepAngle = (progress.toFloat() / maxProgress) * 360
canvas.drawArc(rectF, -90f, sweepAngle, false, progressPaint) // Draw the progress arc.
// Draw the icon in the center.
icon?.let {
val iconSize = if (overlayShowOverlayMinimalStyle) 100 else 80
val iconX = (width - iconSize) / 2
val iconY = (height / 2) - if (overlayShowOverlayMinimalStyle) 50 else 80
it.setBounds(iconX, iconY, iconX + iconSize, iconY + iconSize)
it.draw(canvas)
}
// If not in icon-only mode, draw the text inside the ring.
if (!overlayShowOverlayMinimalStyle) {
canvas.drawText(displayText, width / 2f, height / 2f + 60f, textPaint)
}
}
}
/**
* Custom view for rendering a rectangular progress bar with icons and text.
*/
class HorizontalProgressView(
context: Context,
overlayBackgroundOpacity: Int,
overlayShowOverlayMinimalStyle: Boolean,
overlayProgressColor: Int,
overlayFillBackgroundPaint: Int,
overlayTextColor: Int,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : AbstractProgressView(
context,
overlayBackgroundOpacity,
overlayShowOverlayMinimalStyle,
overlayProgressColor,
overlayFillBackgroundPaint,
overlayTextColor,
attrs,
defStyleAttr
) {
private val iconSize = 60f
private val padding = 40f
init {
textPaint.textSize = 30f // Override default text size for horizontal view
progressPaint.strokeWidth = 0f
progressPaint.strokeCap = Paint.Cap.BUTT
progressPaint.style = Paint.Style.FILL
fillBackgroundPaint.style = Paint.Style.FILL
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val width = width.toFloat()
val height = height.toFloat()
// Radius for rounded corners
val cornerRadius = min(width, height) / 2
// Calculate the total width for the elements
val minimalElementWidth = 5 * padding + iconSize
// Calculate the starting point (X) to center the elements
val minimalStartX = (width - minimalElementWidth) / 2
// Draw the background
if (!overlayShowOverlayMinimalStyle) {
canvas.drawRoundRect(0f, 0f, width, height, cornerRadius, cornerRadius, backgroundPaint)
} else {
canvas.drawRoundRect(minimalStartX, 0f, minimalStartX + minimalElementWidth, height, cornerRadius, cornerRadius, backgroundPaint)
}
if (!overlayShowOverlayMinimalStyle) {
// Draw the fill background
val startX = 2 * padding + iconSize
val endX = width - 4 * padding
val fillWidth = endX - startX
canvas.drawRoundRect(
startX,
height / 2 - 5f,
endX,
height / 2 + 5f,
10f, 10f,
fillBackgroundPaint
)
// Draw the progress
val progressWidth = (progress.toFloat() / maxProgress) * fillWidth
canvas.drawRoundRect(
startX,
height / 2 - 5f,
startX + progressWidth,
height / 2 + 5f,
10f, 10f,
progressPaint
)
}
// Draw the icon
icon?.let {
val iconX = if (!overlayShowOverlayMinimalStyle) {
padding
} else {
padding + minimalStartX
}
val iconY = height / 2 - iconSize / 2
it.setBounds(iconX.toInt(), iconY.toInt(), (iconX + iconSize).toInt(), (iconY + iconSize).toInt())
it.draw(canvas)
}
// Draw the text on the right
val textX = if (!overlayShowOverlayMinimalStyle) {
width - 2 * padding
} else {
minimalStartX + minimalElementWidth - 2 * padding
}
val textY = height / 2 + textPaint.textSize / 3
// Draw the text
canvas.drawText(displayText, textX, textY, textPaint)
}
}

View File

@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
org.gradle.parallel = true org.gradle.parallel = true
android.useAndroidX = true android.useAndroidX = true
kotlin.code.style = official kotlin.code.style = official
version = 5.12.0-dev.4 version = 5.13.0-dev.2

View File

@@ -11,7 +11,7 @@ val hideVideoAdsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.apps.youtube.music"( "com.google.android.apps.youtube.music"(
"7.16.53", "7.16.53",
"8.05.50" "8.05.51"
) )
) )

View File

@@ -11,7 +11,7 @@ val enableExclusiveAudioPlaybackPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.apps.youtube.music"( "com.google.android.apps.youtube.music"(
"7.16.53", "7.16.53",
"8.05.50" "8.05.51"
) )
) )

View File

@@ -14,7 +14,7 @@ val permanentRepeatPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.apps.youtube.music"( "com.google.android.apps.youtube.music"(
"7.16.53", "7.16.53",
"8.05.50" "8.05.51"
) )
) )

View File

@@ -14,7 +14,7 @@ val hideCategoryBar = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.apps.youtube.music"( "com.google.android.apps.youtube.music"(
"7.16.53", "7.16.53",
"8.05.50" "8.05.51"
) )
) )

View File

@@ -14,7 +14,7 @@ val hideGetPremiumPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.apps.youtube.music"( "com.google.android.apps.youtube.music"(
"7.16.53", "7.16.53",
"8.05.50" "8.05.51"
) )
) )

View File

@@ -21,7 +21,7 @@ val removeUpgradeButtonPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.apps.youtube.music"( "com.google.android.apps.youtube.music"(
"7.16.53", "7.16.53",
"8.05.50" "8.05.51"
) )
) )

View File

@@ -11,7 +11,7 @@ val bypassCertificateChecksPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.apps.youtube.music"( "com.google.android.apps.youtube.music"(
"7.16.53", "7.16.53",
"8.05.50" "8.05.51"
) )
) )

View File

@@ -11,7 +11,7 @@ val backgroundPlaybackPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.apps.youtube.music"( "com.google.android.apps.youtube.music"(
"7.16.53", "7.16.53",
"8.05.50" "8.05.51"
) )
) )

View File

@@ -28,7 +28,7 @@ val spoofClientPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.apps.youtube.music"( "com.google.android.apps.youtube.music"(
"7.16.53", "7.16.53",
"8.05.50" "8.05.51"
) )
) )

View File

@@ -78,8 +78,6 @@ val hideAdsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -25,8 +25,6 @@ val hideGetPremiumPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -23,8 +23,6 @@ val videoAdsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -53,8 +53,6 @@ val copyVideoUrlPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -24,8 +24,6 @@ val removeViewerDiscretionDialogPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -68,8 +68,6 @@ val downloadsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -23,8 +23,6 @@ val disablePreciseSeekingGesturePatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -26,8 +26,6 @@ val enableSeekbarTappingPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
// 18.38.44 patches but crashes on startup.
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -35,7 +35,6 @@ val enableSlideToSeekPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -19,7 +19,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
val seekbarThumbnailsPatch = bytecodePatch( val seekbarThumbnailsPatch = bytecodePatch(
name = "Seekbar thumbnails", name = "Seekbar thumbnails",
description = "Adds an option to use high quality fullscreen seekbar thumbnails. " + description = "Adds an option to use high quality fullscreen seekbar thumbnails. " +
"Patching 19.16.39 or lower adds an option to restore old seekbar thumbnails.", "Patching 19.16.39 adds an option to restore old seekbar thumbnails.",
) { ) {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,
@@ -29,8 +29,6 @@ val seekbarThumbnailsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -42,9 +42,10 @@ private val swipeControlsResourcePatch = resourcePatch {
SwitchPreference("revanced_swipe_haptic_feedback"), SwitchPreference("revanced_swipe_haptic_feedback"),
SwitchPreference("revanced_swipe_save_and_restore_brightness"), SwitchPreference("revanced_swipe_save_and_restore_brightness"),
SwitchPreference("revanced_swipe_lowest_value_enable_auto_brightness"), SwitchPreference("revanced_swipe_lowest_value_enable_auto_brightness"),
TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER), SwitchPreference("revanced_swipe_show_circular_overlay"),
TextPreference("revanced_swipe_text_overlay_size", inputType = InputType.NUMBER), SwitchPreference("revanced_swipe_overlay_minimal_style"),
TextPreference("revanced_swipe_overlay_background_opacity", inputType = InputType.NUMBER), TextPreference("revanced_swipe_overlay_background_opacity", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_threshold", inputType = InputType.NUMBER), TextPreference("revanced_swipe_threshold", inputType = InputType.NUMBER),
) )
@@ -53,7 +54,12 @@ private val swipeControlsResourcePatch = resourcePatch {
ResourceGroup( ResourceGroup(
"drawable", "drawable",
"revanced_ic_sc_brightness_auto.xml", "revanced_ic_sc_brightness_auto.xml",
"revanced_ic_sc_brightness_manual.xml", "revanced_ic_sc_brightness_full.xml",
"revanced_ic_sc_brightness_high.xml",
"revanced_ic_sc_brightness_low.xml",
"revanced_ic_sc_brightness_medium.xml",
"revanced_ic_sc_volume_high.xml",
"revanced_ic_sc_volume_low.xml",
"revanced_ic_sc_volume_mute.xml", "revanced_ic_sc_volume_mute.xml",
"revanced_ic_sc_volume_normal.xml", "revanced_ic_sc_volume_normal.xml",
), ),
@@ -74,8 +80,6 @@ val swipeControlsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -22,8 +22,6 @@ val autoCaptionsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -43,8 +43,6 @@ val customBrandingPatch = resourcePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -41,8 +41,6 @@ val changeHeaderPatch = resourcePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -22,8 +22,6 @@ val hideButtonsPatch = resourcePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
@@ -41,6 +39,7 @@ val hideButtonsPatch = resourcePatch(
PreferenceScreenPreference( PreferenceScreenPreference(
"revanced_hide_buttons_screen", "revanced_hide_buttons_screen",
preferences = setOf( preferences = setOf(
SwitchPreference("revanced_disable_like_subscribe_glow"),
SwitchPreference("revanced_hide_like_dislike_button"), SwitchPreference("revanced_hide_like_dislike_button"),
SwitchPreference("revanced_hide_share_button"), SwitchPreference("revanced_hide_share_button"),
SwitchPreference("revanced_hide_report_button"), SwitchPreference("revanced_hide_report_button"),

View File

@@ -40,8 +40,6 @@ val navigationButtonsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -54,8 +54,6 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -30,8 +30,6 @@ val changeFormFactorPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -56,8 +56,6 @@ val hideEndscreenCardsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -29,8 +29,6 @@ val disableFullscreenAmbientModePatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -125,8 +125,6 @@ val hideLayoutComponentsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
@@ -174,7 +172,6 @@ val hideLayoutComponentsPatch = bytecodePatch(
SwitchPreference("revanced_hide_emergency_box"), SwitchPreference("revanced_hide_emergency_box"),
SwitchPreference("revanced_hide_info_panels"), SwitchPreference("revanced_hide_info_panels"),
SwitchPreference("revanced_hide_join_membership_button"), SwitchPreference("revanced_hide_join_membership_button"),
SwitchPreference("revanced_disable_like_subscribe_glow"),
SwitchPreference("revanced_hide_medical_panels"), SwitchPreference("revanced_hide_medical_panels"),
SwitchPreference("revanced_hide_quick_actions"), SwitchPreference("revanced_hide_quick_actions"),
SwitchPreference("revanced_hide_related_videos"), SwitchPreference("revanced_hide_related_videos"),

View File

@@ -57,8 +57,6 @@ val hideInfoCardsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -24,8 +24,6 @@ val hidePlayerFlyoutMenuPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -29,8 +29,6 @@ val disableRollingNumberAnimationPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
// 18.43 is the earliest target this patch works.
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -25,8 +25,6 @@ val hideSeekbarPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -30,12 +30,6 @@ internal val createShortsButtonsFingerprint = fingerprint {
literal { reelPlayerRightCellButtonHeight } literal { reelPlayerRightCellButtonHeight }
} }
internal val reelConstructorFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
opcodes(Opcode.INVOKE_VIRTUAL)
literal { reelMultipleItemShelfId }
}
internal val renderBottomNavigationBarFingerprint = fingerprint { internal val renderBottomNavigationBarFingerprint = fingerprint {
returns("V") returns("V")
parameters("Ljava/lang/String;") parameters("Ljava/lang/String;")

View File

@@ -18,7 +18,6 @@ import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter
import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch
import app.revanced.patches.youtube.misc.navigation.navigationBarHookPatch import app.revanced.patches.youtube.misc.navigation.navigationBarHookPatch
import app.revanced.patches.youtube.misc.playservice.is_19_03_or_greater
import app.revanced.patches.youtube.misc.playservice.is_19_41_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_41_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
@@ -27,11 +26,8 @@ import app.revanced.util.*
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal var reelMultipleItemShelfId = -1L
private set
internal var reelPlayerRightCellButtonHeight = -1L internal var reelPlayerRightCellButtonHeight = -1L
private set private set
internal var bottomBarContainer = -1L internal var bottomBarContainer = -1L
@@ -155,13 +151,6 @@ private val hideShortsComponentsResourcePatch = resourcePatch {
"dimen", "dimen",
"reel_player_right_pivot_v2_size", "reel_player_right_pivot_v2_size",
] ]
if (!is_19_03_or_greater) {
reelMultipleItemShelfId = resourceMappings[
"dimen",
"reel_player_right_cell_button_height",
]
}
} }
} }
@@ -183,8 +172,6 @@ val hideShortsComponentsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
@@ -199,25 +186,6 @@ val hideShortsComponentsPatch = bytecodePatch(
hideShortsWidgetOption() hideShortsWidgetOption()
execute { execute {
// region Hide the Shorts shelf.
// This patch point is not present in 19.03.x and greater.
if (!is_19_03_or_greater && reelConstructorFingerprint.methodOrNull != null) {
reelConstructorFingerprint.method.apply {
val insertIndex = reelConstructorFingerprint.patternMatch!!.startIndex + 2
val viewRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
injectHideViewCall(
insertIndex,
viewRegister,
FILTER_CLASS_DESCRIPTOR,
"hideShortsShelf",
)
}
}
// endregion
// region Hide the Shorts buttons in older versions of YouTube. // region Hide the Shorts buttons in older versions of YouTube.
// Some Shorts buttons are views, hide them by setting their visibility to GONE. // Some Shorts buttons are views, hide them by setting their visibility to GONE.

View File

@@ -54,8 +54,6 @@ val disableSuggestedVideoEndScreenPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -21,8 +21,6 @@ val hideTimestampPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -79,53 +79,52 @@ private val miniplayerResourcePatch = resourcePatch {
"player_overlays", "player_overlays",
] ]
if (is_19_16_or_greater) {
modernMiniplayerClose = resourceMappings[ modernMiniplayerClose = resourceMappings[
"id", "id",
"modern_miniplayer_close", "modern_miniplayer_close",
]
modernMiniplayerExpand = resourceMappings[
"id",
"modern_miniplayer_expand",
]
modernMiniplayerRewindButton = resourceMappings[
"id",
"modern_miniplayer_rewind_button",
]
modernMiniplayerForwardButton = resourceMappings[
"id",
"modern_miniplayer_forward_button",
]
// Resource id is not used during patching, but is used by extension.
// Verify the resource is present while patching.
resourceMappings[
"id",
"modern_miniplayer_subtitle_text",
]
// Only required for exactly 19.16
if (!is_19_17_or_greater) {
ytOutlinePictureInPictureWhite24 = resourceMappings[
"drawable",
"yt_outline_picture_in_picture_white_24",
] ]
modernMiniplayerExpand = resourceMappings[ ytOutlineXWhite24 = resourceMappings[
"id", "drawable",
"modern_miniplayer_expand", "yt_outline_x_white_24",
] ]
}
modernMiniplayerRewindButton = resourceMappings[ if (is_19_26_or_greater) {
"id", miniplayerMaxSize = resourceMappings[
"modern_miniplayer_rewind_button", "dimen",
"miniplayer_max_size",
] ]
modernMiniplayerForwardButton = resourceMappings[
"id",
"modern_miniplayer_forward_button",
]
// Resource id is not used during patching, but is used by extension.
// Verify the resource is present while patching.
resourceMappings[
"id",
"modern_miniplayer_subtitle_text",
]
// Only required for exactly 19.16
if (!is_19_17_or_greater) {
ytOutlinePictureInPictureWhite24 = resourceMappings[
"drawable",
"yt_outline_picture_in_picture_white_24",
]
ytOutlineXWhite24 = resourceMappings[
"drawable",
"yt_outline_x_white_24",
]
}
if (is_19_26_or_greater) {
miniplayerMaxSize = resourceMappings[
"dimen",
"miniplayer_max_size",
]
}
} }
} }
} }
@@ -146,9 +145,6 @@ val miniplayerPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
// 18.49.37 // Could be supported, but no reason when 19.16 exists and has modern types.
// 19.14.43 // Incomplete code for modern miniplayers.
// 19.15.36 // Different code for handling subtitle texts and not worth supporting.
"19.16.39", // First with modern miniplayers. "19.16.39", // First with modern miniplayers.
// 19.17.41 // Works without issues, but no reason to recommend over 19.16. // 19.17.41 // Works without issues, but no reason to recommend over 19.16.
// 19.18.41 // Works without issues, but no reason to recommend over 19.16. // 19.18.41 // Works without issues, but no reason to recommend over 19.16.

View File

@@ -21,8 +21,6 @@ val playerPopupPanelsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -12,8 +12,6 @@ val playerControlsBackgroundPatch = resourcePatch(
) { ) {
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -21,8 +21,6 @@ internal val exitFullscreenPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -52,8 +52,6 @@ val customPlayerOverlayOpacityPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -54,7 +54,6 @@ val returnYouTubeDislikePatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -29,8 +29,6 @@ val wideSearchbarPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -33,7 +33,6 @@ val shortsAutoplayPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -41,8 +41,6 @@ val openShortsInRegularPlayerPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -106,8 +106,6 @@ val sponsorBlockPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -21,7 +21,7 @@ val spoofAppVersionPatch = bytecodePatch(
name = "Spoof app version", name = "Spoof app version",
description = "Adds an option to trick YouTube into thinking you are running an older version of the app. " + description = "Adds an option to trick YouTube into thinking you are running an older version of the app. " +
"This can be used to restore old UI elements and features. " + "This can be used to restore old UI elements and features. " +
"Patching 19.16.39 or lower includes additional older spoofing targets.", "Patching 19.16.39 includes additional older spoofing targets.",
) { ) {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,
@@ -32,8 +32,6 @@ val spoofAppVersionPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
// "19.25.37", // Cannot be supported because the lowest spoof target is higher. // "19.25.37", // Cannot be supported because the lowest spoof target is higher.
// "19.34.42", // Cannot be supported because the lowest spoof target is higher. // "19.34.42", // Cannot be supported because the lowest spoof target is higher.

View File

@@ -29,8 +29,6 @@ val changeStartPagePatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -31,8 +31,6 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -208,8 +208,6 @@ val themePatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -33,8 +33,6 @@ val alternativeThumbnailsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -27,8 +27,6 @@ val bypassImageRegionRestrictionsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -23,8 +23,6 @@ val announcementsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -24,8 +24,6 @@ val autoRepeatPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -48,8 +48,6 @@ val backgroundPlaybackPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -8,7 +8,6 @@ import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPref
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_16_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
@@ -32,8 +31,6 @@ val enableDebuggingPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
@@ -95,22 +92,21 @@ val enableDebuggingPatch = bytecodePatch(
) )
} }
if (is_19_16_or_greater) {
experimentalLongFeatureFlagFingerprint.match(
experimentalFeatureFlagParentFingerprint.originalClassDef
).method.apply {
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT_WIDE)
addInstructions( experimentalLongFeatureFlagFingerprint.match(
insertIndex, experimentalFeatureFlagParentFingerprint.originalClassDef
""" ).method.apply {
move-result-wide v0 val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT_WIDE)
invoke-static/range { v0 .. v5 }, $EXTENSION_CLASS_DESCRIPTOR->isLongFeatureFlagEnabled(JJJ)J
move-result-wide v0 addInstructions(
return-wide v0 insertIndex,
""" """
) move-result-wide v0
} invoke-static/range { v0 .. v5 }, $EXTENSION_CLASS_DESCRIPTOR->isLongFeatureFlagEnabled(JJJ)J
move-result-wide v0
return-wide v0
"""
)
experimentalStringFeatureFlagFingerprint.match( experimentalStringFeatureFlagFingerprint.match(
experimentalFeatureFlagParentFingerprint.originalClassDef experimentalFeatureFlagParentFingerprint.originalClassDef

View File

@@ -24,8 +24,6 @@ val spoofDeviceDimensionsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -21,8 +21,6 @@ val checkWatchHistoryDomainNameResolutionPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -35,8 +35,6 @@ val gmsCoreSupportPatch = gmsCoreSupportPatch(
compatibleWith( compatibleWith(
YOUTUBE_PACKAGE_NAME( YOUTUBE_PACKAGE_NAME(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -30,8 +30,6 @@ val bypassURLRedirectsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -41,8 +41,6 @@ val openLinksExternallyPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -5,10 +5,13 @@ package app.revanced.patches.youtube.misc.playservice
import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.patch.resourcePatch
import app.revanced.util.findElementByAttributeValueOrThrow import app.revanced.util.findElementByAttributeValueOrThrow
@Deprecated("19.16.39 is the lowest supported version")
var is_19_03_or_greater = false var is_19_03_or_greater = false
private set private set
@Deprecated("19.16.39 is the lowest supported version")
var is_19_04_or_greater = false var is_19_04_or_greater = false
private set private set
@Deprecated("19.16.39 is the lowest supported version")
var is_19_16_or_greater = false var is_19_16_or_greater = false
private set private set
var is_19_17_or_greater = false var is_19_17_or_greater = false

View File

@@ -30,8 +30,6 @@ val removeTrackingQueryParameterPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -19,7 +19,6 @@ import app.revanced.patches.shared.misc.settings.settingsPatch
import app.revanced.patches.youtube.misc.check.checkEnvironmentPatch import app.revanced.patches.youtube.misc.check.checkEnvironmentPatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.fix.playbackspeed.fixPlaybackSpeedWhilePlayingPatch import app.revanced.patches.youtube.misc.fix.playbackspeed.fixPlaybackSpeedWhilePlayingPatch
import app.revanced.patches.youtube.misc.playservice.is_19_04_or_greater
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.util.* import app.revanced.util.*
@@ -249,13 +248,10 @@ val settingsPatch = bytecodePatch(
} }
// Add setting to force cairo settings fragment on/off. // Add setting to force cairo settings fragment on/off.
if (is_19_04_or_greater) { cairoFragmentConfigFingerprint.method.insertFeatureFlagBooleanOverride(
cairoFragmentConfigFingerprint.method.insertFeatureFlagBooleanOverride( CAIRO_CONFIG_LITERAL_VALUE,
CAIRO_CONFIG_LITERAL_VALUE, "$activityHookClassDescriptor->useCairoSettingsFragment(Z)Z"
"$activityHookClassDescriptor->useCairoSettingsFragment(Z)Z" )
)
}
} }
finalize { finalize {

View File

@@ -12,8 +12,6 @@ import app.revanced.patches.youtube.misc.settings.settingsPatch
val spoofVideoStreamsPatch = spoofVideoStreamsPatch({ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -21,8 +21,6 @@ val zoomHapticsPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -41,8 +41,6 @@ val forceOriginalAudioPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -28,8 +28,6 @@ val disableHdrPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -35,8 +35,6 @@ val rememberVideoQualityPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

View File

@@ -19,8 +19,6 @@ val playbackSpeedPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",

Some files were not shown because too many files have changed in this diff Show More