From 63d7b6c28059ed0ea8937dd40b14077222898afb Mon Sep 17 00:00:00 2001
From: inotia00 <108592928+inotia00@users.noreply.github.com>
Date: Sat, 28 Sep 2024 23:09:08 +0900
Subject: [PATCH] feat(YouTube): add `Hide shortcuts` patch
---
.../youtube/layout/shortcut/ShortcutPatch.kt | 69 +++++++++++++++++++
.../kotlin/app/revanced/util/ResourceUtils.kt | 27 ++++++++
.../youtube/settings/xml/revanced_prefs.xml | 1 +
3 files changed, 97 insertions(+)
create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/shortcut/ShortcutPatch.kt
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/shortcut/ShortcutPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/shortcut/ShortcutPatch.kt
new file mode 100644
index 0000000000..85c977cc07
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/shortcut/ShortcutPatch.kt
@@ -0,0 +1,69 @@
+package app.revanced.patches.youtube.layout.shortcut
+
+import app.revanced.patcher.data.ResourceContext
+import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.booleanPatchOption
+import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
+import app.revanced.patches.youtube.utils.settings.SettingsPatch
+import app.revanced.util.findElementByAttributeValueOrThrow
+import app.revanced.util.patch.BaseResourcePatch
+import org.w3c.dom.Element
+
+@Suppress("DEPRECATION", "unused")
+object ShortcutPatch : BaseResourcePatch(
+ name = "Hide shortcuts",
+ description = "Remove, at compile time, the app shortcuts that appears when app icon is long pressed.",
+ dependencies = setOf(SettingsPatch::class),
+ compatiblePackages = COMPATIBLE_PACKAGE,
+ use = false
+) {
+ private val Explore by booleanPatchOption(
+ key = "Explore",
+ default = false,
+ title = "Hide Explore",
+ description = "Hide Explore from shortcuts.",
+ required = true
+ )
+
+ private val Subscriptions by booleanPatchOption(
+ key = "Subscriptions",
+ default = false,
+ title = "Hide Subscriptions",
+ description = "Hide Subscriptions from shortcuts.",
+ required = true
+ )
+
+ private val Search by booleanPatchOption(
+ key = "Search",
+ default = false,
+ title = "Hide Search",
+ description = "Hide Search from shortcuts.",
+ required = true
+ )
+
+ private val Shorts by booleanPatchOption(
+ key = "Shorts",
+ default = true,
+ title = "Hide Shorts",
+ description = "Hide Shorts from shortcuts.",
+ required = true
+ )
+
+ override fun execute(context: ResourceContext) {
+
+ this.options.values.forEach { options ->
+ if (options.value == true) {
+ context.xmlEditor["res/xml/main_shortcuts.xml"].use { editor ->
+ val shortcuts = editor.file.getElementsByTagName("shortcuts").item(0) as Element
+ val shortsItem = shortcuts.getElementsByTagName("shortcut")
+ .findElementByAttributeValueOrThrow(
+ "android:shortcutId",
+ "${options.key.lowercase()}-shortcut"
+ )
+ shortsItem.parentNode.removeChild(shortsItem)
+ }
+ }
+ }
+
+ SettingsPatch.updatePatchStatus(this)
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/util/ResourceUtils.kt b/src/main/kotlin/app/revanced/util/ResourceUtils.kt
index d62e713673..7e46120347 100644
--- a/src/main/kotlin/app/revanced/util/ResourceUtils.kt
+++ b/src/main/kotlin/app/revanced/util/ResourceUtils.kt
@@ -8,6 +8,7 @@ import app.revanced.patcher.patch.options.PatchOption
import app.revanced.patcher.util.DomFileEditor
import org.w3c.dom.Element
import org.w3c.dom.Node
+import org.w3c.dom.NodeList
import java.io.File
import java.io.InputStream
import java.nio.file.Files
@@ -195,4 +196,30 @@ fun String.copyXmlNode(source: DomFileEditor, target: DomFileEditor): AutoClosea
source.close()
target.close()
}
+}
+
+internal fun NodeList.findElementByAttributeValue(attributeName: String, value: String): Element? {
+ for (i in 0 until length) {
+ val node = item(i)
+ if (node.nodeType == Node.ELEMENT_NODE) {
+ val element = node as Element
+
+ if (element.getAttribute(attributeName) == value) {
+ return element
+ }
+
+ // Recursively search.
+ val found = element.childNodes.findElementByAttributeValue(attributeName, value)
+ if (found != null) {
+ return found
+ }
+ }
+ }
+
+ return null
+}
+
+internal fun NodeList.findElementByAttributeValueOrThrow(attributeName: String, value: String): Element {
+ return findElementByAttributeValue(attributeName, value)
+ ?: throw PatchException("Could not find: $attributeName $value")
}
\ No newline at end of file
diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml
index 6d602abc9d..4f7588a4db 100644
--- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml
+++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml
@@ -825,6 +825,7 @@
+