diff --git a/patches/src/main/kotlin/app/revanced/util/resource/StringResource.kt b/patches/src/main/kotlin/app/revanced/util/resource/StringResource.kt index c825d67598..915536b77f 100644 --- a/patches/src/main/kotlin/app/revanced/util/resource/StringResource.kt +++ b/patches/src/main/kotlin/app/revanced/util/resource/StringResource.kt @@ -1,8 +1,8 @@ package app.revanced.util.resource -import app.revanced.patcher.patch.PatchException import org.w3c.dom.Document import org.w3c.dom.Node +import java.util.logging.Logger /** * A string value. @@ -19,13 +19,36 @@ class StringResource( ) : BaseResource(name, "string") { override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) = super.serialize(ownerDocument, resourceCallback).apply { + + fun String.validateAndroidStringEscaping() : String { + if (value.startsWith('"') && value.endsWith('"')) { + // Raw strings allow unescaped single quote but not double quote. + if (!value.substring(1, value.length - 1).contains(Regex("(? and elements. + All strings must have a unique path, even if the same string is declared in two different apps. + This is because Crowdin requires temporarily flattening this file and removing the and elements. -# General guidelines and information for translating -## Strings parameters can be reordered to allow more flexible translations if the grammar should be changed. + Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. + Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. - For example, the patches string: - You will arrive at %1$s in %2$s hours from now - Could be translated to another language using a rearranged grammar: - You will arrive %2$s hours from now at %1$s + Raw strings are required because Crowdin AI translations regularly gets confused and + replace \n with an encoded new line character. - For Manager strings: - You will arrive at ${destination} in ${count} hours from now - Could be rearranged by changing the order of the ${} parameters: - You will arrive ${count} hours from now at ${destination} + Bad: + First \'item\' text\nSecond \"item\" text - Reordering is particularly relevant when translating into right to left languages, or for any language with grammar that is noticeably different from English. + Good: + "First 'item' text +Second \"item\" text" -## Single and double quotation marks must be escaped for patch strings (Manager does not require escaping any quotes). - - All _patches_ single and double quotation marks must be escaped as \" or \' - Forgetting to do this will cause that string to appear in app with no quotation characters. - - Correct: - You\'re correct. This is the \"correct\" way and this text will appear as expected in the app - Not correct: - You're not correct. This is not the "correct" way and this text will not appear as expected the in app --> @@ -67,9 +56,17 @@ This is because Crowdin requires temporarily flattening this file and removing t MicroG GmsCore is not installed. Install it. Action needed - MicroG GmsCore does not have permission to run in the background.\n\nFollow the \"Don\'t kill my app\" guide for your phone, and apply the instructions to your MicroG installation.\n\nThis is required for the app to work. + "MicroG GmsCore does not have permission to run in the background. + +Follow the \"Don\'t kill my app\" guide for your phone, and apply the instructions to your MicroG installation. + +This is required for the app to work." Open website - MicroG GmsCore battery optimizations must be disabled to prevent issues.\n\nDisabling battery optimizations for MicroG will not negatively affect battery usage.\n\nTap the continue button and allow optimization changes. + "MicroG GmsCore battery optimizations must be disabled to prevent issues. + +Disabling battery optimizations for MicroG will not negatively affect battery usage. + +Tap the continue button and allow optimization changes." Continue @@ -107,7 +104,9 @@ This is because Crowdin requires temporarily flattening this file and removing t Show toast on ReVanced error Toast shown if error occurs Toast not shown if error occurs - Turning off error toasts hides all ReVanced error notifications.\n\nYou will not be notified of any unexpected events. + "Turning off error toasts hides all ReVanced error notifications. + +You will not be notified of any unexpected events." Disable like / subscribe button glow @@ -126,7 +125,12 @@ This is because Crowdin requires temporarily flattening this file and removing t Watermark is hidden Watermark is shown Hide horizontal shelves - Shelves are hidden such as:\n• Breaking news\n• Continue watching\n• Explore more channels\n• Shopping\n• Watch it again + "Shelves are hidden such as: +• Breaking news +• Continue watching +• Explore more channels +• Shopping +• Watch it again" Shelves are shown @@ -278,8 +282,9 @@ This is because Crowdin requires temporarily flattening this file and removing t Hide YouTube Doodles Search bar Doodles are hidden Search bar Doodles are shown - YouTube Doodles show up a few days each year.\n\nIf a Doodle is currently showing in your region and this hide setting is on, then the filter bar below the search bar will also be hidden. + "YouTube Doodles are shown a few days each year. +If a Doodle is currently showing in your region and this hide setting is on, then the filter bar below the search bar will also be hidden." Custom filter Hide components using custom filters Enable custom filter @@ -304,9 +309,18 @@ This is because Crowdin requires temporarily flattening this file and removing t Keywords to hide - Keywords and phrases to hide, separated by new lines\n\nKeywords can be channel names or any text shown in video titles\n\nWords with uppercase letters in the middle must be entered with the casing (ie: iPhone, TikTok, LeBlanc) + "Keywords and phrases to hide, separated by new lines + +Keywords can be channel names or any text shown in video titles + +Words with uppercase letters in the middle must be entered with the casing (ie: iPhone, TikTok, LeBlanc)" About keyword filtering - Home/Subscription/Search results are filtered to hide content that matches keyword phrases\n\nLimitations\n• Shorts cannot be hidden by channel name\n• Some UI components may not be hidden\n• Searching for a keyword may show no results + "Home/Subscription/Search results are filtered to hide content that matches keyword phrases + +Limitations +• Shorts cannot be hidden by channel name +• Some UI components may not be hidden +• Searching for a keyword may show no results" Match whole words Surrounding a keyword/phrase with double-quotes will prevent partial matches of video titles and channel names<br><br>For example,<br><b>\"ai\"</b> will hide the video: <b>How does AI work?</b><br>but will not hide: <b>What does fair use mean?</b> @@ -322,7 +336,9 @@ This is because Crowdin requires temporarily flattening this file and removing t General ads are hidden General ads are shown Hide fullscreen ads - Fullscreen ads are hidden\n\nThis feature is only available for older devices + "Fullscreen ads are hidden + +This feature is only available for older devices" Fullscreen ads are shown Hide buttoned ads Buttoned ads are hidden @@ -496,7 +512,9 @@ This is because Crowdin requires temporarily flattening this file and removing t Subscriptions button is shown Switch Create with Notifications - Create button is switched with Notifications button\n\nNote: Enabling this also forcibly hides video ads + "Create button is switched with Notifications button + +Note: Enabling this also forcibly hides video ads" Create button is not switched with Notifications button Hide navigation button labels Labels are hidden @@ -739,7 +757,9 @@ This is because Crowdin requires temporarily flattening this file and removing t Dislikes are not shown Show dislikes on Shorts Dislikes shown on Shorts - Dislikes shown on Shorts\n\nLimitation: Dislikes may not appear in incognito mode + "Dislikes shown on Shorts + +Limitation: Dislikes may not appear in incognito mode" Dislikes hidden on Shorts Dislikes as percentage Dislikes shown as percentage @@ -783,7 +803,11 @@ This is because Crowdin requires temporarily flattening this file and removing t Seekbar thumbnails are medium quality Fullscreen seekbar thumbnails are high quality Fullscreen seekbar thumbnails are medium quality - This will also restore thumbnails on livestreams that do not have seekbar thumbnails.\n\nSeekbar thumbnails will use the same quality as the current video.\n\nThis feature works best with a video quality of 720p or lower and when using a very fast internet connection. + "This will also restore thumbnails on livestreams that do not have seekbar thumbnails. + +Seekbar thumbnails will use the same quality as the current video. + +This feature works best with a video quality of 720p or lower and when using a very fast internet connection." Restore old seekbar thumbnails Seekbar thumbnails will appear above the seekbar Seekbar thumbnails will appear in fullscreen @@ -847,7 +871,10 @@ This is because Crowdin requires temporarily flattening this file and removing t Settings imported successfully Failed to import: %s Failed to export: %s - Your settings contain a private SponsorBlock userid.\n\nYour user id is like a password and it should never be shared.\n + "Your settings contain a private SponsorBlock userid. + +Your user id is like a password and it should never be shared. +" Do not show again Change segment behavior Sponsor @@ -907,9 +934,10 @@ This is because Crowdin requires temporarily flattening this file and removing t Unable to submit segment: %s SponsorBlock is temporarily down Unable to submit segment (status: %1$d %2$s) - Unable to submit segment.\nRate Limited (too many from the same user or IP) + Unable to submit segment. Rate Limited (too many from the same user or IP) Can\'t submit the segment: %s - Can\'t submit the segment.\nAlready exists + "Can\'t submit the segment. +Already exists" Segment submitted successfully SponsorBlock temporarily not available (API timed out) @@ -932,7 +960,15 @@ This is because Crowdin requires temporarily flattening this file and removing t Time the segment begins at Time the segment ends at Are the times correct? - The segment is from\n\n%1$s\nto\n%2$s\n\n(%3$s)\n\nReady to submit? + "The segment is from + +%1$s +to +%2$s + +(%3$s) + +Ready to submit?" Start must be before the end Mark two locations on the time bar first Preview the segment, and ensure it skips smoothly @@ -975,7 +1011,11 @@ This is because Crowdin requires temporarily flattening this file and removing t Spoof app version Version spoofed Version not spoofed - App version will be spoofed to an older version of YouTube.\n\nThis will change the appearance and features of the app, but unknown side effects may occur.\n\nIf later turned off, it is recommended to clear the app data to prevent UI bugs. + "App version will be spoofed to an older version of YouTube. + +This will change the appearance and features of the app, but unknown side effects may occur. + +If later turned off, it is recommended to clear the app data to prevent UI bugs." Spoof app version target @@ -1038,19 +1078,28 @@ This is because Crowdin requires temporarily flattening this file and removing t Corners are rounded Corners are square Enable double-tap and pinch to resize - Double-tap action and pinch to resize is enabled\n\n• Double tap to increase miniplayer size\n• Double tap again to restore original size + "Double-tap action and pinch to resize is enabled + +• Double tap to increase miniplayer size +• Double tap again to restore original size" Double-tap action and pinch to resize is disabled Enable drag and drop - Drag and drop is enabled\n\nMiniplayer can be dragged to any corner of the screen + "Drag and drop is enabled + +Miniplayer can be dragged to any corner of the screen" Drag and drop is disabled Enable horizontal drag gesture - Horizontal drag gesture enabled\n\nMiniplayer can be dragged off screen to the left or right + "Horizontal drag gesture enabled + +Miniplayer can be dragged off screen to the left or right" Horizontal drag gesture disabled Hide close button Close button is hidden Close button is shown Hide expand and close buttons - Buttons are hidden\n\nSwipe to expand or close + "Buttons are hidden + +Swipe to expand or close" Expand and close buttons are shown Hide subtexts Subtexts are hidden @@ -1081,7 +1130,9 @@ This is because Crowdin requires temporarily flattening this file and removing t Bypass image region restrictions Using image host yt4.ggpht.com - Using original image host\n\nEnabling this can fix missing images that are blocked in some regions + "Using original image host + +Enabling this can fix missing images that are blocked in some regions" @@ -1097,7 +1148,11 @@ This is because Crowdin requires temporarily flattening this file and removing t 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 + "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. If a video does not have DeArrow thumbnails, then the original or still captures are shown + +Tap 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 @@ -1136,8 +1191,12 @@ This is because Crowdin requires temporarily flattening this file and removing t Spoof device dimensions - Device dimensions spoofed\n\nHigher video qualities might be unlocked but you may experience video playback stuttering, worse battery life, and unknown side effects - Device dimensions not spoofed\n\nEnabling this can unlock higher video qualities + "Device dimensions spoofed + +Higher video qualities might be unlocked but you may experience video playback stuttering, worse battery life, and unknown side effects" + "Device dimensions not spoofed + +Enabling this can unlock higher video qualities" Enabling this can cause video playback stuttering, worse battery life, and unknown side effects. @@ -1187,8 +1246,8 @@ This is because Crowdin requires temporarily flattening this file and removing t Custom speed menu is not shown Custom playback speeds Add or change the custom playback speeds - Custom speeds must be less than %s. Using default values. - Invalid custom playback speeds. Using default values. + Custom speeds must be less than %s + Invalid custom playback speeds Auto @@ -1213,17 +1272,25 @@ This is because Crowdin requires temporarily flattening this file and removing t Spoof the client video streams to prevent playback issues Spoof video streams Video streams are spoofed - Video streams are not spoofed\n\nVideo playback may not work + "Video streams are not spoofed + +Video playback may not work" Turning off this setting may cause video playback issues. Default client Force AVC (H.264) Video codec is forced to AVC (H.264) Video codec is determined automatically - Enabling this might improve battery life and fix playback stuttering.\n\nAVC has a maximum resolution of 1080p, Opus audio codec is not available, and video playback will use more internet data than VP9 or AV1. + "Enabling this might improve battery life and fix playback stuttering. + +AVC has a maximum resolution of 1080p, Opus audio codec is not available, and video playback will use more internet data than VP9 or AV1." iOS spoofing side effects - • Private kids videos may not play\n• Livestreams start from the beginning\n• Videos end 1 second early + "• Private kids videos may not play +• Livestreams start from the beginning +• Videos end 1 second early" Android VR spoofing side effects - • Kids videos may not play\n• Livestreams start from the beginning\n• Videos end 1 second early + "• Kids videos may not play +• Livestreams start from the beginning +• Videos end 1 second early" Default audio stream language App language Arabic @@ -1287,8 +1354,8 @@ This is because Crowdin requires temporarily flattening this file and removing t Audio ads are unblocked - %s is unavailable. Ads may show. Try switching to another ad block service in settings. - %s server returned an error. Ads may show. Try switching to another ad block service in settings. + %s unavailable, ads may show. Try changing ad block service in settings. + %s returned an error, ads may show. Try changing ad block service in settings. Block embedded video ads Disabled Luminous proxy