@@ -27,6 +27,32 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"options": []
|
"options": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Remove timeline Upgrade button",
|
||||||
|
"description": "Removes the Premium Upgrade button from the timeline's top bar.",
|
||||||
|
"default": true,
|
||||||
|
"dependencies": [],
|
||||||
|
"compatiblePackages": [
|
||||||
|
{
|
||||||
|
"packageName": "com.twitter.android",
|
||||||
|
"name": "X",
|
||||||
|
"description": null,
|
||||||
|
"apkFileType": "APKM",
|
||||||
|
"appIconColor": "#000000",
|
||||||
|
"signatures": null,
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"version": "12.7.1-release.0",
|
||||||
|
"versionCodes": null,
|
||||||
|
"isExperimental": false,
|
||||||
|
"minSdk": 28,
|
||||||
|
"description": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"options": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
+9
-4
@@ -23,7 +23,7 @@ import kotlin.test.assertTrue
|
|||||||
|
|
||||||
class MorphePatchIntegrationTest {
|
class MorphePatchIntegrationTest {
|
||||||
@Test
|
@Test
|
||||||
fun `applies outdated version patch to target APKM`() {
|
fun `applies patches to target APKM`() {
|
||||||
val inputApkm = requiredPathProperty("integrationTest.inputApkm")
|
val inputApkm = requiredPathProperty("integrationTest.inputApkm")
|
||||||
val patchBundle = requiredPathProperty("integrationTest.patchBundle")
|
val patchBundle = requiredPathProperty("integrationTest.patchBundle")
|
||||||
val morpheCache = requiredPathProperty("integrationTest.morpheCache")
|
val morpheCache = requiredPathProperty("integrationTest.morpheCache")
|
||||||
@@ -47,7 +47,8 @@ class MorphePatchIntegrationTest {
|
|||||||
"patch",
|
"patch",
|
||||||
"--patches=${patchBundle.absolutePathString()}",
|
"--patches=${patchBundle.absolutePathString()}",
|
||||||
"--exclusive",
|
"--exclusive",
|
||||||
"--enable=$PATCH_NAME",
|
"--enable=$OUTDATED_PATCH_NAME",
|
||||||
|
"--enable=$UPGRADE_PATCH_NAME",
|
||||||
"--unsigned",
|
"--unsigned",
|
||||||
"--out=${patchedApk.absolutePathString()}",
|
"--out=${patchedApk.absolutePathString()}",
|
||||||
"--result-file=${resultFile.absolutePathString()}",
|
"--result-file=${resultFile.absolutePathString()}",
|
||||||
@@ -91,7 +92,10 @@ class MorphePatchIntegrationTest {
|
|||||||
|
|
||||||
val appliedPatchNames = result.getAsJsonArray("appliedPatches")
|
val appliedPatchNames = result.getAsJsonArray("appliedPatches")
|
||||||
.map { it.asJsonObject.get("name").asString }
|
.map { it.asJsonObject.get("name").asString }
|
||||||
assertTrue(PATCH_NAME in appliedPatchNames, "Expected patch was not applied: $appliedPatchNames")
|
assertTrue(
|
||||||
|
appliedPatchNames.containsAll(listOf(OUTDATED_PATCH_NAME, UPGRADE_PATCH_NAME)),
|
||||||
|
"Expected patches were not applied: $appliedPatchNames"
|
||||||
|
)
|
||||||
assertTrue(result.getAsJsonArray("failedPatches").isEmpty, "Morphe reported failed patches")
|
assertTrue(result.getAsJsonArray("failedPatches").isEmpty, "Morphe reported failed patches")
|
||||||
} finally {
|
} finally {
|
||||||
workDirectory.toFile().deleteRecursively()
|
workDirectory.toFile().deleteRecursively()
|
||||||
@@ -142,7 +146,8 @@ class MorphePatchIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
const val PATCH_NAME = "Disable outdated version screen"
|
const val OUTDATED_PATCH_NAME = "Disable outdated version screen"
|
||||||
|
const val UPGRADE_PATCH_NAME = "Remove timeline Upgrade button"
|
||||||
const val MORPHE_VERSION = "1.13.1"
|
const val MORPHE_VERSION = "1.13.1"
|
||||||
const val MORPHE_SHA256 = "a212531f68d3ada4b504bf9dac3e02460589f3bf8868ee66e1b4780152d3466b"
|
const val MORPHE_SHA256 = "a212531f68d3ada4b504bf9dac3e02460589f3bf8868ee66e1b4780152d3466b"
|
||||||
const val MORPHE_URL =
|
const val MORPHE_URL =
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package app.twitter.patches
|
||||||
|
|
||||||
|
import app.morphe.patcher.patch.resourcePatch
|
||||||
|
import app.twitter.patches.shared.Constants.COMPATIBILITY_X
|
||||||
|
import org.w3c.dom.Element
|
||||||
|
|
||||||
|
private const val TOOLBAR_ITEMS_PATH = "res/menu/toolbar_items.xml"
|
||||||
|
private const val UPGRADE_BUTTON_ID = "premium_upsell_upgrade"
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val removeTimelineUpgradeButtonPatch = resourcePatch(
|
||||||
|
name = "Remove timeline Upgrade button",
|
||||||
|
description = "Removes the Premium Upgrade button from the timeline's top bar.",
|
||||||
|
default = true
|
||||||
|
) {
|
||||||
|
compatibleWith(COMPATIBILITY_X)
|
||||||
|
|
||||||
|
execute {
|
||||||
|
document(TOOLBAR_ITEMS_PATH).use { document ->
|
||||||
|
val menu = document.documentElement
|
||||||
|
val upgradeButton = (0 until menu.childNodes.length)
|
||||||
|
.asSequence()
|
||||||
|
.map { menu.childNodes.item(it) }
|
||||||
|
.filterIsInstance<Element>()
|
||||||
|
.single {
|
||||||
|
it.getAttribute("android:id").substringAfterLast('/') == UPGRADE_BUTTON_ID
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.removeChild(upgradeButton)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user