diff --git a/src/main/kotlin/app/util/ResourceUtils.kt b/src/main/kotlin/app/util/ResourceUtils.kt index 66e50501..048a3175 100644 --- a/src/main/kotlin/app/util/ResourceUtils.kt +++ b/src/main/kotlin/app/util/ResourceUtils.kt @@ -5,6 +5,7 @@ import app.revanced.patcher.util.DomFileEditor import app.revanced.util.resource.BaseResource import org.w3c.dom.Node import org.w3c.dom.NodeList +import java.io.FileNotFoundException import java.io.InputStream import java.nio.file.Files import java.nio.file.StandardCopyOption @@ -24,10 +25,9 @@ fun Node.childElementsSequence() = this.childNodes.asSequence().filter { it.node /** * Performs the given [action] on each child element. */ -fun Node.forEachChildElement(action: (Node) -> Unit) = - childElementsSequence().forEach { - action(it) - } +fun Node.forEachChildElement(action: (Node) -> Unit) = childElementsSequence().forEach { + action(it) +} /** * Recursively traverse the DOM tree starting from the given root node. @@ -119,21 +119,42 @@ fun String.copyXmlNode(source: DomFileEditor, target: DomFileEditor): AutoClosea * @param elementTag The element to copy. */ fun ResourceContext.copyXmlNode( - resourceDirectory: String, - targetResource: String, - elementTag: String + resourceDirectory: String, targetResource: String, elementTag: String ) { - val stringsResourceInputStream = - classLoader.getResourceAsStream("$resourceDirectory/$targetResource")!! + val stringsResourceInputStream = classLoader.getResourceAsStream("$resourceDirectory/$targetResource")!! // Copy nodes from the resources node to the real resource node elementTag.copyXmlNode( - this.xmlEditor[stringsResourceInputStream], - this.xmlEditor["res/$targetResource"] + this.xmlEditor[stringsResourceInputStream], this.xmlEditor["res/$targetResource"] ).close() } +fun ResourceContext.appendStrings( + resourceDirectory: String, + targetResource: String, +) { + val source = classLoader.getResourceAsStream("$resourceDirectory/$targetResource") ?: throw FileNotFoundException() + + val target = this["res/$targetResource"] + val targetContent = target.readLines().dropLastWhile { it != "" }.dropLast(1) + + target.bufferedWriter().use { writer -> + targetContent.forEach { + writer.write(it) + } + + source.bufferedReader().useLines { lines -> + lines.dropWhile { + it != "" + }.drop(1).forEach { line -> + writer.write(line) + } + } + } +} + + // /** // * Copies the specified node of the source [Document] to the target [Document]. // * @param source the source [Document]. diff --git a/src/main/kotlin/app/util/Utils.kt b/src/main/kotlin/app/util/Utils.kt new file mode 100644 index 00000000..ad650f03 --- /dev/null +++ b/src/main/kotlin/app/util/Utils.kt @@ -0,0 +1,8 @@ +package app.util + +inline fun measureExecutionTime(block: () -> Unit): Long { + val start = System.currentTimeMillis() + block() + val end = System.currentTimeMillis() + return end - start +} diff --git a/src/main/kotlin/crimera/patches/twitter/misc/settings/SettingsResourcePatch.kt b/src/main/kotlin/crimera/patches/twitter/misc/settings/SettingsResourcePatch.kt index 968e883d..a14a5ec7 100644 --- a/src/main/kotlin/crimera/patches/twitter/misc/settings/SettingsResourcePatch.kt +++ b/src/main/kotlin/crimera/patches/twitter/misc/settings/SettingsResourcePatch.kt @@ -6,14 +6,14 @@ import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.util.ResourceGroup +import app.revanced.util.appendStrings import app.revanced.util.copyResources -import app.revanced.util.copyXmlNode import org.w3c.dom.Element @Patch( compatiblePackages = [CompatiblePackage("com.twitter.android")], ) -object SettingsResourcePatch: ResourcePatch() { +object SettingsResourcePatch : ResourcePatch() { override fun execute(context: ResourceContext) { val settingsRoot = context["res/xml/settings_root.xml"] if (!settingsRoot.exists()) throw PatchException("settings_root not found") @@ -37,7 +37,8 @@ object SettingsResourcePatch: ResourcePatch() { context.xmlEditor["res/layout/main_activity_app_bar.xml"].use { editor -> val parent = editor.file.getElementsByTagName("FrameLayout").item(1) as Element - val sideBtn = editor.file.createElement("app.revanced.integrations.twitter.settings.widgets.PikoSettingsButton") + val sideBtn = + editor.file.createElement("app.revanced.integrations.twitter.settings.widgets.PikoSettingsButton") sideBtn.setAttribute("android:text", "Piko") sideBtn.setAttribute("android:textAllCaps", "false") sideBtn.setAttribute("android:background", "?android:attr/selectableItemBackground") @@ -53,31 +54,19 @@ object SettingsResourcePatch: ResourcePatch() { } //credits @inotia00 - context.copyXmlNode("twitter/settings", "values/strings.xml", "resources") - context.copyXmlNode("twitter/settings", "values/arrays.xml", "resources") + context.appendStrings("twitter/settings", "values/strings.xml") + context.appendStrings("twitter/settings", "values/arrays.xml") /** * create directory for the untranslated language resources */ - //Strings val languages = arrayOf( - "es", - "ar", - "ja", - "hi", - "in", - "zh-rCN", - "ru", - "pl", - "pt-rBR", - "v21", - "tr", - "zh-rTW" + "es", "ar", "ja", "hi", "in", "zh-rCN", "ru", "pl", "pt-rBR", "v21", "tr", "zh-rTW" ).map { "values-$it" } languages.forEach { if (context["res/$it"].exists()) { - context.copyXmlNode("twitter/settings", "$it/strings.xml", "resources") + context.appendStrings("twitter/settings", "$it/strings.xml") } else { context["res/$it"].mkdirs() context.copyResources("twitter/settings", ResourceGroup(it, "strings.xml"))