feat(YouTube): Reorganize settings menu (#2737)

Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
Co-authored-by: dic1911 <htk030@protonmail.com>
This commit is contained in:
LisoUseInAIKyrios
2024-03-02 11:27:05 +04:00
committed by GitHub
parent 0342c79c17
commit 36132df4be
80 changed files with 606 additions and 505 deletions

View File

@ -41,12 +41,18 @@ abstract class BaseSettingsResourcePatch(
}
override fun close() {
fun Node.addPreference(preference: BasePreference) {
fun Node.addPreference(preference: BasePreference, prepend: Boolean = false) {
preference.serialize(ownerDocument) { resource ->
// TODO: Currently, resources can only be added to "values", which may not be the correct place.
// It may be necessary to ask for the desired resourceValue in the future.
AddResourcesPatch("values", resource)
}.let(this::appendChild)
}.let { preferenceNode ->
if (prepend && firstChild != null) {
insertBefore(preferenceNode, firstChild)
} else {
appendChild(preferenceNode)
}
}
}
// Add the root preference to an existing fragment if needed.
@ -54,7 +60,7 @@ abstract class BaseSettingsResourcePatch(
context.xmlEditor["res/xml/$fragment.xml"].use { editor ->
val document = editor.file
document.getNode("PreferenceScreen").addPreference(intentPreference)
document.getNode("PreferenceScreen").addPreference(intentPreference, true)
}
}

View File

@ -1,9 +1,10 @@
package app.revanced.patches.shared.misc.settings.preference
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import java.io.Closeable
abstract class BasePreferenceScreen(
private val root: MutableSet<Screen> = mutableSetOf()
private val root: MutableSet<Screen> = mutableSetOf(),
) : Closeable {
override fun close() {
@ -24,33 +25,27 @@ abstract class BasePreferenceScreen(
titleKey: String = "${key}_title",
private val summaryKey: String? = "${key}_summary",
preferences: MutableSet<BasePreference> = mutableSetOf(),
val categories: MutableSet<Category> = mutableSetOf()
val categories: MutableSet<Category> = mutableSetOf(),
private val sorting: Sorting = Sorting.BY_TITLE,
) : BasePreferenceCollection(key, titleKey, preferences) {
/**
* Initialize using title and summary keys with suffix "_title" and "_summary".
*/
constructor(
key: String? = null,
preferences: MutableSet<BasePreference> = mutableSetOf(),
categories: MutableSet<Category> = mutableSetOf()
) : this(key, key + "_title", key + "_summary", preferences, categories)
override fun transform(): PreferenceScreen {
return PreferenceScreen(
key,
titleKey,
summaryKey,
sorting,
// Screens and preferences are sorted at runtime by integrations code,
// so they appear in alphabetical order for the localized language in use.
preferences = preferences + categories.map { it.transform() }
// so title sorting uses the localized language in use.
preferences = preferences + categories.map { it.transform() },
)
}
private fun ensureScreenInserted() {
// Add to screens if not yet done
if (!root.contains(this))
if (!root.contains(this)) {
root.add(this)
}
}
fun addPreferences(vararg preferences: BasePreference) {
@ -61,13 +56,13 @@ abstract class BasePreferenceScreen(
open inner class Category(
key: String? = null,
titleKey: String = "${key}_title",
preferences: MutableSet<BasePreference> = mutableSetOf()
preferences: MutableSet<BasePreference> = mutableSetOf(),
) : BasePreferenceCollection(key, titleKey, preferences) {
override fun transform(): PreferenceCategory {
return PreferenceCategory(
key,
titleKey,
preferences = preferences
preferences = preferences,
)
}
@ -75,8 +70,9 @@ abstract class BasePreferenceScreen(
ensureScreenInserted()
// Add to the categories if not done yet.
if (!categories.contains(this))
if (!categories.contains(this)) {
categories.add(this)
}
this.preferences.addAll(preferences)
}
@ -86,8 +82,8 @@ abstract class BasePreferenceScreen(
abstract class BasePreferenceCollection(
val key: String? = null,
val titleKey: String = "${key}_title",
val preferences: MutableSet<BasePreference> = mutableSetOf()
val preferences: MutableSet<BasePreference> = mutableSetOf(),
) {
abstract fun transform(): BasePreference
}
}
}

View File

@ -1,19 +1,16 @@
package app.revanced.patches.shared.misc.settings.preference
import app.revanced.patches.shared.misc.settings.preference.IntentPreference.Intent
import app.revanced.util.resource.BaseResource
import org.w3c.dom.Document
/**
* A preference that opens an intent.
*
* @param key The preference key. If null, other parameters must be specified.
* @param key Optional preference key.
* @param titleKey The preference title key.
* @param summaryKey The preference summary key.
* @param tag The preference tag.
* @param intent The intent to open.
*
* @see Intent
*/
class IntentPreference(
key: String? = null,
@ -21,7 +18,7 @@ class IntentPreference(
summaryKey: String? = "${key}_summary",
tag: String = "Preference",
val intent: Intent,
) : BasePreference(null, titleKey, summaryKey, tag) {
) : BasePreference(key, titleKey, summaryKey, tag) {
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
super.serialize(ownerDocument, resourceCallback).apply {

View File

@ -6,10 +6,12 @@ import org.w3c.dom.Document
/**
* A non-interactive preference.
*
* Typically used to present static text, but also used for custom integration code that responds to taps.
*
* @param key The preference key.
* @param summaryKey The preference summary key.
* @param tag The preference tag.
* @param selectable Whether the preference is selectable.
* @param tag The tag or full class name of the preference.
* @param selectable If the preference is selectable and responds to tap events.
*/
@Suppress("MemberVisibilityCanBePrivate")
class NonInteractivePreference(

View File

@ -9,6 +9,8 @@ import org.w3c.dom.Document
* @param key The key of the preference. If null, other parameters must be specified.
* @param titleKey The key of the preference title.
* @param summaryKey The key of the preference summary.
* @param sorting Sorting to use. If the sorting is not [Sorting.UNSORTED],
* then the key parameter will be modified to include the sort type.
* @param tag The tag or full class name of the preference.
* @param preferences The preferences in this screen.
*/
@ -17,14 +19,40 @@ open class PreferenceScreen(
key: String? = null,
titleKey: String = "${key}_title",
summaryKey: String? = "${key}_summary",
sorting: Sorting = Sorting.BY_TITLE,
tag: String = "PreferenceScreen",
val preferences: Set<BasePreference>
) : BasePreference(key, titleKey, summaryKey, tag) {
val preferences: Set<BasePreference>,
// Alternatively, instead of repurposing the key for sorting,
// an extra bundle parameter can be added to the preferences XML declaration.
// This would require bundling and referencing an additional XML file
// or adding new attributes to the attrs.xml file.
// Since the key value is not currently used by integrations,
// for now it's much simpler to modify the key to include the sort parameter.
) : BasePreference(if (sorting == Sorting.UNSORTED) key else (key + sorting.keySuffix), titleKey, summaryKey, tag) {
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
super.serialize(ownerDocument, resourceCallback).apply {
preferences.forEach {
appendChild(it.serialize(ownerDocument, resourceCallback))
}
}
/**
* How a PreferenceScreen should be sorted.
*/
enum class Sorting(val keySuffix: String) {
/**
* Sort by the localized preference title.
*/
BY_TITLE("_sort_by_title"),
/**
* Sort by the preference keys.
*/
BY_KEY("_sort_by_key"),
/**
* Unspecified sorting.
*/
UNSORTED("_sort_by_unsorted"),
}
}