|
1 | 1 | package app.revanced.patches.music.misc.translations |
2 | 2 |
|
3 | 3 | import app.revanced.patcher.data.ResourceContext |
| 4 | +import app.revanced.patcher.patch.PatchException |
| 5 | +import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption |
4 | 6 | import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE |
5 | 7 | import app.revanced.patches.music.utils.settings.SettingsPatch |
| 8 | +import app.revanced.patches.shared.translations.APP_LANGUAGES |
6 | 9 | import app.revanced.patches.shared.translations.TranslationsUtils.copyXml |
| 10 | +import app.revanced.patches.shared.translations.TranslationsUtils.updateStringsXml |
7 | 11 | import app.revanced.util.patch.BaseResourcePatch |
| 12 | +import java.io.File |
8 | 13 |
|
9 | | -@Suppress("unused") |
| 14 | +// Array of supported RVX languages, each represented by its language code. |
| 15 | +val LANGUAGES = arrayOf( |
| 16 | + "bg-rBG", "bn", "cs-rCZ", "el-rGR", "es-rES", "fr-rFR", "id-rID", "in", "it-rIT", |
| 17 | + "ja-rJP", "ko-rKR", "nl-rNL", "pl-rPL", "pt-rBR", "ro-rRO", "ru-rRU", "tr-rTR", "uk-rUA", |
| 18 | + "vi-rVN", "zh-rCN", "zh-rTW" |
| 19 | +) |
| 20 | + |
| 21 | +@Suppress("DEPRECATION", "unused") |
10 | 22 | object TranslationsPatch : BaseResourcePatch( |
11 | 23 | name = "Translations", |
12 | 24 | description = "Adds Crowdin translations for YouTube Music.", |
13 | 25 | dependencies = setOf(SettingsPatch::class), |
14 | 26 | compatiblePackages = COMPATIBLE_PACKAGE |
15 | 27 | ) { |
| 28 | + private var CustomLanguage by stringPatchOption( |
| 29 | + key = "CustomLanguage", |
| 30 | + default = "", |
| 31 | + title = "Custom language file", |
| 32 | + description = """ |
| 33 | + The file path to the strings.xml file. |
| 34 | + Please note that applying the strings.xml file will overwrite all existing language translations. |
| 35 | + """.trimIndent() |
| 36 | + ) |
| 37 | + |
| 38 | + private var SelectedLanguages by stringPatchOption( |
| 39 | + key = "SelectedLanguages", |
| 40 | + default = LANGUAGES.joinToString(", "), |
| 41 | + title = "Selected RVX languages", |
| 42 | + description = "Selected RVX languages that will be added." |
| 43 | + ) |
| 44 | + |
| 45 | + private var SelectedAppLanguages by stringPatchOption( |
| 46 | + key = "SelectedAppLanguages", |
| 47 | + default = APP_LANGUAGES.joinToString(", "), |
| 48 | + title = "Selected app languages", |
| 49 | + description = "Selected app languages that will be kept, languages that are not in the list will be removed from the app." |
| 50 | + ) |
| 51 | + |
16 | 52 | override fun execute(context: ResourceContext) { |
17 | | - context.copyXml( |
18 | | - "music", |
19 | | - arrayOf( |
20 | | - "bg-rBG", |
21 | | - "bn", |
22 | | - "cs-rCZ", |
23 | | - "el-rGR", |
24 | | - "es-rES", |
25 | | - "fr-rFR", |
26 | | - "id-rID", |
27 | | - "in", |
28 | | - "it-rIT", |
29 | | - "ja-rJP", |
30 | | - "ko-rKR", |
31 | | - "nl-rNL", |
32 | | - "pl-rPL", |
33 | | - "pt-rBR", |
34 | | - "ro-rRO", |
35 | | - "ru-rRU", |
36 | | - "tr-rTR", |
37 | | - "uk-rUA", |
38 | | - "vi-rVN", |
39 | | - "zh-rCN", |
40 | | - "zh-rTW" |
41 | | - ) |
42 | | - ) |
| 53 | + CustomLanguage?.takeIf { it.isNotEmpty() }?.let { customLang -> |
| 54 | + try { |
| 55 | + val customLangFile = File(customLang) |
| 56 | + if (!customLangFile.exists() || !customLangFile.isFile || customLangFile.name != "strings.xml") { |
| 57 | + throw PatchException("Invalid custom language file: $customLang") |
| 58 | + } |
| 59 | + val resourceDirectory = context["res"].resolve("values") |
| 60 | + val destinationFile = resourceDirectory.resolve("strings.xml") |
| 61 | + |
| 62 | + updateStringsXml(customLangFile, destinationFile) |
| 63 | + } catch (e: Exception) { |
| 64 | + throw PatchException("Error copying custom language file: ${e.message}") |
| 65 | + } |
| 66 | + } ?: run { |
| 67 | + // Process selected RVX languages if no custom language file is set. |
| 68 | + val selectedLanguagesArray = SelectedLanguages!!.split(",").map { it.trim() }.toTypedArray() |
| 69 | + val filteredLanguages = LANGUAGES.filter { it in selectedLanguagesArray }.toTypedArray() |
| 70 | + context.copyXml("youtube", filteredLanguages) |
| 71 | + } |
| 72 | + |
| 73 | + // Process selected app languages. |
| 74 | + val selectedAppLanguagesArray = SelectedAppLanguages!!.split(",").map { it.trim() }.toTypedArray() |
| 75 | + val filteredAppLanguages = APP_LANGUAGES.filter { it in selectedAppLanguagesArray }.toTypedArray() |
| 76 | + val resourceDirectory = context["res"] |
43 | 77 |
|
| 78 | + // Remove unselected app languages. |
| 79 | + APP_LANGUAGES.filter { it !in filteredAppLanguages }.forEach { language -> |
| 80 | + resourceDirectory.resolve("values-$language").takeIf { it.exists() && it.isDirectory }?.deleteRecursively() |
| 81 | + } |
44 | 82 | } |
45 | 83 | } |
0 commit comments