Skip to content

Commit

Permalink
feat(youtube): import / export of revanced settings (#2077)
Browse files Browse the repository at this point in the history
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
  • Loading branch information
LisoUseInAIKyrios and oSumAtrIX committed May 15, 2023
1 parent 78803f8 commit b59cb3e
Show file tree
Hide file tree
Showing 79 changed files with 437 additions and 572 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,26 @@ import org.w3c.dom.Element
*
* @param key The key of the preference.
* @param title The title of the preference.
* @param tag The tag of the preference.
* @param summary The summary of the preference.
*/
internal abstract class BasePreference(
override val key: String,
override val title: StringResource,
) : IPreference {

val key: String?,
val title: StringResource,
val summary: StringResource? = null,
val tag: String
) {
/**
* Serialize preference element to XML.
* Overriding methods should invoke super and operate on its return value.
* @param ownerDocument Target document to create elements from.
* @param resourceCallback Called when a resource has been processed.
* @return The serialized element.
*/
open fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)? = null): Element {
return ownerDocument.createElement(tag).apply {
if(key.isNotEmpty())
setAttribute("android:key", key)
setAttribute("android:title", "@string/${title.also { resourceCallback?.invoke(it) }.name}")
open fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit): Element =
ownerDocument.createElement(tag).apply {
if (key != null) setAttribute("android:key", key)
setAttribute("android:title", "@string/${title.also { resourceCallback.invoke(it) }.name}")
addSummary(summary?.also { resourceCallback.invoke(it) })
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@ import org.w3c.dom.Element
* Base resource class for all resources.
*
* @param name The name of the resource.
* @param tag The tag of the resource.
*/
internal abstract class BaseResource(
override val name: String
) : IResource {

val name: String,
val tag: String
) {
/**
* Serialize resource element to XML.
* Overriding methods should invoke super and operate on its return value.
* @param ownerDocument Target document to create elements from.
* @param resourceCallback Called when a resource has been processed.
*/
open fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)? = null): Element {
open fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit = { }): Element {
return ownerDocument.createElement(tag).apply {
setAttribute("name", name)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import org.w3c.dom.Node
* @param resource The resource to add.
* @param resourceCallback Called when a resource has been processed.
*/
internal fun Node.addResource(resource: BaseResource, resourceCallback: ((IResource) -> Unit)? = null) {
internal fun Node.addResource(resource: BaseResource, resourceCallback: (BaseResource) -> Unit = { }) {
appendChild(resource.serialize(ownerDocument, resourceCallback))
}

Expand All @@ -20,7 +20,7 @@ internal fun Node.addResource(resource: BaseResource, resourceCallback: ((IResou
* @param preference The preference to add.
* @param resourceCallback Called when a resource has been processed.
*/
internal fun Node.addPreference(preference: BasePreference, resourceCallback: ((IResource) -> Unit)? = null) {
internal fun Node.addPreference(preference: BasePreference, resourceCallback: ((BaseResource) -> Unit) = { }) {
appendChild(preference.serialize(ownerDocument, resourceCallback))
}

Expand All @@ -30,10 +30,11 @@ internal fun Element.addSummary(summaryResource: StringResource?, summaryType: S
}

internal fun <T> Element.addDefault(default: T) {
if (default is Boolean && !(default as Boolean)) return // No need to include the default, as no value already means 'false'
default?.let {
setAttribute(
"android:defaultValue", when (it) {
is Boolean -> if (it) "true" else "false"
is Boolean -> it.toString()
is String -> it
else -> throw IllegalArgumentException("Unsupported default value type: ${it::class.java.name}")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package app.revanced.patches.shared.settings.preference

import app.revanced.patches.shared.settings.preference.impl.StringResource
import org.w3c.dom.Document

/**
* Base preference class that also has a default value.
*
* @param key The key of the preference.
* @param title The title of the preference.
* @param tag The tag of the preference.
* @param summary The summary of the preference.
* @param default The default value of the preference.
*/
internal abstract class DefaultBasePreference<T>(
key: String?,
title: StringResource,
summary: StringResource? = null,
tag: String,
val default: T? = null,
) : BasePreference(key, title, summary, tag) {

/**
* Serialize preference element to XML.
* Overriding methods should invoke super and operate on its return value.
* @param ownerDocument Target document to create elements from.
* @param resourceCallback Called when a resource has been processed.
* @return The serialized element.
*/
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
super.serialize(ownerDocument, resourceCallback).apply { addDefault(default) }
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,34 +1,29 @@
package app.revanced.patches.shared.settings.preference.impl

import app.revanced.patches.shared.settings.preference.BaseResource
import app.revanced.patches.shared.settings.preference.IResource
import org.w3c.dom.Document
import org.w3c.dom.Element

// TODO: allow specifying an array resource file instead of using a list of StringResources
/**
* Represents an array resource.
* An array resource.
*
* @param name The name of the array resource.
* @param items The items of the array resource.
*/
// TODO: allow specifying an array resource file instead of using a list of StringResources
internal data class ArrayResource(
override val name: String,
internal class ArrayResource(
name: String,
val items: List<StringResource>
) : BaseResource(name) {
override val tag = "string-array"

override fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)?): Element {
return super.serialize(ownerDocument, resourceCallback).apply {
) : BaseResource(name, "string-array") {
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
super.serialize(ownerDocument, resourceCallback).apply {
setAttribute("name", name)

items.forEach { item ->
resourceCallback?.invoke(item)
resourceCallback.invoke(item)

this.appendChild(ownerDocument.createElement("item").also { itemNode ->
itemNode.textContent = "@string/${item.name}"
})
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package app.revanced.patches.shared.settings.preference.impl

enum class InputType(val type: String) {
STRING("text"), // TODO: rename to "TEXT"
TEXT("text"),
TEXT_CAP_CHARACTERS("textCapCharacters"),
TEXT_MULTI_LINE("textMultiLine"),
NUMBER("number"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package app.revanced.patches.shared.settings.preference.impl

import app.revanced.patches.shared.settings.preference.BasePreference
import app.revanced.patches.shared.settings.preference.IResource
import app.revanced.patches.shared.settings.preference.addDefault
import app.revanced.patches.shared.settings.preference.BaseResource
import app.revanced.patches.shared.settings.preference.DefaultBasePreference
import app.revanced.patches.shared.settings.preference.addSummary
import org.w3c.dom.Document
import org.w3c.dom.Element

/**
* List preference.
Expand All @@ -14,25 +12,21 @@ import org.w3c.dom.Element
* @param title The title of the list preference.
* @param entries The human-readable entries of the list preference.
* @param entryValues The entry values of the list preference.
* @param default The default entry value of the list preference.
* @param summary The summary of the list preference.
* @param default The default entry value of the list preference.
*/
internal class ListPreference(
key: String,
title: StringResource,
val entries: ArrayResource,
val entryValues: ArrayResource,
val default: String? = null,
val summary: StringResource? = null
) : BasePreference(key, title) {
override val tag: String = "ListPreference"

override fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)?): Element {
return super.serialize(ownerDocument, resourceCallback).apply {
setAttribute("android:entries", "@array/${entries.also { resourceCallback?.invoke(it) }.name}")
setAttribute("android:entryValues", "@array/${entryValues.also { resourceCallback?.invoke(it) }.name}")
addDefault(default)
summary: StringResource? = null,
default: String? = null,
) : DefaultBasePreference<String>(key, title, summary, "ListPreference", default) {
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
super.serialize(ownerDocument, resourceCallback).apply {
setAttribute("android:entries", "@array/${entries.also { resourceCallback.invoke(it) }.name}")
setAttribute("android:entryValues", "@array/${entryValues.also { resourceCallback.invoke(it) }.name}")
addSummary(summary)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
package app.revanced.patches.shared.settings.preference.impl

import app.revanced.patches.shared.settings.preference.BasePreference
import app.revanced.patches.shared.settings.preference.IResource
import app.revanced.patches.shared.settings.preference.BaseResource
import app.revanced.patches.shared.settings.preference.addSummary
import org.w3c.dom.Document
import org.w3c.dom.Element

/**
* A simple static title and summary that is not backed by any preference key/value,
* and cannot be changed by or interacted with by the user,
* A non interactive preference.
*
* Not backed by any preference key/value,
* and cannot be changed by or interacted with by the user.
*
* @param title The title of the preference.
* @param summary The summary of the text preference.
*/
internal class NonInteractivePreference(
title: StringResource,
val summary: StringResource,
) : BasePreference("", title) {
override val tag: String = "Preference"

override fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)?): Element {
summary: StringResource,
) : BasePreference(null, title, summary, "Preference") {
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit): Element {
return super.serialize(ownerDocument, resourceCallback).apply {
addSummary(summary.also { resourceCallback?.invoke(it)
addSummary(summary?.also { resourceCallback.invoke(it)
setAttribute("android:selectable", false.toString())
})
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,41 @@
package app.revanced.patches.shared.settings.preference.impl

import app.revanced.patches.shared.settings.preference.BasePreference
import app.revanced.patches.shared.settings.preference.IResource
import app.revanced.patches.shared.settings.preference.addSummary
import app.revanced.patches.shared.settings.preference.BaseResource
import org.w3c.dom.Document
import org.w3c.dom.Element

/**
* A Preference object.
* A preference object.
*
* @param key The key of the preference.
* @param title The title of the preference.
* @param intent The intent of the preference.
* @param summary The summary of the text preference.
* @param intent The intent of the preference.
*/
internal class Preference(
key: String,
title: StringResource,
val intent: Intent,
val summary: StringResource? = null
) : BasePreference(key, title) {
override val tag: String = "Preference"

/* Key-less constructor */
summary: StringResource,
val intent: Intent
) : BasePreference(key, title, summary, "Preference") {
constructor(
title: StringResource,
intent: Intent,
summary: StringResource? = null
) : this("", title, intent, summary)

override fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)?): Element {
return super.serialize(ownerDocument, resourceCallback).apply {
addSummary(summary?.also { resourceCallback?.invoke(it) })
summary: StringResource,
intent: Intent
) : this("", title, summary, intent)

override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
super.serialize(ownerDocument, resourceCallback).apply {
this.appendChild(ownerDocument.createElement("intent").also { intentNode ->
intentNode.setAttribute("android:targetPackage", intent.targetPackage)
intentNode.setAttribute("android:data", intent.data)
intentNode.setAttribute("android:targetClass", intent.targetClass)
})
}
}

data class Intent(val targetPackage: String, val data: String, val targetClass: String)
internal class Intent(
internal val targetPackage: String,
internal val data: String,
internal val targetClass: String
)
}

0 comments on commit b59cb3e

Please sign in to comment.