Skip to content

Commit 3bd76d6

Browse files
MarcaDianLisoUseInAIKyriosoSumAtrIX
authored
feat(YouTube Music): Add Theme patch (#5984)
Co-authored-by: LisoUseInAIKyrios <[email protected]> Co-authored-by: oSumAtrIX <[email protected]>
1 parent 1587178 commit 3bd76d6

File tree

14 files changed

+465
-231
lines changed

14 files changed

+465
-231
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package app.revanced.extension.music.patches.theme;
2+
3+
import app.revanced.extension.shared.theme.BaseThemePatch;
4+
5+
@SuppressWarnings("unused")
6+
public class ThemePatch extends BaseThemePatch {
7+
8+
// Color constants used in relation with litho components.
9+
private static final int[] DARK_VALUES = {
10+
0xFF212121, // Comments box background.
11+
0xFF030303, // Button container background in album.
12+
0xFF000000, // Button container background in playlist.
13+
};
14+
15+
/**
16+
* Injection point.
17+
* <p>
18+
* Change the color of Litho components.
19+
* If the color of the component matches one of the values, return the background color.
20+
*
21+
* @param originalValue The original color value.
22+
* @return The new or original color value.
23+
*/
24+
public static int getValue(int originalValue) {
25+
return processColorValue(originalValue, DARK_VALUES, null);
26+
}
27+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package app.revanced.extension.shared.theme;
2+
3+
import androidx.annotation.Nullable;
4+
5+
import app.revanced.extension.shared.Utils;
6+
7+
@SuppressWarnings("unused")
8+
public abstract class BaseThemePatch {
9+
// Background colors.
10+
protected static final int BLACK_COLOR = Utils.getResourceColor("yt_black1");
11+
protected static final int WHITE_COLOR = Utils.getResourceColor("yt_white1");
12+
13+
/**
14+
* Check if a value matches any of the provided values.
15+
*
16+
* @param value The value to check.
17+
* @param of The array of values to compare against.
18+
* @return True if the value matches any of the provided values.
19+
*/
20+
protected static boolean anyEquals(int value, int... of) {
21+
for (int v : of) {
22+
if (value == v) {
23+
return true;
24+
}
25+
}
26+
return false;
27+
}
28+
29+
/**
30+
* Helper method to process color values for Litho components.
31+
*
32+
* @param originalValue The original color value.
33+
* @param darkValues Array of dark mode color values to match.
34+
* @param lightValues Array of light mode color values to match.
35+
* @return The new or original color value.
36+
*/
37+
protected static int processColorValue(int originalValue, int[] darkValues, @Nullable int[] lightValues) {
38+
if (Utils.isDarkModeEnabled()) {
39+
if (anyEquals(originalValue, darkValues)) {
40+
return BLACK_COLOR;
41+
}
42+
} else if (lightValues != null && anyEquals(originalValue, lightValues)) {
43+
return WHITE_COLOR;
44+
}
45+
46+
return originalValue;
47+
}
48+
}

extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/ThemePatch.java

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
package app.revanced.extension.youtube.patches.theme;
22

3-
import static app.revanced.extension.youtube.patches.theme.ThemePatch.SplashScreenAnimationStyle.styleFromOrdinal;
4-
53
import androidx.annotation.Nullable;
64

75
import app.revanced.extension.shared.Logger;
8-
import app.revanced.extension.shared.Utils;
6+
import app.revanced.extension.shared.theme.BaseThemePatch;
97
import app.revanced.extension.youtube.settings.Settings;
108

119
@SuppressWarnings("unused")
12-
public class ThemePatch {
13-
10+
public class ThemePatch extends BaseThemePatch {
1411
public enum SplashScreenAnimationStyle {
1512
DEFAULT(0),
1613
FPS_60_ONE_SECOND(1),
@@ -43,57 +40,39 @@ static SplashScreenAnimationStyle styleFromOrdinal(int style) {
4340
}
4441
}
4542

46-
// color constants used in relation with litho components
43+
// Color constants used in relation with litho components.
4744
private static final int[] WHITE_VALUES = {
48-
-1, // comments chip background
49-
-394759, // music related results panel background
50-
-83886081, // video chapters list background
45+
0xFFFFFFFF, // Comments chip background.
46+
0xFFF9F9F9, // Music related results panel background.
47+
0xFAFFFFFF, // Video chapters list background.
5148
};
5249

5350
private static final int[] DARK_VALUES = {
54-
-14145496, // explore drawer background
55-
-14606047, // comments chip background
56-
-15198184, // music related results panel background
57-
-15790321, // comments chip background (new layout)
58-
-98492127 // video chapters list background
51+
0xFF282828, // Explore drawer background.
52+
0xFF212121, // Comments chip background.
53+
0xFF181818, // Music related results panel background.
54+
0xFF0F0F0F, // Comments chip background (new layout).
55+
0xFA212121, // Video chapters list background.
5956
};
6057

61-
// Background colors.
62-
private static final int WHITE_COLOR = Utils.getResourceColor("yt_white1");
63-
private static final int BLACK_COLOR = Utils.getResourceColor("yt_black1");
64-
65-
private static final boolean GRADIENT_LOADING_SCREEN_ENABLED = Settings.GRADIENT_LOADING_SCREEN.get();
66-
6758
/**
6859
* Injection point.
69-
*
60+
* <p>
7061
* Change the color of Litho components.
71-
* If the color of the component matches one of the values, return the background color .
62+
* If the color of the component matches one of the values, return the background color.
7263
*
7364
* @param originalValue The original color value.
74-
* @return The new or original color value
65+
* @return The new or original color value.
7566
*/
7667
public static int getValue(int originalValue) {
77-
if (Utils.isDarkModeEnabled()) {
78-
if (anyEquals(originalValue, DARK_VALUES)) return BLACK_COLOR;
79-
} else {
80-
if (anyEquals(originalValue, WHITE_VALUES)) return WHITE_COLOR;
81-
}
82-
83-
return originalValue;
84-
}
85-
86-
private static boolean anyEquals(int value, int... of) {
87-
for (int v : of) if (value == v) return true;
88-
89-
return false;
68+
return processColorValue(originalValue, DARK_VALUES, WHITE_VALUES);
9069
}
9170

9271
/**
9372
* Injection point.
9473
*/
9574
public static boolean gradientLoadingScreenEnabled(boolean original) {
96-
return GRADIENT_LOADING_SCREEN_ENABLED;
75+
return Settings.GRADIENT_LOADING_SCREEN.get();
9776
}
9877

9978
/**
@@ -108,7 +87,7 @@ public static int getLoadingScreenType(int original) {
10887
final int replacement = style.style;
10988
if (original != replacement) {
11089
Logger.printDebug(() -> "Overriding splash screen style from: "
111-
+ styleFromOrdinal(original) + " to: " + style);
90+
+ SplashScreenAnimationStyle.styleFromOrdinal(original) + " to: " + style);
11291
}
11392

11493
return replacement;

patches/api/patches.api

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,10 @@ public final class app/revanced/patches/music/layout/premium/HideGetPremiumPatch
388388
public static final fun getHideGetPremiumPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
389389
}
390390

391+
public final class app/revanced/patches/music/layout/theme/ThemePatchKt {
392+
public static final fun getThemePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
393+
}
394+
391395
public final class app/revanced/patches/music/layout/upgradebutton/HideUpgradeButtonPatchKt {
392396
public static final fun getHideUpgradeButton ()Lapp/revanced/patcher/patch/BytecodePatch;
393397
public static final fun getRemoveUpgradeButton ()Lapp/revanced/patcher/patch/BytecodePatch;
@@ -733,6 +737,11 @@ public final class app/revanced/patches/serviceportalbund/detection/root/RootDet
733737
public static final fun getRootDetectionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
734738
}
735739

740+
public final class app/revanced/patches/shared/layout/theme/LithoColorHookPatchKt {
741+
public static final fun getLithoColorHookPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
742+
public static final fun getLithoColorOverrideHook ()Lkotlin/jvm/functions/Function2;
743+
}
744+
736745
public final class app/revanced/patches/shared/misc/checks/BaseCheckEnvironmentPatchKt {
737746
public static final fun checkEnvironmentPatch (Lapp/revanced/patcher/Fingerprint;Lapp/revanced/patcher/patch/Patch;[Ljava/lang/String;)Lapp/revanced/patcher/patch/BytecodePatch;
738747
}

patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/NavigationBarPatch.kt

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
44
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
55
import app.revanced.patcher.patch.PatchException
66
import app.revanced.patcher.patch.bytecodePatch
7+
import app.revanced.patcher.patch.resourcePatch
78
import app.revanced.patches.all.misc.resources.addResources
89
import app.revanced.patches.all.misc.resources.addResourcesPatch
910
import app.revanced.patches.music.misc.extension.sharedExtensionPatch
@@ -35,7 +36,23 @@ val navigationBarPatch = bytecodePatch(
3536
resourceMappingPatch,
3637
sharedExtensionPatch,
3738
settingsPatch,
38-
addResourcesPatch
39+
addResourcesPatch,
40+
resourcePatch {
41+
execute {
42+
// Ensure the first ImageView has 'layout_weight' to stay properly sized
43+
// when the TextView is hidden.
44+
document("res/layout/image_with_text_tab.xml").use { document ->
45+
val imageView = document.getElementsByTagName("ImageView").item(0)
46+
imageView?.let {
47+
if (it.attributes.getNamedItem("android:layout_weight") == null) {
48+
val attr = document.createAttribute("android:layout_weight")
49+
attr.value = "0.5"
50+
it.attributes.setNamedItem(attr)
51+
}
52+
}
53+
}
54+
}
55+
}
3956
)
4057

4158
compatibleWith(
@@ -46,10 +63,7 @@ val navigationBarPatch = bytecodePatch(
4663
)
4764

4865
execute {
49-
text1 = resourceMappings[
50-
"id",
51-
"text1",
52-
]
66+
text1 = resourceMappings["id", "text1"]
5367

5468
addResources("music", "layout.navigationbar.navigationBarPatch")
5569

@@ -71,9 +85,7 @@ val navigationBarPatch = bytecodePatch(
7185
)
7286

7387
tabLayoutTextFingerprint.method.apply {
74-
/**
75-
* Hide navigation labels.
76-
*/
88+
// Hide navigation labels.
7789
val constIndex = indexOfFirstLiteralInstructionOrThrow(text1)
7890
val targetIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
7991
val targetParameter = getInstruction<ReferenceInstruction>(targetIndex).reference
@@ -87,9 +99,7 @@ val navigationBarPatch = bytecodePatch(
8799
"invoke-static { v$targetRegister }, $EXTENSION_CLASS_DESCRIPTOR->hideNavigationLabel(Landroid/widget/TextView;)V"
88100
)
89101

90-
/**
91-
* Set navigation enum and hide navigation buttons.
92-
*/
102+
// Set navigation enum and hide navigation buttons.
93103
val enumIndex = tabLayoutTextFingerprint.patternMatch!!.startIndex + 3
94104
val enumRegister = getInstruction<OneRegisterInstruction>(enumIndex).registerA
95105
val insertEnumIndex = indexOfFirstInstructionOrThrow(Opcode.AND_INT_LIT8) - 2
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package app.revanced.patches.music.layout.theme
2+
3+
import app.revanced.patches.music.misc.extension.sharedExtensionPatch
4+
import app.revanced.patches.shared.layout.theme.THEME_DEFAULT_DARK_COLOR_NAMES
5+
import app.revanced.patches.shared.layout.theme.baseThemePatch
6+
import app.revanced.patches.shared.layout.theme.baseThemeResourcePatch
7+
import app.revanced.patches.shared.layout.theme.darkThemeBackgroundColorOption
8+
import app.revanced.patches.shared.misc.settings.overrideThemeColors
9+
10+
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/music/patches/theme/ThemePatch;"
11+
12+
@Suppress("unused")
13+
val themePatch = baseThemePatch(
14+
extensionClassDescriptor = EXTENSION_CLASS_DESCRIPTOR,
15+
16+
block = {
17+
dependsOn(
18+
sharedExtensionPatch,
19+
baseThemeResourcePatch(
20+
darkColorNames = THEME_DEFAULT_DARK_COLOR_NAMES + setOf(
21+
"yt_black_pure",
22+
"yt_black_pure_opacity80",
23+
"ytm_color_grey_12",
24+
"material_grey_800"
25+
)
26+
)
27+
)
28+
29+
compatibleWith(
30+
"com.google.android.apps.youtube.music"(
31+
"7.29.52",
32+
"8.10.52"
33+
)
34+
)
35+
},
36+
37+
executeBlock = {
38+
overrideThemeColors(
39+
null,
40+
darkThemeBackgroundColorOption.value!!
41+
)
42+
}
43+
)

0 commit comments

Comments
 (0)