revanced-patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockResourcePatch.kt

107 lines
4.0 KiB
Kotlin

package app.revanced.patches.youtube.layout.sponsorblock
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.IntentPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.misc.settings.SettingsResourcePatch
import app.revanced.util.ResourceGroup
import app.revanced.util.copyResources
import app.revanced.util.copyXmlNode
import app.revanced.util.inputStreamFromBundledResource
@Patch(
dependencies = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class,
],
)
internal object SponsorBlockResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsResourcePatch += IntentPreference(
key = "revanced_settings_screen_10",
titleKey = "revanced_sb_settings_title",
summaryKey = null,
intent = SettingsPatch.newIntent("revanced_sb_settings_intent")
)
arrayOf(
ResourceGroup(
"layout",
"revanced_sb_inline_sponsor_overlay.xml",
"revanced_sb_new_segment.xml",
"revanced_sb_skip_sponsor_button.xml",
),
ResourceGroup(
// required resource for back button, because when the base APK is used, this resource will not exist
"drawable",
"revanced_sb_adjust.xml",
"revanced_sb_compare.xml",
"revanced_sb_edit.xml",
"revanced_sb_logo.xml",
"revanced_sb_publish.xml",
"revanced_sb_voting.xml",
),
ResourceGroup(
// required resource for back button, because when the base APK is used, this resource will not exist
"drawable-xxxhdpi",
"quantum_ic_skip_next_white_24.png",
),
).forEach { resourceGroup ->
context.copyResources("sponsorblock", resourceGroup)
}
// copy nodes from host resources to their real xml files
val hostingResourceStream =
inputStreamFromBundledResource(
"sponsorblock",
"host/layout/youtube_controls_layout.xml",
)!!
var modifiedControlsLayout = false
val editor = context.xmlEditor["res/layout/youtube_controls_layout.xml"]
"RelativeLayout".copyXmlNode(
context.xmlEditor[hostingResourceStream],
editor,
).also {
val document = editor.file
val children = document.getElementsByTagName("RelativeLayout").item(0).childNodes
// Replace the startOf with the voting button view so that the button does not overlap
for (i in 1 until children.length) {
val view = children.item(i)
// Replace the attribute for a specific node only
if (!(
view.hasAttributes() &&
view.attributes.getNamedItem(
"android:id",
).nodeValue.endsWith("live_chat_overlay_button")
)
) {
continue
}
// voting button id from the voting button view from the youtube_controls_layout.xml host file
val votingButtonId = "@+id/revanced_sb_voting_button"
view.attributes.getNamedItem("android:layout_toStartOf").nodeValue = votingButtonId
modifiedControlsLayout = true
break
}
}.close()
if (!modifiedControlsLayout) throw PatchException("Could not modify controls layout")
}
}