diff --git a/.github/workflows/sync_crowdin.yml b/.github/workflows/sync_crowdin.yml
new file mode 100644
index 0000000000..e0d0912b72
--- /dev/null
+++ b/.github/workflows/sync_crowdin.yml
@@ -0,0 +1,39 @@
+name: Sync Crowdin
+
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: 0 * 1 * *
+ push:
+ paths:
+ - /src/main/resources/addresources/values/strings.xml
+
+jobs:
+ sync:
+ name: Sync translations
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Sync translations
+ uses: crowdin/github-action@v1
+ with:
+ config: crowdin.yml
+ upload_sources: true
+ upload_translations: false
+ download_translations: true
+ localization_branch_name: feat/translations
+ create_pull_request: true
+ pull_request_title: "chore: Sync translations"
+ pull_request_body: "Sync translations from [crowdin.com/project/revanced](https://crowdin.com/project/revanced)"
+ pull_request_base_branch_name: "dev"
+ commit_message: "chore: Sync translations"
+ github_user_name: revanced-bot
+ github_user_email: github@revanced.app
+ env:
+ GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
+ CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
+ CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a4078bad06..9afb840949 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+# [4.5.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.5.0-dev.1...v4.5.0-dev.2) (2024-03-30)
+
+
+### Features
+
+* **YouTube - GmsCore:** Require ignoring battery optimizations ([#2952](https://github.com/ReVanced/revanced-patches/issues/2952)) ([c0bef25](https://github.com/ReVanced/revanced-patches/commit/c0bef255909ca884838675ca6f7ac5b0e2e21730))
+
+# [4.5.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.4.0...v4.5.0-dev.1) (2024-03-29)
+
+
+### Features
+
+* **YouTube - Alternative thumbnails:** Selectively enable for home / subscription / search ([#2926](https://github.com/ReVanced/revanced-patches/issues/2926)) ([8549e1b](https://github.com/ReVanced/revanced-patches/commit/8549e1ba58ad1e1608f5e3ceacd31eeb94578949))
+
# [4.4.0](https://github.com/ReVanced/revanced-patches/compare/v4.3.0...v4.4.0) (2024-03-27)
diff --git a/crowdin.yml b/crowdin.yml
new file mode 100644
index 0000000000..4ac3cb98b3
--- /dev/null
+++ b/crowdin.yml
@@ -0,0 +1,8 @@
+project_id_env: "CROWDIN_PROJECT_ID"
+api_token_env: "CROWDIN_PERSONAL_TOKEN"
+
+preserve_hierarchy: false
+files:
+ - source: src/main/resources/addresources/values/strings.xml
+ translation: src/main/resources/addresources/values-%android_code%/strings.xml
+ skip_untranslated_strings: true
diff --git a/gradle.properties b/gradle.properties
index fa4f042dc7..9bb54304c5 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
org.gradle.parallel = true
org.gradle.caching = true
kotlin.code.style = official
-version = 4.4.0
+version = 4.5.0-dev.2
diff --git a/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt
index 65d9053960..060d3447c7 100644
--- a/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt
@@ -34,5 +34,5 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
PrimeMethodFingerprint,
),
) {
- override val gmsCoreVendor by gmsCoreVendorGroupIdOption
+ override val gmsCoreVendorGroupId by gmsCoreVendorGroupIdOption
}
diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt
index f7bfcb6efd..9d2544b7e8 100644
--- a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt
@@ -2,7 +2,7 @@ package app.revanced.patches.shared.misc.gms
import app.revanced.patcher.PatchClass
import app.revanced.patcher.data.BytecodeContext
-import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
+import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.MethodFingerprint
@@ -12,7 +12,7 @@ import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch.Constants.AC
import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch.Constants.AUTHORITIES
import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch.Constants.PERMISSIONS
import app.revanced.patches.shared.misc.gms.fingerprints.GmsCoreSupportFingerprint
-import app.revanced.patches.shared.misc.gms.fingerprints.GmsCoreSupportFingerprint.GET_GMS_CORE_VENDOR_METHOD_NAME
+import app.revanced.patches.shared.misc.gms.fingerprints.GmsCoreSupportFingerprint.GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME
import app.revanced.util.exception
import app.revanced.util.getReference
import app.revanced.util.returnEarly
@@ -32,7 +32,7 @@ import com.android.tools.smali.dexlib2.util.MethodUtil
* @param toPackageName The package name to fall back to if no custom package name is specified in patch options.
* @param primeMethodFingerprint The fingerprint of the "prime" method that needs to be patched.
* @param earlyReturnFingerprints The fingerprints of methods that need to be returned early.
- * @param mainActivityOnCreateFingerprint The fingerprint of the main activity's onCreate method.
+ * @param mainActivityOnCreateFingerprint The fingerprint of the main activity onCreate method.
* @param integrationsPatchDependency The patch responsible for the integrations.
* @param gmsCoreSupportResourcePatch The corresponding resource patch that is used to patch the resources.
* @param dependencies Additional dependencies of this patch.
@@ -60,7 +60,10 @@ abstract class BaseGmsCoreSupportPatch(
integrationsPatchDependency,
) + dependencies,
compatiblePackages = compatiblePackages,
- fingerprints = setOf(GmsCoreSupportFingerprint, mainActivityOnCreateFingerprint) + fingerprints,
+ fingerprints = setOf(
+ GmsCoreSupportFingerprint,
+ mainActivityOnCreateFingerprint,
+ ) + fingerprints,
requiresIntegrations = true,
) {
init {
@@ -68,7 +71,7 @@ abstract class BaseGmsCoreSupportPatch(
gmsCoreSupportResourcePatch.options.values.forEach(options::register)
}
- internal abstract val gmsCoreVendor: String?
+ internal abstract val gmsCoreVendorGroupId: String?
override fun execute(context: BytecodeContext) {
val packageName = ChangePackageNamePatch.setOrGetFallbackPackageName(toPackageName)
@@ -93,16 +96,17 @@ abstract class BaseGmsCoreSupportPatch(
// Return these methods early to prevent the app from crashing.
earlyReturnFingerprints.toList().returnEarly()
- // Check the availability of GmsCore.
- mainActivityOnCreateFingerprint.result?.mutableMethod?.addInstruction(
- 1, // Hack to not disturb other patches (such as the integrations patch).
- "invoke-static {}, Lapp/revanced/integrations/shared/GmsCoreSupport;->checkAvailability()V",
+ // Verify GmsCore is installed and whitelisted for power optimizations and background usage.
+ mainActivityOnCreateFingerprint.result?.mutableMethod?.addInstructions(
+ 1, // Hack to not disturb other patches (such as the YTMusic integrations patch).
+ "invoke-static/range { p0 .. p0 }, Lapp/revanced/integrations/shared/GmsCoreSupport;->" +
+ "checkGmsCore(Landroid/content/Context;)V",
) ?: throw mainActivityOnCreateFingerprint.exception
// Change the vendor of GmsCore in ReVanced Integrations.
GmsCoreSupportFingerprint.result?.mutableClass?.methods
- ?.single { it.name == GET_GMS_CORE_VENDOR_METHOD_NAME }
- ?.replaceInstruction(0, "const-string v0, \"$gmsCoreVendor\"")
+ ?.single { it.name == GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME }
+ ?.replaceInstruction(0, "const-string v0, \"$gmsCoreVendorGroupId\"")
?: throw GmsCoreSupportFingerprint.exception
}
@@ -146,10 +150,10 @@ abstract class BaseGmsCoreSupportPatch(
in PERMISSIONS,
in ACTIONS,
in AUTHORITIES,
- -> referencedString.replace("com.google", gmsCoreVendor!!)
+ -> referencedString.replace("com.google", gmsCoreVendorGroupId!!)
// No vendor prefix for whatever reason...
- "subscribedfeeds" -> "$gmsCoreVendor.subscribedfeeds"
+ "subscribedfeeds" -> "$gmsCoreVendorGroupId.subscribedfeeds"
else -> null
}
@@ -162,7 +166,7 @@ abstract class BaseGmsCoreSupportPatch(
if (str.startsWith(uriPrefix)) {
return str.replace(
uriPrefix,
- "content://${authority.replace("com.google", gmsCoreVendor!!)}",
+ "content://${authority.replace("com.google", gmsCoreVendorGroupId!!)}",
)
}
}
@@ -170,7 +174,7 @@ abstract class BaseGmsCoreSupportPatch(
// gms also has a 'subscribedfeeds' authority, check for that one too
val subFeedsUriPrefix = "content://subscribedfeeds"
if (str.startsWith(subFeedsUriPrefix)) {
- return str.replace(subFeedsUriPrefix, "content://$gmsCoreVendor.subscribedfeeds")
+ return str.replace(subFeedsUriPrefix, "content://$gmsCoreVendorGroupId.subscribedfeeds")
}
}
diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt
index eef039f740..f77a6d3616 100644
--- a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt
@@ -121,7 +121,6 @@ abstract class BaseGmsCoreSupportResourcePatch(
}
private companion object {
- private const val VANCED_VENDOR = "com.mgoogle"
private const val PACKAGE_NAME_REGEX_PATTERN = "^[a-z]\\w*(\\.[a-z]\\w*)+\$"
}
}
diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/gms/fingerprints/GmsCoreSupportFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/misc/gms/fingerprints/GmsCoreSupportFingerprint.kt
index 79be107f90..52cef8fd6b 100644
--- a/src/main/kotlin/app/revanced/patches/shared/misc/gms/fingerprints/GmsCoreSupportFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/shared/misc/gms/fingerprints/GmsCoreSupportFingerprint.kt
@@ -5,7 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
internal object GmsCoreSupportFingerprint : MethodFingerprint(
customFingerprint = { _, classDef ->
classDef.type.endsWith("GmsCoreSupport;")
- }
+ },
) {
- const val GET_GMS_CORE_VENDOR_METHOD_NAME = "getGmsCoreVendor"
+ const val GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME = "getGmsCoreVendorGroupId"
}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt
index e9f2c920be..6147a3d546 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt
@@ -14,7 +14,7 @@ import app.revanced.util.resultOrThrow
@Patch(
name = "Downloads",
- description = "Adds support to download videos with an external downloader app" +
+ description = "Adds support to download videos with an external downloader app " +
"using the in-app download button or a video player action button.",
dependencies = [
DownloadsResourcePatch::class,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt
index 4daa6248fa..2f624435b1 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt
@@ -22,6 +22,8 @@ import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.reques
import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.request.callback.OnResponseStartedFingerprint
import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.request.callback.OnSucceededFingerprint
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
+import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
+import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.AccessFlags
@@ -38,6 +40,8 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
IntegrationsPatch::class,
SettingsPatch::class,
AddResourcesPatch::class,
+ NavigationBarHookPatch::class,
+ PlayerTypeHookPatch::class
],
compatiblePackages = [
CompatiblePackage(
@@ -127,25 +131,45 @@ object AlternativeThumbnailsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
+ val entries = "revanced_alt_thumbnail_options_entries"
+ val values = "revanced_alt_thumbnail_options_entry_values"
SettingsPatch.PreferenceScreen.ALTERNATIVE_THUMBNAILS.addPreferences(
- NonInteractivePreference(
- "revanced_alt_thumbnail_about",
- null, // Summary is dynamically updated based on the current settings.
- tag = "app.revanced.integrations.youtube.settings.preference.AlternativeThumbnailsStatusPreference",
+ ListPreference("revanced_alt_thumbnail_home",
+ summaryKey = null,
+ entriesKey = entries,
+ entryValuesKey = values
+ ),
+ ListPreference("revanced_alt_thumbnail_subscription",
+ summaryKey = null,
+ entriesKey = entries,
+ entryValuesKey = values
+ ),
+ ListPreference("revanced_alt_thumbnail_library",
+ summaryKey = null,
+ entriesKey = entries,
+ entryValuesKey = values
+ ),
+ ListPreference("revanced_alt_thumbnail_player",
+ summaryKey = null,
+ entriesKey = entries,
+ entryValuesKey = values
+ ),
+ ListPreference("revanced_alt_thumbnail_search",
+ summaryKey = null,
+ entriesKey = entries,
+ entryValuesKey = values
),
- SwitchPreference("revanced_alt_thumbnail_dearrow"),
- SwitchPreference("revanced_alt_thumbnail_dearrow_connection_toast"),
- TextPreference("revanced_alt_thumbnail_dearrow_api_url"),
NonInteractivePreference(
"revanced_alt_thumbnail_dearrow_about",
// Custom about preference with link to the DeArrow website.
tag = "app.revanced.integrations.youtube.settings.preference.AlternativeThumbnailsAboutDeArrowPreference",
selectable = true,
),
- SwitchPreference("revanced_alt_thumbnail_stills"),
- ListPreference("revanced_alt_thumbnail_stills_time", summaryKey = null),
- SwitchPreference("revanced_alt_thumbnail_stills_fast"),
+ SwitchPreference("revanced_alt_thumbnail_dearrow_connection_toast"),
+ TextPreference("revanced_alt_thumbnail_dearrow_api_url"),
NonInteractivePreference("revanced_alt_thumbnail_stills_about"),
+ SwitchPreference("revanced_alt_thumbnail_stills_fast"),
+ ListPreference("revanced_alt_thumbnail_stills_time", summaryKey = null)
)
fun MethodFingerprint.alsoResolve(fingerprint: MethodFingerprint) =
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt
index f7b43a2b60..434ddcaa21 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt
@@ -2,16 +2,14 @@ package app.revanced.patches.youtube.misc.announcements
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
-import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch
-import app.revanced.patches.youtube.shared.fingerprints.MainActivityFingerprint
-import app.revanced.util.exception
-import com.android.tools.smali.dexlib2.Opcode
+import app.revanced.patches.youtube.shared.fingerprints.MainActivityOnCreateFingerprint
+import app.revanced.util.resultOrThrow
@Patch(
name = "Announcements",
@@ -21,7 +19,7 @@ import com.android.tools.smali.dexlib2.Opcode
)
@Suppress("unused")
object AnnouncementsPatch : BytecodePatch(
- setOf(MainActivityFingerprint)
+ setOf(MainActivityOnCreateFingerprint)
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch;"
@@ -33,16 +31,11 @@ object AnnouncementsPatch : BytecodePatch(
SwitchPreference("revanced_announcements")
)
- val onCreateMethod = MainActivityFingerprint.result?.let {
- it.mutableClass.methods.find { method -> method.name == "onCreate" }
- } ?: throw MainActivityFingerprint.exception
-
- val superCallIndex = onCreateMethod.getInstructions().indexOfFirst { it.opcode == Opcode.INVOKE_SUPER_RANGE }
-
- onCreateMethod.addInstructions(
- superCallIndex + 1,
- "invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->showAnnouncement(Landroid/app/Activity;)V"
+ MainActivityOnCreateFingerprint.resultOrThrow().mutableMethod.addInstructions(
+ // Insert index must be great than the insert index used by GmsCoreSupport,
+ // as both patch the same method and GmsCore check should be first.
+ 1,
+ "invoke-static/range { p0 .. p0 }, $INTEGRATIONS_CLASS_DESCRIPTOR->showAnnouncement(Landroid/app/Activity;)V"
)
-
}
}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt
index ff29023516..6547f0ec32 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt
@@ -9,7 +9,7 @@ import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME
import app.revanced.patches.youtube.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorGroupIdOption
import app.revanced.patches.youtube.misc.gms.fingerprints.*
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
-import app.revanced.patches.youtube.shared.fingerprints.HomeActivityFingerprint
+import app.revanced.patches.youtube.shared.fingerprints.MainActivityOnCreateFingerprint
@Suppress("unused")
object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
@@ -23,7 +23,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
CastDynamiteModuleV2Fingerprint,
CastContextFetchFingerprint,
),
- mainActivityOnCreateFingerprint = HomeActivityFingerprint,
+ mainActivityOnCreateFingerprint = MainActivityOnCreateFingerprint,
integrationsPatchDependency = IntegrationsPatch::class,
dependencies = setOf(
HideCastButtonPatch::class,
@@ -57,5 +57,5 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
PrimeMethodFingerprint,
),
) {
- override val gmsCoreVendor by gmsCoreVendorGroupIdOption
+ override val gmsCoreVendorGroupId by gmsCoreVendorGroupIdOption
}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/shared/fingerprints/MainActivityOnCreateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/shared/fingerprints/MainActivityOnCreateFingerprint.kt
new file mode 100644
index 0000000000..fa63c0fdeb
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/shared/fingerprints/MainActivityOnCreateFingerprint.kt
@@ -0,0 +1,14 @@
+package app.revanced.patches.youtube.shared.fingerprints
+
+import app.revanced.patcher.fingerprint.MethodFingerprint
+
+internal object MainActivityOnCreateFingerprint : MethodFingerprint(
+ returnType = "V",
+ parameters = listOf("Landroid/os/Bundle;"),
+ customFingerprint = { methodDef, classDef ->
+ methodDef.name == "onCreate" &&
+ (classDef.type.endsWith("MainActivity;")
+ // Old versions of YouTube called this class "WatchWhileActivity" instead.
+ || classDef.type.endsWith("WatchWhileActivity;"))
+ }
+)
\ No newline at end of file
diff --git a/src/main/resources/addresources/values/arrays.xml b/src/main/resources/addresources/values/arrays.xml
index 064dcd05b3..5fad2d8841 100644
--- a/src/main/resources/addresources/values/arrays.xml
+++ b/src/main/resources/addresources/values/arrays.xml
@@ -44,15 +44,28 @@
+
+ - @string/revanced_alt_thumbnail_options_entry_1
+ - @string/revanced_alt_thumbnail_options_entry_2
+ - @string/revanced_alt_thumbnail_options_entry_3
+ - @string/revanced_alt_thumbnail_options_entry_4
+
+
+
+ - ORIGINAL
+ - DEARROW
+ - DEARROW_STILL_IMAGES
+ - STILL_IMAGES
+
- @string/revanced_alt_thumbnail_stills_time_entry_1
- @string/revanced_alt_thumbnail_stills_time_entry_2
- @string/revanced_alt_thumbnail_stills_time_entry_3
- - 1
- - 2
- - 3
+ - BEGINNING
+ - MIDDLE
+ - END
diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml
index b799eef24b..b587547558 100644
--- a/src/main/resources/addresources/values/strings.xml
+++ b/src/main/resources/addresources/values/strings.xml
@@ -13,8 +13,12 @@
Import failed: %s
- GmsCore is not installed. Please install.
- GmsCore is failing to run. Please follow the \"Don\'t kill my app\" guide for GmsCore.
+ GmsCore is not installed. Install it.
+ Follow the \"Don\'t kill my app\" guide for GmsCore.
+ Action needed
+ GmsCore is not whitelisted from battery optimization.\n\nFollow the \"Don\'t kill my app\" guide for GmsCore.
+ GmsCore does not have permission to run in the background.\n\nFollow the \"Don\'t kill my app\" guide for GmsCore.
+ Open website
@@ -847,33 +851,31 @@
Invalid seekbar color value. Using default value.
- Thumbnails in use
- Enable DeArrow thumbnails
- Using DeArrow thumbnails
- Not using DeArrow thumbnails
+ Home tab
+ Subscription tab
+ You tab
+ Player playlists, recommendations
+ Search results
+ Original thumbnails
+ DeArrow & Original thumbnails
+ DeArrow & Still captures
+ Still captures
+ DeArrow
+ DeArrow provides crowd-sourced thumbnails for YouTube videos. These thumbnails are often more relevant than those provided by YouTube\n\nIf enabled, video URLs will be sent to the API server and no other data is sent. If a video does not have DeArrow thumbnails, then the original or still captures are shown\n\nTap here to learn more about DeArrow
Show a toast if API is not available
Toast is shown if DeArrow is not available
Toast is not shown if DeArrow is not available
DeArrow API endpoint
- The URL of the DeArrow thumbnail cache endpoint. Do not change this unless you know what you\'re doing
- About DeArrow
- DeArrow provides crowd-sourced thumbnails for YouTube videos. These thumbnails are often more relevant than those provided by YouTube. If enabled, video URLs will be sent to the API server and no other data is sent\n\nTap here to learn more about DeArrow
- Enable still video captures
- Using YouTube still video captures
- Not using YouTube still video captures
- Video time to take the still from
- Beginning of video
- Middle of video
- End of video
+ The URL of the DeArrow thumbnail cache endpoint
+ Still video captures
+ Still captures are taken from the beginning/middle/end of each video. These images are built into YouTube and no external API is used
Use fast still captures
Using medium quality still captures. Thumbnails will load faster, but live streams, unreleased, or very old videos may show blank thumbnails
Using high quality still captures
- About still video captures
- Still captures are taken from the beginning/middle/end of each video. These images are built into YouTube and no external API is used
- Showing original YouTube thumbnails
- Showing still video captures
- Showing DeArrow thumbnails. If a video has no DeArrow thumbnails then the original YouTube thumbnails are shown
- Showing DeArrow thumbnails. If a video has no DeArrow thumbnails then still video captures are shown
+ Video time to take still captures from
+ Beginning of video
+ Middle of video
+ End of video
DeArrow temporarily not available (status code: %s)
DeArrow temporarily not available
@@ -883,6 +885,7 @@
Announcements are not shown on startup
Show announcements on startup
Failed connecting to announcements provider
+ Dismiss
Enable auto-repeat