Compare commits

...

5 Commits

Author SHA1 Message Date
semantic-release-bot
098162173f chore(release): 2.186.0-dev.2 [skip ci]
# [2.186.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.186.0-dev.1...v2.186.0-dev.2) (2023-07-20)

### Bug Fixes

* **YouTube - Theme:** apply custom seekbar color to shorts ([#2670](https://github.com/ReVanced/revanced-patches/issues/2670)) ([a19fa4e](a19fa4e087))

### Features

* **Youtube - Theme:** add a switch to enable/disable custom seekbar color ([#2663](https://github.com/ReVanced/revanced-patches/issues/2663)) ([dd7c663](dd7c663df6))
2023-07-20 17:31:06 +00:00
LisoUseInAIKyrios
a19fa4e087 fix(YouTube - Theme): apply custom seekbar color to shorts (#2670) 2023-07-20 21:28:22 +04:00
LisoUseInAIKyrios
dd7c663df6 feat(Youtube - Theme): add a switch to enable/disable custom seekbar color (#2663) 2023-07-20 21:27:44 +04:00
semantic-release-bot
9bd7773af2 chore(release): 2.186.0-dev.1 [skip ci]
# [2.186.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.185.0...v2.186.0-dev.1) (2023-07-20)

### Features

* **Twitter:** remove `Hide view stats` patch ([4e1c9b9](4e1c9b9ec2))
2023-07-20 16:47:25 +00:00
oSumAtrIX
4e1c9b9ec2 feat(Twitter): remove Hide view stats patch
The patch is constrained on a version that is not working properly anymore.
2023-07-20 18:44:08 +02:00
15 changed files with 77 additions and 281 deletions

View File

@@ -1,3 +1,22 @@
# [2.186.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.186.0-dev.1...v2.186.0-dev.2) (2023-07-20)
### Bug Fixes
* **YouTube - Theme:** apply custom seekbar color to shorts ([#2670](https://github.com/ReVanced/revanced-patches/issues/2670)) ([1f6fe3d](https://github.com/ReVanced/revanced-patches/commit/1f6fe3da4284fd768057ef068c7ddf88d3a11049))
### Features
* **Youtube - Theme:** add a switch to enable/disable custom seekbar color ([#2663](https://github.com/ReVanced/revanced-patches/issues/2663)) ([5c39985](https://github.com/ReVanced/revanced-patches/commit/5c39985888cdfe3acfdd8811ff9b6f80e243704e))
# [2.186.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.185.0...v2.186.0-dev.1) (2023-07-20)
### Features
* **Twitter:** remove `Hide view stats` patch ([f0d3800](https://github.com/ReVanced/revanced-patches/commit/f0d38001b34db63f212209afb91eebf59dad2b24))
# [2.185.0](https://github.com/ReVanced/revanced-patches/compare/v2.184.0...v2.185.0) (2023-07-20)

View File

@@ -1,4 +1,4 @@
org.gradle.parallel = true
org.gradle.caching = true
kotlin.code.style = official
version = 2.185.0
version = 2.186.0-dev.2

File diff suppressed because one or more lines are too long

View File

@@ -1,12 +0,0 @@
package app.revanced.patches.twitter.layout.hideviews.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.twitter.android", arrayOf("9.69.1-release.0", "9.71.0-release.0")
)]
)
@Target(AnnotationTarget.CLASS)
internal annotation class HideViewsCompatibility

View File

@@ -1,15 +0,0 @@
package app.revanced.patches.twitter.layout.hideviews.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object InlineActionTypesFingerprint : MethodFingerprint(
returnType = "Ljava/util/List",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
strings = listOf(
"getCurrentMemoizing()",
"android_animated_reply_icon_enabled",
"reply_voting_android_position_before_favorite_enabled"
)
)

View File

@@ -1,22 +0,0 @@
package app.revanced.patches.twitter.layout.hideviews.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object TweetStatsContainerConstructorFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("L"),
opcodes = listOf(
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.INVOKE_VIRTUAL
)
)

View File

@@ -1,22 +0,0 @@
package app.revanced.patches.twitter.layout.hideviews.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object TweetStatsContainerWrapperConstructorFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("L"),
opcodes = listOf(
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IPUT_OBJECT
)
)

View File

@@ -1,26 +0,0 @@
package app.revanced.patches.twitter.layout.hideviews.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object TweetStatsViewDelegateBinderFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(
Opcode.NEW_INSTANCE,
Opcode.CONST_16,
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.CONST_16,
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_OBJECT
)
)

View File

@@ -1,114 +0,0 @@
package app.revanced.patches.twitter.layout.hideviews.patch
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.twitter.layout.hideviews.fingerprints.InlineActionTypesFingerprint
import app.revanced.patches.twitter.layout.hideviews.fingerprints.TweetStatsContainerConstructorFingerprint
import app.revanced.patches.twitter.layout.hideviews.fingerprints.TweetStatsContainerWrapperConstructorFingerprint
import app.revanced.patches.twitter.layout.hideviews.fingerprints.TweetStatsViewDelegateBinderFingerprint
import org.jf.dexlib2.Opcode
class HideViewsBytecodePatch : BytecodePatch(
listOf(
InlineActionTypesFingerprint,
TweetStatsContainerWrapperConstructorFingerprint,
TweetStatsContainerConstructorFingerprint,
TweetStatsViewDelegateBinderFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
removeViewsFromTimeline(context)
removeTweetStatViewInitializer(context)
removeTweetStatViewWrapperInitializer(context)
removeViewDelegateBinderSubscription()
return PatchResultSuccess()
}
private fun removeViewsFromTimeline(context: BytecodeContext) {
val addViewsToActionBarMethodFingerprint = object : MethodFingerprint(
opcodes = listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.SGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IF_EQZ,
)
) {}
transformMethodAtPattern(
context,
InlineActionTypesFingerprint,
addViewsToActionBarMethodFingerprint
) { patternScanResult, method ->
method.removeInstruction(patternScanResult.endIndex - 1)
}
}
private fun removeTweetStatViewInitializer(context: BytecodeContext) {
val returnFingerprint = object : MethodFingerprint(
opcodes = listOf(Opcode.RETURN_VOID)
) {}
transformMethodAtPattern(
context,
TweetStatsContainerConstructorFingerprint,
returnFingerprint
) { patternScanResult, method ->
method.removeInstructions(patternScanResult.endIndex - 3, 3)
}
}
private fun removeTweetStatViewWrapperInitializer(context: BytecodeContext) {
val wrapperReturnFingerprint = object : MethodFingerprint(
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.RETURN_VOID,
)
) {}
transformMethodAtPattern(
context,
TweetStatsContainerWrapperConstructorFingerprint,
wrapperReturnFingerprint
) { patternScanResult, method ->
method.removeInstructions(patternScanResult.startIndex - 4, 4)
}
}
private fun removeViewDelegateBinderSubscription() {
transformMethod(TweetStatsViewDelegateBinderFingerprint) { result, method ->
method.removeInstructions(result.scanResult.patternScanResult!!.startIndex - 4, 10)
}
}
private fun transformMethodAtPattern(
context: BytecodeContext, methodFingerprint: MethodFingerprint,
patternFingerprint: MethodFingerprint, transformer: TransformerAtPattern
) {
transformMethod(methodFingerprint) { result, method ->
val patternResult = patternFingerprint.also {
it.resolve(context, method, result.classDef)
}.result!!
transformer(patternResult.scanResult.patternScanResult!!, method)
}
}
private fun transformMethod(methodFingerprint: MethodFingerprint, transformer: Transformer) {
val result = methodFingerprint.result!!
val method = result.mutableMethod
transformer(result, method)
}
}
private typealias Transformer = (MethodFingerprintResult, MutableMethod) -> Unit
private typealias TransformerAtPattern = (MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult, MutableMethod) -> Unit

View File

@@ -1,34 +0,0 @@
package app.revanced.patches.twitter.layout.hideviews.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.*
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.twitter.layout.hideviews.annotations.HideViewsCompatibility
import org.w3c.dom.Element
@Patch
@DependsOn([HideViewsBytecodePatch::class])
@Name("Hide views stats")
@Description("Hides the view stats under tweets.")
@HideViewsCompatibility
@Version("0.0.1")
class HideViewsResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
arrayOf(
"res/layout/condensed_tweet_stats.xml",
"res/layout/focal_tweet_stats.xml"
).forEach { file ->
context.xmlEditor[file].use { editor ->
val tags = editor.file.getElementsByTagName("com.twitter.ui.tweet.TweetStatView")
List(tags.length) { tags.item(it) as Element }
.filter { it.getAttribute("android:id").contains("views_stat") }
.forEach { it.parentNode.removeChild(it) }
}
}
return PatchResultSuccess()
}
}

View File

@@ -6,7 +6,7 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarColorResourcePatch
import org.jf.dexlib2.AccessFlags
object CreateDarkThemeSeekbarFingerprint : MethodFingerprint(
object PlayerSeekbarColorFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
customFingerprint = { method, _ ->
method.containsConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId)

View File

@@ -0,0 +1,11 @@
package app.revanced.patches.youtube.layout.seekbar.bytecode.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarColorResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.AccessFlags
object ShortsSeekbarColorFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
literal = SeekbarColorResourcePatch.reelTimeBarPlayedColorId,
)

View File

@@ -14,8 +14,9 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.layout.seekbar.annotations.SeekbarColorCompatibility
import app.revanced.patches.youtube.layout.seekbar.bytecode.fingerprints.CreateDarkThemeSeekbarFingerprint
import app.revanced.patches.youtube.layout.seekbar.bytecode.fingerprints.PlayerSeekbarColorFingerprint
import app.revanced.patches.youtube.layout.seekbar.bytecode.fingerprints.SetSeekbarClickedColorFingerprint
import app.revanced.patches.youtube.layout.seekbar.bytecode.fingerprints.ShortsSeekbarColorFingerprint
import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarColorResourcePatch
import app.revanced.patches.youtube.layout.theme.bytecode.patch.LithoColorHookPatch
import app.revanced.patches.youtube.layout.theme.bytecode.patch.LithoColorHookPatch.Companion.lithoColorOverrideHook
@@ -28,30 +29,29 @@ import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
@SeekbarColorCompatibility
@Version("0.0.1")
class SeekbarColorBytecodePatch : BytecodePatch(
listOf(CreateDarkThemeSeekbarFingerprint, SetSeekbarClickedColorFingerprint)
listOf(PlayerSeekbarColorFingerprint, ShortsSeekbarColorFingerprint, SetSeekbarClickedColorFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
CreateDarkThemeSeekbarFingerprint.result?.mutableMethod?.apply {
var registerIndex = indexOfFirstConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId) + 2
var colorRegister = (getInstruction(registerIndex) as OneRegisterInstruction).registerA
fun MutableMethod.addColorChangeInstructions(resourceId: Long) {
var registerIndex = indexOfFirstConstantInstructionValue(resourceId) + 2
var colorRegister = getInstruction<OneRegisterInstruction>(registerIndex).registerA
addInstructions(
registerIndex + 1,
"""
invoke-static { v$colorRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I
move-result v$colorRegister
"""
invoke-static { v$colorRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I
move-result v$colorRegister
"""
)
registerIndex = indexOfFirstConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarPlayedNotHighlightedColorId) + 2
colorRegister = (getInstruction(registerIndex) as OneRegisterInstruction).registerA
addInstructions(
registerIndex + 1,
"""
invoke-static { v$colorRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I
move-result v$colorRegister
"""
)
} ?: return CreateDarkThemeSeekbarFingerprint.toErrorResult()
}
PlayerSeekbarColorFingerprint.result?.mutableMethod?.apply {
addColorChangeInstructions(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId)
addColorChangeInstructions(SeekbarColorResourcePatch.inlineTimeBarPlayedNotHighlightedColorId)
} ?: return PlayerSeekbarColorFingerprint.toErrorResult()
ShortsSeekbarColorFingerprint.result?.mutableMethod?.apply {
addColorChangeInstructions(SeekbarColorResourcePatch.reelTimeBarPlayedColorId)
} ?: return ShortsSeekbarColorFingerprint.toErrorResult()
SetSeekbarClickedColorFingerprint.result?.let { result ->
result.mutableMethod.let {
@@ -62,7 +62,7 @@ class SeekbarColorBytecodePatch : BytecodePatch(
.getMethod() as MutableMethod
method.apply {
val colorRegister = (method.getInstruction(0) as TwoRegisterInstruction).registerA
val colorRegister = getInstruction<TwoRegisterInstruction>(0).registerA
addInstructions(
0,
"""

View File

@@ -9,17 +9,20 @@ import org.w3c.dom.Element
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
class SeekbarColorResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
// Edit theme colors via bytecode.
// For that the resource id is used in a bytecode patch to change the color.
val seekbarErrorMessage = "Could not find seekbar resource"
inlineTimeBarColorizedBarPlayedColorDarkId = ResourceMappingPatch.resourceMappings
.find { it.name == "inline_time_bar_colorized_bar_played_color_dark" }?.id
?: return PatchResultError(seekbarErrorMessage)
inlineTimeBarPlayedNotHighlightedColorId = ResourceMappingPatch.resourceMappings
.find { it.name == "inline_time_bar_played_not_highlighted_color" }?.id
?: return PatchResultError(seekbarErrorMessage)
override fun execute(context: ResourceContext): PatchResult {
fun findColorResource(resourceName: String): Long {
return ResourceMappingPatch.resourceMappings
.find { it.type == "color" && it.name == resourceName }?.id
?: throw PatchResultError("Could not find color resource: $resourceName")
}
reelTimeBarPlayedColorId =
findColorResource("reel_time_bar_played_color")
inlineTimeBarColorizedBarPlayedColorDarkId =
findColorResource("inline_time_bar_colorized_bar_played_color_dark")
inlineTimeBarPlayedNotHighlightedColorId =
findColorResource("inline_time_bar_played_not_highlighted_color")
// Edit the resume playback drawable and replace the progress bar with a custom drawable
context.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { editor ->
@@ -39,6 +42,7 @@ class SeekbarColorResourcePatch : ResourcePatch {
}
companion object {
internal var reelTimeBarPlayedColorId = -1L
internal var inlineTimeBarColorizedBarPlayedColorDarkId = -1L
internal var inlineTimeBarPlayedNotHighlightedColorId = -1L
}

View File

@@ -9,6 +9,7 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.InputType
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.shared.settings.preference.impl.TextPreference
import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarPreferencesPatch
import app.revanced.patches.youtube.layout.theme.bytecode.patch.ThemeBytecodePatch.Companion.darkThemeBackgroundColor
@@ -20,10 +21,16 @@ import org.w3c.dom.Element
class ThemeResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
SeekbarPreferencesPatch.addPreferences(
SwitchPreference(
"revanced_seekbar_custom_color",
StringResource("revanced_seekbar_custom_color_title", "Enable custom seekbar color"),
StringResource("revanced_seekbar_custom_color_summary_on", "Custom seekbar color is shown"),
StringResource("revanced_seekbar_custom_color_summary_off", "Original seekbar color is shown")
),
TextPreference(
"revanced_seekbar_color",
StringResource("revanced_seekbar_color_title", "Seekbar color"),
StringResource("revanced_seekbar_color_summary", "The color of the seekbar"),
"revanced_seekbar_custom_color_value",
StringResource("revanced_seekbar_custom_color_value_title", "Custom seekbar color"),
StringResource("revanced_seekbar_custom_color_value_summary", "The color of the seekbar"),
InputType.TEXT_CAP_CHARACTERS
)
)